Use enums for status, result code & error code for async jobs

This commit is contained in:
andreisavu 2011-11-30 17:42:15 +02:00
parent 3b785994c7
commit 09de9bf00e
12 changed files with 210 additions and 103 deletions

View File

@ -43,6 +43,22 @@ public class AsyncJob<T> {
} }
public int code() { return this.code; } public int code() { return this.code; }
public static ResultCode fromValue(String value) {
try {
int resultCode = Integer.parseInt(value);
switch (resultCode) {
case 0:
return SUCCESS;
case 530:
return FAIL;
default:
return UNKNOWN;
}
} catch(NumberFormatException e) {
return UNKNOWN;
}
}
} }
/** /**
@ -61,6 +77,24 @@ public class AsyncJob<T> {
} }
public int code() { return this.code; } public int code() { return this.code; }
public static Status fromValue(String value) {
try {
int statusCode = Integer.parseInt(value);
switch (statusCode) {
case 0:
return IN_PROGRESS;
case 1:
return SUCCEEDED;
case 2:
return FAILED;
default:
return UNKNOWN;
}
} catch (NumberFormatException e) {
return UNKNOWN;
}
}
} }
public static <T> Builder<T> builder() { public static <T> Builder<T> builder() {
@ -76,10 +110,10 @@ public class AsyncJob<T> {
private String instanceType; private String instanceType;
private int progress = -1; private int progress = -1;
private T result; private T result;
private int resultCode = -1; private ResultCode resultCode = ResultCode.UNKNOWN;
private String resultType; private String resultType;
private AsyncJobError error; private AsyncJobError error;
private int status = -1; private Status status = Status.UNKNOWN;
private int userId = -1; private int userId = -1;
public Builder<T> accountId(long accountId) { public Builder<T> accountId(long accountId) {
@ -127,7 +161,7 @@ public class AsyncJob<T> {
return this; return this;
} }
public Builder<T> resultCode(int resultCode) { public Builder<T> resultCode(ResultCode resultCode) {
this.resultCode = resultCode; this.resultCode = resultCode;
return this; return this;
} }
@ -137,7 +171,7 @@ public class AsyncJob<T> {
return this; return this;
} }
public Builder<T> status(int status) { public Builder<T> status(Status status) {
this.status = status; this.status = status;
return this; return this;
} }
@ -174,17 +208,17 @@ public class AsyncJob<T> {
@SerializedName("jobresult") @SerializedName("jobresult")
private T result; private T result;
@SerializedName("jobresultcode") @SerializedName("jobresultcode")
private int resultCode = -1; private ResultCode resultCode = ResultCode.UNKNOWN;
@SerializedName("jobresulttype") @SerializedName("jobresulttype")
private String resultType; private String resultType;
@SerializedName("jobstatus") @SerializedName("jobstatus")
private int status = -1; private Status status = Status.UNKNOWN;
@SerializedName("userid") @SerializedName("userid")
private int userId = -1; private int userId = -1;
private AsyncJobError error; private AsyncJobError error;
public AsyncJob(long accountId, String cmd, Date created, long id, long instanceId, String instanceType, public AsyncJob(long accountId, String cmd, Date created, long id, long instanceId, String instanceType,
int progress, T result, int resultCode, String resultType, int status, int userId, AsyncJobError error) { int progress, T result, ResultCode resultCode, String resultType, Status status, int userId, AsyncJobError error) {
this.accountId = accountId; this.accountId = accountId;
this.cmd = cmd; this.cmd = cmd;
this.created = created; this.created = created;
@ -267,7 +301,7 @@ public class AsyncJob<T> {
/** /**
* @return the result code for the job * @return the result code for the job
*/ */
public int getResultCode() { public ResultCode getResultCode() {
return resultCode; return resultCode;
} }
@ -281,7 +315,7 @@ public class AsyncJob<T> {
/** /**
* @return the current job status-should be 0 for PENDING * @return the current job status-should be 0 for PENDING
*/ */
public int getStatus() { public Status getStatus() {
return status; return status;
} }
@ -302,6 +336,14 @@ public class AsyncJob<T> {
return error; return error;
} }
public boolean hasFailed() {
return getError() != null || getResultCode() == ResultCode.FAIL || getStatus() == Status.FAILED;
}
public boolean hasSucceed() {
return getError() == null && getResultCode() == ResultCode.SUCCESS && getStatus() == Status.SUCCEEDED;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
@ -315,9 +357,9 @@ public class AsyncJob<T> {
result = prime * result + ((error == null) ? 0 : error.hashCode()); result = prime * result + ((error == null) ? 0 : error.hashCode());
result = prime * result + progress; result = prime * result + progress;
result = prime * result + ((this.result == null) ? 0 : this.result.hashCode()); result = prime * result + ((this.result == null) ? 0 : this.result.hashCode());
result = prime * result + resultCode; result = prime * result + resultCode.code();
result = prime * result + ((resultType == null) ? 0 : resultType.hashCode()); result = prime * result + ((resultType == null) ? 0 : resultType.hashCode());
result = prime * result + status; result = prime * result + status.code();
result = prime * result + userId; result = prime * result + userId;
return result; return result;
} }

View File

@ -29,7 +29,7 @@ public class AsyncJobError {
/** /**
* Error codes for job errors * Error codes for job errors
*/ */
public static enum Code { public static enum ErrorCode {
INTERNAL_ERROR (530), INTERNAL_ERROR (530),
ACCOUNT_ERROR (531), ACCOUNT_ERROR (531),
ACCOUNT_RESOURCE_LIMIT_ERROR(532), ACCOUNT_RESOURCE_LIMIT_ERROR(532),
@ -42,15 +42,30 @@ public class AsyncJobError {
private final int code; private final int code;
private Code(int code) { private ErrorCode(int code) {
this.code = code; this.code = code;
} }
public int code() { return this.code; } public int code() { return this.code; }
public static ErrorCode fromValue(String value) {
try {
int errorCode = Integer.parseInt(value);
for(ErrorCode candidate : values()) {
if (candidate.code() == errorCode) {
return candidate;
}
}
return UNKNOWN;
} catch(NumberFormatException e) {
return UNKNOWN;
}
}
} }
@SerializedName("errorcode") @SerializedName("errorcode")
private int errorCode; private ErrorCode errorCode;
@SerializedName("errortext") @SerializedName("errortext")
private String errorText; private String errorText;
@ -62,12 +77,12 @@ public class AsyncJobError {
} }
public AsyncJobError(int errorCode, String errorText) { public AsyncJobError(ErrorCode errorCode, String errorText) {
this.errorCode = errorCode; this.errorCode = errorCode;
this.errorText = errorText; this.errorText = errorText;
} }
public int getErrorCode() { public ErrorCode getErrorCode() {
return errorCode; return errorCode;
} }
@ -79,7 +94,7 @@ public class AsyncJobError {
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + errorCode; result = prime * result + errorCode.code();
result = prime * result + ((errorText == null) ? 0 : errorText.hashCode()); result = prime * result + ((errorText == null) ? 0 : errorText.hashCode());
return result; return result;
} }

View File

@ -19,6 +19,7 @@
package org.jclouds.cloudstack.functions; package org.jclouds.cloudstack.functions;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.cloudstack.domain.AsyncJobError.ErrorCode;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -50,7 +51,6 @@ import com.google.common.collect.Iterables;
import com.google.inject.Inject; import com.google.inject.Inject;
/** /**
*
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
@ -61,10 +61,13 @@ public class ParseTypedAsyncJob implements Function<AsyncJob<Map<String, JsonBal
@Inject(optional = true) @Inject(optional = true)
@VisibleForTesting @VisibleForTesting
@Named("jclouds.cloudstack.jobresult-type-map") @Named("jclouds.cloudstack.jobresult-type-map")
Map<String, Class<?>> typeMap = ImmutableMap.<String, Class<?>> builder().put("securitygroup", SecurityGroup.class) Map<String, Class<?>> typeMap = ImmutableMap.<String, Class<?>>builder()
.put("portforwardingrule", PortForwardingRule.class).put("ipforwardingrule", IPForwardingRule.class) .put("securitygroup", SecurityGroup.class)
.put("network", Network.class).put("ipaddress", PublicIPAddress.class) .put("portforwardingrule", PortForwardingRule.class)
.put("virtualmachine", VirtualMachine.class).build(); .put("ipforwardingrule", IPForwardingRule.class)
.put("network", Network.class)
.put("ipaddress", PublicIPAddress.class)
.put("virtualmachine", VirtualMachine.class).build();
private final Json json; private final Json json;
@Inject @Inject
@ -76,7 +79,7 @@ public class ParseTypedAsyncJob implements Function<AsyncJob<Map<String, JsonBal
AsyncJob<?> result = toParse; AsyncJob<?> result = toParse;
if (toParse.getResult() != null) { if (toParse.getResult() != null) {
if (toParse.getResult().size() == 1) { if (toParse.getResult().size() == 1) {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({"unchecked", "rawtypes"})
Builder<Object> builder = AsyncJob.Builder.fromAsyncJobUntyped((AsyncJob) toParse); Builder<Object> builder = AsyncJob.Builder.fromAsyncJobUntyped((AsyncJob) toParse);
if (toParse.getResult().containsKey("success")) { if (toParse.getResult().containsKey("success")) {
builder.result(null); builder.result(null);
@ -94,23 +97,23 @@ public class ParseTypedAsyncJob implements Function<AsyncJob<Map<String, JsonBal
builder.result(json.fromJson(entry.getValue().toString(), typeMap.get(entry.getKey()))); builder.result(json.fromJson(entry.getValue().toString(), typeMap.get(entry.getKey())));
} else { } else {
logger.warn( logger.warn(
"type key %s not configured. please override default for Map<String, Class<?>> bound to name jclouds.cloudstack.jobresult-type-map", "type key %s not configured. please override default for Map<String, Class<?>> bound to name jclouds.cloudstack.jobresult-type-map",
entry.getKey()); entry.getKey());
builder.result(entry.getValue().toString()); builder.result(entry.getValue().toString());
} }
} }
result = builder.build(); result = builder.build();
} else if (toParse.getResult().containsKey("errorcode")) { } else if (toParse.getResult().containsKey("errorcode")) {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({"unchecked", "rawtypes"})
Builder<Object> builder = AsyncJob.Builder.fromAsyncJobUntyped((AsyncJob) toParse); Builder<Object> builder = AsyncJob.Builder.fromAsyncJobUntyped((AsyncJob) toParse);
builder.result(null);// avoid classcastexceptions builder.result(null);// avoid classcastexceptions
builder.error(new AsyncJobError(Integer.parseInt(toParse.getResult().get("errorcode").toString()), toParse builder.error(new AsyncJobError(ErrorCode.fromValue(toParse.getResult().get("errorcode").toString()), toParse
.getResult().containsKey("errortext") ? toParse.getResult().get("errortext").toString() .getResult().containsKey("errortext") ? toParse.getResult().get("errortext").toString()
.replace("\"", "") : null)); .replace("\"", "") : null));
result = builder.build(); result = builder.build();
} else if (toParse.getResult().size() > 1) { } else if (toParse.getResult().size() > 1) {
logger.warn("unexpected size of async job result; expecting a map with a single element", logger.warn("unexpected size of async job result; expecting a map with a single element",
toParse.getResult()); toParse.getResult());
} }
} }
return result; return result;

View File

@ -61,15 +61,12 @@ public class JobComplete implements Predicate<Long> {
return false; return false;
} }
logger.trace("%s: looking for job status %s: currently: %s", job.getId(), 1, job.getStatus()); logger.trace("%s: looking for job status %s: currently: %s", job.getId(), 1, job.getStatus());
if (job.getError() != null || if (job.hasFailed()) {
job.getStatus() == FAILED.code() ||
job.getResultCode() == FAIL.code()) {
throw new AsyncJobException(String.format("job %s failed with exception %s", throw new AsyncJobException(String.format("job %s failed with exception %s",
job.toString(), job.getError().toString())); job.toString(), job.getError().toString()));
} }
return job.getStatus() == SUCCEEDED.code() && return job.hasSucceed();
job.getResultCode() == SUCCESS.code();
} }
private AsyncJob<?> refresh(Long jobId) { private AsyncJob<?> refresh(Long jobId) {

View File

@ -54,15 +54,15 @@ public class AsyncJobClientLiveTest extends BaseCloudStackClientLiveTest {
} }
private void checkJob(AsyncJob<?> query) { private void checkJob(AsyncJob<?> query) {
assert query.getStatus() >= 0 : query; assert query.getStatus().code() >= 0 : query;
assert query.getResultCode() >= 0 : query; assert query.getResultCode().code() >= 0 : query;
assert query.getProgress() >= 0 : query; assert query.getProgress() >= 0 : query;
if (query.getResultCode() == 0) { if (query.getResultCode().code() == 0) {
if (query.getResult() != null)// null is ok for result of success = if (query.getResult() != null)// null is ok for result of success =
// true // true
// ensure we parsed properly // ensure we parsed properly
assert (query.getResult().getClass().getPackage().equals(AsyncJob.class.getPackage())) : query; assert (query.getResult().getClass().getPackage().equals(AsyncJob.class.getPackage())) : query;
} else if (query.getResultCode() > 400) { } else if (query.getResultCode().code() > 400) {
assert query.getResult() == null : query; assert query.getResult() == null : query;
assert query.getError() != null : query; assert query.getError() != null : query;
} else { } else {

View File

@ -22,6 +22,7 @@ import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock; import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay; import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify; import static org.easymock.classextension.EasyMock.verify;
import static org.jclouds.cloudstack.domain.AsyncJobError.ErrorCode;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
@ -101,7 +102,8 @@ public class BlockUntilJobCompletesAndReturnResultTest {
expect(client.getAsyncJobClient()).andReturn(jobClient).atLeastOnce(); expect(client.getAsyncJobClient()).andReturn(jobClient).atLeastOnce();
expect(jobClient.getAsyncJob(jobId)).andReturn( expect(jobClient.getAsyncJob(jobId)).andReturn(
AsyncJob.builder().id(jobId).error(new AsyncJobError(1, "ERRROR")).result("foo").build()).atLeastOnce(); AsyncJob.builder().id(jobId).error(
new AsyncJobError(ErrorCode.INTERNAL_ERROR, "ERRROR")).result("foo").build()).atLeastOnce();
replay(client); replay(client);
replay(jobClient); replay(jobClient);

View File

@ -18,6 +18,9 @@
*/ */
package org.jclouds.cloudstack.functions; package org.jclouds.cloudstack.functions;
import static org.jclouds.cloudstack.domain.AsyncJob.ResultCode;
import static org.jclouds.cloudstack.domain.AsyncJob.Status;
import static org.jclouds.cloudstack.domain.AsyncJobError.ErrorCode;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
@ -41,7 +44,6 @@ import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
/** /**
*
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "unit") @Test(groups = "unit")
@ -60,13 +62,16 @@ public class ParseAsyncJobFromHttpResponseTest {
public void testWithNoResult() { public void testWithNoResult() {
String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":860,\"jobstatus\":0,\"jobprocstatus\":0,\"jobresultcode\":0} }"; String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":860,\"jobstatus\":0,\"jobprocstatus\":0,\"jobresultcode\":0} }";
AsyncJob<PublicIPAddress> expects = AsyncJob.<PublicIPAddress> builder().id(860).status(0).progress(0) AsyncJob<PublicIPAddress> expects = AsyncJob.<PublicIPAddress>builder()
.resultCode(0).build(); .id(860)
.status(Status.IN_PROGRESS)
.progress(0)
.resultCode(ResultCode.SUCCESS).build();
ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class); ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok", AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok",
Payloads.newStringPayload(input))); Payloads.newStringPayload(input)));
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -74,13 +79,17 @@ public class ParseAsyncJobFromHttpResponseTest {
public void testWithSuccessTrueResultSetsNullResult() { public void testWithSuccessTrueResultSetsNullResult() {
String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":1138,\"jobstatus\":1,\"jobprocstatus\":0,\"jobresultcode\":0,\"jobresulttype\":\"object\",\"jobresult\":{\"success\":true}} }"; String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":1138,\"jobstatus\":1,\"jobprocstatus\":0,\"jobresultcode\":0,\"jobresulttype\":\"object\",\"jobresult\":{\"success\":true}} }";
AsyncJob<PublicIPAddress> expects = AsyncJob.<PublicIPAddress> builder().id(1138).status(1).progress(0) AsyncJob<PublicIPAddress> expects = AsyncJob.<PublicIPAddress>builder()
.resultType("object").resultCode(0).build(); .id(1138)
.status(Status.SUCCEEDED)
.progress(0)
.resultType("object")
.resultCode(ResultCode.SUCCESS).build();
ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class); ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok", AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok",
Payloads.newStringPayload(input))); Payloads.newStringPayload(input)));
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -89,18 +98,19 @@ public class ParseAsyncJobFromHttpResponseTest {
String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":1103,\"jobstatus\":2,\"jobprocstatus\":0,\"jobresultcode\":530,\"jobresulttype\":\"object\",\"jobresult\":{\"errorcode\":530,\"errortext\":\"Internal error executing command, please contact your system administrator\"}} }"; String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":1103,\"jobstatus\":2,\"jobprocstatus\":0,\"jobresultcode\":530,\"jobresulttype\":\"object\",\"jobresult\":{\"errorcode\":530,\"errortext\":\"Internal error executing command, please contact your system administrator\"}} }";
AsyncJob<PublicIPAddress> expects = AsyncJob AsyncJob<PublicIPAddress> expects = AsyncJob
.<PublicIPAddress> builder() .<PublicIPAddress>builder()
.id(1103) .id(1103)
.status(2) .status(Status.FAILED)
.progress(0) .progress(0)
.resultType("object") .resultType("object")
.error(new AsyncJobError(530, "Internal error executing command, please contact your system administrator")) .error(new AsyncJobError(ErrorCode.INTERNAL_ERROR, "Internal error executing " +
.resultCode(530).build(); "command, please contact your system administrator"))
.resultCode(ResultCode.FAIL).build();
ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class); ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok", AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok",
Payloads.newStringPayload(input))); Payloads.newStringPayload(input)));
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -108,13 +118,18 @@ public class ParseAsyncJobFromHttpResponseTest {
public void testWithUnknownResultReturnsStringifiedJson() { public void testWithUnknownResultReturnsStringifiedJson() {
String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":860,\"jobstatus\":0,\"jobprocstatus\":0,\"jobresultcode\":0,\"jobresult\":{\"foo\":{\"bar\":1}}}}"; String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":860,\"jobstatus\":0,\"jobprocstatus\":0,\"jobresultcode\":0,\"jobresult\":{\"foo\":{\"bar\":1}}}}";
AsyncJob<?> expects = AsyncJob.builder().id(860).status(0).progress(0).resultCode(0).result("{\"bar\":1}") AsyncJob<?> expects = AsyncJob.builder()
.build(); .id(860)
.status(Status.IN_PROGRESS)
.progress(0)
.resultCode(ResultCode.SUCCESS)
.result("{\"bar\":1}")
.build();
ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class); ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok", AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok",
Payloads.newStringPayload(input))); Payloads.newStringPayload(input)));
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -127,13 +142,17 @@ public class ParseAsyncJobFromHttpResponseTest {
// thrown in case they change their minds. // thrown in case they change their minds.
String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":860,\"jobstatus\":0,\"jobprocstatus\":0,\"jobresultcode\":0,\"jobresult\":{\"foo\":{\"bar\":1},\"foo2\":{\"bar2\":2}}}}"; String input = "{ \"queryasyncjobresultresponse\" : {\"jobid\":860,\"jobstatus\":0,\"jobprocstatus\":0,\"jobresultcode\":0,\"jobresult\":{\"foo\":{\"bar\":1},\"foo2\":{\"bar2\":2}}}}";
AsyncJob<?> expects = AsyncJob.builder().id(860).status(0).progress(0).resultCode(0) AsyncJob<?> expects = AsyncJob.builder()
.result(ImmutableMap.of("foo", new JsonBall("{\"bar\":1}"), "foo2", new JsonBall("{\"bar2\":2}"))).build(); .id(860)
.status(Status.IN_PROGRESS)
.progress(0)
.resultCode(ResultCode.SUCCESS)
.result(ImmutableMap.of("foo", new JsonBall("{\"bar\":1}"), "foo2", new JsonBall("{\"bar2\":2}"))).build();
ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class); ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok", AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok",
Payloads.newStringPayload(input))); Payloads.newStringPayload(input)));
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -141,29 +160,29 @@ public class ParseAsyncJobFromHttpResponseTest {
public void testPublicIPAddress() { public void testPublicIPAddress() {
InputStream is = getClass().getResourceAsStream("/queryasyncjobresultresponse-ipaddress.json"); InputStream is = getClass().getResourceAsStream("/queryasyncjobresultresponse-ipaddress.json");
AsyncJob<PublicIPAddress> expects = AsyncJob AsyncJob<PublicIPAddress> expects = AsyncJob
.<PublicIPAddress> builder() .<PublicIPAddress>builder()
.id(860) .id(860)
.status(1) .status(Status.SUCCEEDED)
.progress(0) .progress(0)
.resultType("object") .resultType("object")
.resultCode(0) .resultCode(ResultCode.SUCCESS)
.result( .result(
PublicIPAddress PublicIPAddress
.builder() .builder()
.id(6) .id(6)
.IPAddress("72.52.126.35") .IPAddress("72.52.126.35")
.allocated( .allocated(
new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-02-23T20:15:01-0800")) new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-02-23T20:15:01-0800"))
.zoneId(1).zoneName("San Jose 1").isSourceNAT(false).account("adrian").domainId(1) .zoneId(1).zoneName("San Jose 1").isSourceNAT(false).account("adrian").domainId(1)
.domain("ROOT").usesVirtualNetwork(true).isStaticNAT(false).associatedNetworkId(204) .domain("ROOT").usesVirtualNetwork(true).isStaticNAT(false).associatedNetworkId(204)
.networkId(200).state(PublicIPAddress.State.ALLOCATING).build() .networkId(200).state(PublicIPAddress.State.ALLOCATING).build()
).build(); ).build();
ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class); ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok", AsyncJob<PublicIPAddress> response = (AsyncJob<PublicIPAddress>) parser.apply(new HttpResponse(200, "ok",
Payloads.newInputStreamPayload(is))); Payloads.newInputStreamPayload(is)));
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -171,21 +190,21 @@ public class ParseAsyncJobFromHttpResponseTest {
public void testIPForwardingRule() { public void testIPForwardingRule() {
InputStream is = getClass().getResourceAsStream("/queryasyncjobresultresponse-ipforwardingrule.json"); InputStream is = getClass().getResourceAsStream("/queryasyncjobresultresponse-ipforwardingrule.json");
AsyncJob<IPForwardingRule> expects = AsyncJob AsyncJob<IPForwardingRule> expects = AsyncJob
.<IPForwardingRule> builder() .<IPForwardingRule>builder()
.id(1133) .id(1133)
.status(1) .status(Status.SUCCEEDED)
.progress(0) .progress(0)
.resultType("object") .resultType("object")
.resultCode(0) .resultCode(ResultCode.SUCCESS)
.result( .result(
IPForwardingRule.builder().id(109).protocol("tcp").virtualMachineId(226) IPForwardingRule.builder().id(109).protocol("tcp").virtualMachineId(226)
.virtualMachineName("i-3-226-VM").IPAddressId(36).IPAddress("72.52.126.65").startPort(22) .virtualMachineName("i-3-226-VM").IPAddressId(36).IPAddress("72.52.126.65").startPort(22)
.endPort(22).state("Active").build()).build(); .endPort(22).state("Active").build()).build();
ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class); ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
AsyncJob<IPForwardingRule> response = (AsyncJob<IPForwardingRule>) parser.apply(new HttpResponse(200, "ok", AsyncJob<IPForwardingRule> response = (AsyncJob<IPForwardingRule>) parser.apply(new HttpResponse(200, "ok",
Payloads.newInputStreamPayload(is))); Payloads.newInputStreamPayload(is)));
assertEquals(response, expects); assertEquals(response, expects);
} }
@ -194,10 +213,10 @@ public class ParseAsyncJobFromHttpResponseTest {
InputStream is = getClass().getResourceAsStream("/queryasyncjobresultresponse-createtemplate.json"); InputStream is = getClass().getResourceAsStream("/queryasyncjobresultresponse-createtemplate.json");
ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class); ParseAsyncJobFromHttpResponse parser = i.getInstance(ParseAsyncJobFromHttpResponse.class);
AsyncJob<?> response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is))); 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()); assertTrue(response.getResult() instanceof Template, "response expected to be Template, actually is " + response.getResult().getClass());
is = getClass().getResourceAsStream("/queryasyncjobresultresponse-extracttemplate.json"); is = getClass().getResourceAsStream("/queryasyncjobresultresponse-extracttemplate.json");
response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(is))); 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()); assertTrue(response.getResult() instanceof TemplateExtraction, "response expected to be TemplateExtraction, actually is " + response.getResult().getClass());
} }
} }

View File

@ -18,18 +18,23 @@
*/ */
package org.jclouds.cloudstack.predicates; package org.jclouds.cloudstack.predicates;
import org.jclouds.cloudstack.AsyncJobException;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.AsyncJob; import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.AsyncJobError;
import org.jclouds.cloudstack.features.AsyncJobClient; import org.jclouds.cloudstack.features.AsyncJobClient;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify; import static org.easymock.EasyMock.verify;
import static org.jclouds.cloudstack.domain.AsyncJob.ResultCode.SUCCESS; import static org.jclouds.cloudstack.domain.AsyncJob.ResultCode;
import static org.jclouds.cloudstack.domain.AsyncJob.Status.SUCCEEDED; import static org.jclouds.cloudstack.domain.AsyncJob.Status;
import static org.jclouds.cloudstack.domain.AsyncJobError.ErrorCode;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
/** /**
* @author Andrei Savu * @author Andrei Savu
@ -37,19 +42,43 @@ import static org.testng.Assert.assertTrue;
@Test(groups = "unit", singleThreaded = true) @Test(groups = "unit", singleThreaded = true)
public class JobCompleteTest { public class JobCompleteTest {
@Test CloudStackClient client;
public void testJobComplete() { AsyncJobClient asyncJobClient;
CloudStackClient client = createMock(CloudStackClient.class);
AsyncJobClient asyncJobClient = createMock(AsyncJobClient.class); @BeforeMethod
public void setUp() {
client = createMock(CloudStackClient.class);
asyncJobClient = createMock(AsyncJobClient.class);
expect(client.getAsyncJobClient()).andReturn(asyncJobClient); expect(client.getAsyncJobClient()).andReturn(asyncJobClient);
}
@Test
public void testJobComplete() {
AsyncJob job = AsyncJob.builder().id(100L) AsyncJob job = AsyncJob.builder().id(100L)
.status(SUCCEEDED.code()).resultCode(SUCCESS.code()).build(); .status(Status.SUCCEEDED).resultCode(ResultCode.SUCCESS).build();
expect(asyncJobClient.getAsyncJob(job.getId())).andReturn(job); expect(asyncJobClient.getAsyncJob(job.getId())).andReturn(job);
replay(client, asyncJobClient); replay(client, asyncJobClient);
assertTrue(new JobComplete(client).apply(job.getId())); assertTrue(new JobComplete(client).apply(job.getId()));
verify(client, asyncJobClient); verify(client, asyncJobClient);
} }
@Test
public void testFailedJobComplete() {
AsyncJob job = AsyncJob.builder().id(100L)
.status(Status.FAILED).resultCode(ResultCode.FAIL)
.error(new AsyncJobError(ErrorCode.INTERNAL_ERROR, "Dummy test error")).build();
expect(asyncJobClient.getAsyncJob(job.getId())).andReturn(job);
replay(client, asyncJobClient);
try {
new JobComplete(client).apply(job.getId());
fail("No exception thrown");
} catch (AsyncJobException e) {
assertTrue(e.toString().contains("Dummy test error"));
}
verify(client, asyncJobClient);
}
} }

View File

@ -41,7 +41,7 @@ import static org.testng.Assert.assertTrue;
/** /**
* @author Andrei Savu * @author Andrei Savu
*/ */
@Test(groups = "unit", singleThreaded=true) @Test(groups = "unit", singleThreaded = true)
public class OSCategoryInTest { public class OSCategoryInTest {
private CloudStackClient client; private CloudStackClient client;

View File

@ -35,7 +35,7 @@ import static org.testng.Assert.assertTrue;
/** /**
* @author Andrei Savu * @author Andrei Savu
*/ */
@Test(groups = "unit", singleThreaded=true, testName = "VirtualMachineDestroyedTest") @Test(groups = "unit", singleThreaded = true, testName = "VirtualMachineDestroyedTest")
public class VirtualMachineDestroyedTest { public class VirtualMachineDestroyedTest {
CloudStackClient client; CloudStackClient client;

View File

@ -35,7 +35,7 @@ import static org.testng.Assert.assertTrue;
/** /**
* @author Andrei Savu * @author Andrei Savu
*/ */
@Test(groups = "unit", singleThreaded=true, testName = "VirtualMachineExpungedTest") @Test(groups = "unit", singleThreaded = true, testName = "VirtualMachineExpungedTest")
public class VirtualMachineExpungedTest { public class VirtualMachineExpungedTest {
CloudStackClient client; CloudStackClient client;

View File

@ -36,7 +36,7 @@ import static org.testng.Assert.assertEquals;
/** /**
* @author Andrei Savu * @author Andrei Savu
*/ */
@Test(groups = "unit", singleThreaded=true, testName = "VirtualMachineRunningTest") @Test(groups = "unit", singleThreaded = true, testName = "VirtualMachineRunningTest")
public class VirtualMachineRunningTest { public class VirtualMachineRunningTest {
CloudStackClient client; CloudStackClient client;