diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java
index 0137190a0d4..4577f8ec778 100755
--- a/api/src/com/cloud/api/ApiConstants.java
+++ b/api/src/com/cloud/api/ApiConstants.java
@@ -88,6 +88,7 @@ public class ApiConstants {
public static final String IS_RECURSIVE = "isrecursive";
public static final String ISO_FILTER = "isofilter";
public static final String JOB_ID = "jobid";
+ public static final String JOB_STATUS = "jobstatus";
public static final String LASTNAME = "lastname";
public static final String LEVEL = "level";
public static final String LUN = "lun";
diff --git a/api/src/com/cloud/api/BaseAsyncCmd.java b/api/src/com/cloud/api/BaseAsyncCmd.java
index 25a5d6698b4..2354ead5345 100644
--- a/api/src/com/cloud/api/BaseAsyncCmd.java
+++ b/api/src/com/cloud/api/BaseAsyncCmd.java
@@ -18,6 +18,7 @@
package com.cloud.api;
import com.cloud.api.response.AsyncJobResponse;
+import com.cloud.async.AsyncJob;
/**
* A base command for supporting asynchronous API calls. When an API command is received, the command will be
@@ -76,4 +77,19 @@ public abstract class BaseAsyncCmd extends BaseCmd {
public void setStartEventId(Long startEventId) {
this.startEventId = startEventId;
}
+
+ /**
+ * Async commands that want to be tracked as part of the listXXX commands need to
+ * provide implementations of the two following methods, getInstanceId() and getInstanceType()
+ *
+ * getObjectId() should return the id of the object the async command is executing on
+ * getObjectType() should return a type from the AsyncJobVO.Type enumeration
+ */
+ public Long getInstanceId() {
+ return null;
+ }
+
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.None;
+ }
}
diff --git a/api/src/com/cloud/api/BaseListCmd.java b/api/src/com/cloud/api/BaseListCmd.java
index 12f066f9c2e..15982b0786b 100644
--- a/api/src/com/cloud/api/BaseListCmd.java
+++ b/api/src/com/cloud/api/BaseListCmd.java
@@ -1,5 +1,7 @@
package com.cloud.api;
+import com.cloud.async.AsyncJob;
+
public abstract class BaseListCmd extends BaseCmd {
@@ -61,4 +63,8 @@ public abstract class BaseListCmd extends BaseCmd {
}
return startIndex;
}
+
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.None;
+ }
}
diff --git a/api/src/com/cloud/api/ResponseObject.java b/api/src/com/cloud/api/ResponseObject.java
index 6c92b9fd5ed..3e5c978174d 100644
--- a/api/src/com/cloud/api/ResponseObject.java
+++ b/api/src/com/cloud/api/ResponseObject.java
@@ -24,4 +24,33 @@ public interface ResponseObject {
* @param name
*/
void setObjectName(String name);
+
+ /**
+ * Returns the object Id
+ */
+ Long getObjectId();
+
+ /**
+ * Returns the job id
+ * @return
+ */
+ Long getJobId();
+
+ /**
+ * Sets the job id
+ * @param jobId
+ */
+ void setJobId(Long jobId);
+
+ /**
+ * Returns the job status
+ * @return
+ */
+ Integer getJobStatus();
+
+ /**
+ *
+ * @param jobStatus
+ */
+ void setJobStatus(Integer jobStatus);
}
diff --git a/api/src/com/cloud/api/commands/DeployVMCmd.java b/api/src/com/cloud/api/commands/DeployVMCmd.java
index 410227ebed8..489708c674d 100644
--- a/api/src/com/cloud/api/commands/DeployVMCmd.java
+++ b/api/src/com/cloud/api/commands/DeployVMCmd.java
@@ -29,6 +29,7 @@ import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.InsufficientStorageCapacityException;
import com.cloud.exception.ResourceAllocationException;
@@ -191,6 +192,10 @@ public class DeployVMCmd extends BaseAsyncCmd {
return "deploying Vm";
}
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.VirtualMachine;
+ }
+
@Override
public void execute(){
try {
diff --git a/api/src/com/cloud/api/commands/DestroyVMCmd.java b/api/src/com/cloud/api/commands/DestroyVMCmd.java
index 6641ab04bed..08de8039a1e 100644
--- a/api/src/com/cloud/api/commands/DestroyVMCmd.java
+++ b/api/src/com/cloud/api/commands/DestroyVMCmd.java
@@ -26,6 +26,7 @@ import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ResourceUnavailableException;
@@ -81,6 +82,14 @@ public class DestroyVMCmd extends BaseAsyncCmd {
public String getEventDescription() {
return "destroying vm: " + getId();
}
+
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.VirtualMachine;
+ }
+
+ public Long getInstanceId() {
+ return getId();
+ }
@Override
public void execute() throws ResourceUnavailableException, ConcurrentOperationException{
diff --git a/api/src/com/cloud/api/commands/ListVMsCmd.java b/api/src/com/cloud/api/commands/ListVMsCmd.java
index 48e958bb4a8..fcfab3b0f46 100644
--- a/api/src/com/cloud/api/commands/ListVMsCmd.java
+++ b/api/src/com/cloud/api/commands/ListVMsCmd.java
@@ -28,6 +28,7 @@ import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.response.ListResponse;
import com.cloud.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
import com.cloud.uservm.UserVm;
@Implementation(description="List the virtual machines owned by the account.", responseObject=UserVmResponse.class)
@@ -126,6 +127,10 @@ public class ListVMsCmd extends BaseListCmd {
return s_name;
}
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.VirtualMachine;
+ }
+
@Override
public void execute(){
List extends UserVm> result = _mgr.searchForUserVMs(this);
diff --git a/api/src/com/cloud/api/commands/RebootVMCmd.java b/api/src/com/cloud/api/commands/RebootVMCmd.java
index 4baa2470ff2..1a08cb92047 100644
--- a/api/src/com/cloud/api/commands/RebootVMCmd.java
+++ b/api/src/com/cloud/api/commands/RebootVMCmd.java
@@ -26,6 +26,7 @@ import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
@@ -79,6 +80,14 @@ public class RebootVMCmd extends BaseAsyncCmd {
return "rebooting user vm: " + getId();
}
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.VirtualMachine;
+ }
+
+ public Long getInstanceId() {
+ return getId();
+ }
+
@Override
public void execute(){
UserVm result = _userVmService.rebootVirtualMachine(this);
diff --git a/api/src/com/cloud/api/commands/ResetVMPasswordCmd.java b/api/src/com/cloud/api/commands/ResetVMPasswordCmd.java
index 040ede9ce76..c84e045b658 100644
--- a/api/src/com/cloud/api/commands/ResetVMPasswordCmd.java
+++ b/api/src/com/cloud/api/commands/ResetVMPasswordCmd.java
@@ -28,6 +28,7 @@ import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
@@ -95,6 +96,14 @@ public class ResetVMPasswordCmd extends BaseAsyncCmd {
public String getEventDescription() {
return "resetting password for vm: " + getId();
}
+
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.VirtualMachine;
+ }
+
+ public Long getInstanceId() {
+ return getId();
+ }
Random _rand = new Random(System.currentTimeMillis());
@Override
diff --git a/api/src/com/cloud/api/commands/StartVMCmd.java b/api/src/com/cloud/api/commands/StartVMCmd.java
index 928ee70f921..cc77fe1fd6b 100644
--- a/api/src/com/cloud/api/commands/StartVMCmd.java
+++ b/api/src/com/cloud/api/commands/StartVMCmd.java
@@ -26,6 +26,7 @@ import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
@@ -89,6 +90,14 @@ public class StartVMCmd extends BaseAsyncCmd {
return "starting user vm: " + getId();
}
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.VirtualMachine;
+ }
+
+ public Long getInstanceId() {
+ return getId();
+ }
+
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException{
try {
diff --git a/api/src/com/cloud/api/commands/StopVMCmd.java b/api/src/com/cloud/api/commands/StopVMCmd.java
index 5de3b1768e3..58ea501311f 100644
--- a/api/src/com/cloud/api/commands/StopVMCmd.java
+++ b/api/src/com/cloud/api/commands/StopVMCmd.java
@@ -26,6 +26,7 @@ import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.api.response.UserVmResponse;
+import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.user.Account;
@@ -84,6 +85,14 @@ public class StopVMCmd extends BaseAsyncCmd {
public String getEventDescription() {
return "stopping user vm: " + getId();
}
+
+ public AsyncJob.Type getInstanceType() {
+ return AsyncJob.Type.VirtualMachine;
+ }
+
+ public Long getInstanceId() {
+ return getId();
+ }
@Override
public void execute() throws ServerApiException, ConcurrentOperationException{
diff --git a/api/src/com/cloud/api/response/BaseResponse.java b/api/src/com/cloud/api/response/BaseResponse.java
index 02ab756ca35..b23de307e1f 100644
--- a/api/src/com/cloud/api/response/BaseResponse.java
+++ b/api/src/com/cloud/api/response/BaseResponse.java
@@ -1,11 +1,14 @@
package com.cloud.api.response;
+import com.cloud.api.ApiConstants;
import com.cloud.api.ResponseObject;
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
public class BaseResponse implements ResponseObject {
private transient String responseName;
private transient String objectName;
-
+
@Override
public String getResponseName() {
return responseName;
@@ -25,5 +28,32 @@ public class BaseResponse implements ResponseObject {
public void setObjectName(String objectName) {
this.objectName = objectName;
}
-
+
+ public Long getObjectId() {
+ return null;
+ }
+
+ // For use by list commands with pending async jobs
+ @SerializedName(ApiConstants.JOB_ID) @Param(description="the ID of the latest async job acting on this object")
+ private Long jobId;
+
+ @SerializedName(ApiConstants.JOB_STATUS) @Param(description="the current status of the latest async job acting on this object")
+ private Integer jobStatus;
+
+ public Long getJobId() {
+ return jobId;
+ }
+
+ public void setJobId(Long jobId) {
+ this.jobId = jobId;
+ }
+
+ public Integer getJobStatus() {
+ return jobStatus;
+ }
+
+ public void setJobStatus(Integer jobStatus) {
+ this.jobStatus = jobStatus;
+ }
+
}
diff --git a/api/src/com/cloud/api/response/DomainRouterResponse.java b/api/src/com/cloud/api/response/DomainRouterResponse.java
index 5eb3db00ac9..6ef83fe6af6 100644
--- a/api/src/com/cloud/api/response/DomainRouterResponse.java
+++ b/api/src/com/cloud/api/response/DomainRouterResponse.java
@@ -28,12 +28,6 @@ public class DomainRouterResponse extends BaseResponse {
@SerializedName(ApiConstants.ID) @Param(description="the id of the router")
private Long id;
- @SerializedName(ApiConstants.JOB_ID) @Param(description="the job ID associated with the router. This is only displayed if the router listed is part of a currently running asynchronous job.")
- private Long jobId;
-
- @SerializedName("jobstatus") @Param(description="the job status associated with the router. This is only displayed if the router listed is part of a currently running asynchronous job.")
- private Integer jobStatus;
-
@SerializedName(ApiConstants.ZONE_ID) @Param(description="the Zone ID for the router")
private Long zoneId;
@@ -117,22 +111,6 @@ public class DomainRouterResponse extends BaseResponse {
this.id = id;
}
- public Long getJobId() {
- return jobId;
- }
-
- public void setJobId(Long jobId) {
- this.jobId = jobId;
- }
-
- public Integer getJobStatus() {
- return jobStatus;
- }
-
- public void setJobStatus(Integer jobStatus) {
- this.jobStatus = jobStatus;
- }
-
public Long getZoneId() {
return zoneId;
}
diff --git a/api/src/com/cloud/api/response/UserVmResponse.java b/api/src/com/cloud/api/response/UserVmResponse.java
index 7b375869f8f..e06ec3c1a1a 100644
--- a/api/src/com/cloud/api/response/UserVmResponse.java
+++ b/api/src/com/cloud/api/response/UserVmResponse.java
@@ -141,6 +141,10 @@ public class UserVmResponse extends BaseResponse {
@SerializedName("jobstatus") @Param(description="shows the current pending asynchronous job status")
private Integer jobStatus;
+ public Long getObjectId() {
+ return getId();
+ }
+
public Long getId() {
return id;
}
diff --git a/api/src/com/cloud/async/AsyncJob.java b/api/src/com/cloud/async/AsyncJob.java
index 644771441c8..d9eca636556 100644
--- a/api/src/com/cloud/async/AsyncJob.java
+++ b/api/src/com/cloud/async/AsyncJob.java
@@ -20,6 +20,15 @@ package com.cloud.async;
import java.util.Date;
public interface AsyncJob {
+ public enum Type {
+ None,
+ VirtualMachine,
+ Router,
+ Volume,
+ ConsoleProxy,
+ Snapshot
+ }
+
Long getId();
long getUserId();
long getAccountId();
@@ -38,7 +47,7 @@ public interface AsyncJob {
Date getLastUpdated();
Date getLastPolled();
Date getRemoved();
- String getInstanceType();
+ Type getInstanceType();
Long getInstanceId();
String getSessionKey();
String getCmdOriginator();
diff --git a/core/.classpath b/core/.classpath
index 1867836084a..f2fff92d833 100644
--- a/core/.classpath
+++ b/core/.classpath
@@ -38,6 +38,6 @@
-
+
diff --git a/core/src/com/cloud/async/AsyncJobVO.java b/core/src/com/cloud/async/AsyncJobVO.java
index f2da44f9922..bb40e8c4521 100644
--- a/core/src/com/cloud/async/AsyncJobVO.java
+++ b/core/src/com/cloud/async/AsyncJobVO.java
@@ -22,6 +22,8 @@ import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@@ -81,9 +83,10 @@ public class AsyncJobVO implements AsyncJob {
@Column(name="job_result", length=65535)
private String result;
-
+
+ @Enumerated(value=EnumType.STRING)
@Column(name="instance_type", length=64)
- private String instanceType;
+ private Type instanceType;
@Column(name="instance_id", length=64)
private Long instanceId;
@@ -296,11 +299,11 @@ public class AsyncJobVO implements AsyncJob {
}
@Override
- public String getInstanceType() {
+ public Type getInstanceType() {
return instanceType;
}
- public void setInstanceType(String instanceType) {
+ public void setInstanceType(Type instanceType) {
this.instanceType = instanceType;
}
diff --git a/server/.classpath b/server/.classpath
index fe6302cf152..fddc52a165d 100644
--- a/server/.classpath
+++ b/server/.classpath
@@ -20,6 +20,6 @@
-
+
diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java
index bab80089e92..6c2e9288d85 100755
--- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java
+++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java
@@ -21,6 +21,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URLEncoder;
import java.nio.channels.ClosedChannelException;
import java.util.ArrayList;
import java.util.Enumeration;
@@ -143,6 +144,7 @@ import com.cloud.uservm.UserVm;
import com.cloud.utils.ActionDelegate;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
+import com.cloud.utils.UriUtils;
import com.cloud.utils.component.Adapters;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
@@ -583,7 +585,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, ResourceS
}
try {
- uri = new URI(url);
+ uri = new URI(UriUtils.encodeURIComponent(url));
if (uri.getScheme() == null)
throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// as a prefix");
else if (uri.getScheme().equalsIgnoreCase("nfs")) {
diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java
index 1ba61a4d6c4..c55d5642691 100644
--- a/server/src/com/cloud/api/ApiDispatcher.java
+++ b/server/src/com/cloud/api/ApiDispatcher.java
@@ -143,6 +143,14 @@ public class ApiDispatcher {
public static void setupParameters(BaseCmd cmd, Map params){
Map unpackedParams = cmd.unpackParams(params);
+ if (cmd instanceof BaseListCmd) {
+ if ((unpackedParams.get(ApiConstants.PAGE) == null) && (unpackedParams.get(ApiConstants.PAGE_SIZE) != null)) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "\"page\" parameter is required when \"pagesize\" is specified");
+ } else if ((unpackedParams.get(ApiConstants.PAGE_SIZE) == null) && (unpackedParams.get(ApiConstants.PAGE) != null)) {
+ throw new ServerApiException(BaseCmd.PARAM_ERROR, "\"pagesize\" parameter is required when \"page\" is specified");
+ }
+ }
+
Field[] fields = cmd.getClass().getDeclaredFields();
Class> superClass = cmd.getClass().getSuperclass();
while (BaseCmd.class.isAssignableFrom(superClass)) {
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index b6849bb3226..4c8252be2d9 100644
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -606,12 +606,6 @@ public class ApiResponseHelper implements ResponseGenerator {
DomainRouterResponse routerResponse = new DomainRouterResponse();
routerResponse.setId(router.getId());
- AsyncJobVO asyncJob = ApiDBUtils.findInstancePendingAsyncJob("domain_router", router.getId());
- if (asyncJob != null) {
- routerResponse.setJobId(asyncJob.getId());
- routerResponse.setJobStatus(asyncJob.getStatus());
- }
-
routerResponse.setZoneId(router.getDataCenterId());
routerResponse.setZoneName(ApiDBUtils.findZoneById(router.getDataCenterId()).getName());
routerResponse.setDns1(router.getDns1());
@@ -1266,12 +1260,6 @@ public class ApiResponseHelper implements ResponseGenerator {
routerResponse.setDomainName(ApiDBUtils.findDomainById(accountTemp.getDomainId()).getName());
}
- AsyncJobVO asyncJob = ApiDBUtils.findInstancePendingAsyncJob("domain_router", router.getId());
- if (asyncJob != null) {
- routerResponse.setJobId(asyncJob.getId());
- routerResponse.setJobStatus(asyncJob.getStatus());
- }
-
List extends Nic> nics = ApiDBUtils.getNics(router);
for (Nic singleNic : nics) {
Long configId = singleNic.getNetworkId();
@@ -1912,7 +1900,7 @@ public class ApiResponseHelper implements ResponseGenerator {
jobResponse.setCreated(job.getCreated());
jobResponse.setId(job.getId());
jobResponse.setJobInstanceId(job.getInstanceId());
- jobResponse.setJobInstanceType(job.getInstanceType());
+ jobResponse.setJobInstanceType(job.getInstanceType().toString());
jobResponse.setJobProcStatus(job.getProcessStatus());
jobResponse.setJobResult((ResponseObject)ApiSerializerHelper.fromSerializedString(job.getResult()));
jobResponse.setJobResultCode(job.getResultCode());
diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java
index 0120fbf02c5..dba8252ea3b 100755
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@ -80,6 +80,8 @@ import org.apache.http.protocol.ResponseServer;
import org.apache.log4j.Logger;
import com.cloud.api.response.ApiResponseSerializer;
+import com.cloud.api.response.ListResponse;
+import com.cloud.async.AsyncJob;
import com.cloud.async.AsyncJobManager;
import com.cloud.async.AsyncJobVO;
import com.cloud.configuration.ConfigurationVO;
@@ -363,6 +365,9 @@ public class ApiServer implements HttpRequestHandler {
}
private String queueCommand(BaseCmd cmdObj, Map params) {
+ UserContext ctx = UserContext.current();
+ Long userId = ctx.getUserId();
+ Account account = ctx.getAccount();
if (cmdObj instanceof BaseAsyncCmd) {
Long objectId = null;
if (cmdObj instanceof BaseAsyncCreateCmd) {
@@ -375,10 +380,10 @@ public class ApiServer implements HttpRequestHandler {
}
BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmdObj;
+ if (objectId != null) {
+ objectId = asyncCmd.getInstanceId();
+ }
- UserContext ctx = UserContext.current();
- Long userId = ctx.getUserId();
- Account account = ctx.getAccount();
if (userId != null) {
params.put("ctxUserId", userId.toString());
}
@@ -395,6 +400,8 @@ public class ApiServer implements HttpRequestHandler {
}
AsyncJobVO job = new AsyncJobVO();
+ job.setInstanceId(asyncCmd.getInstanceId());
+ job.setInstanceType(asyncCmd.getInstanceType());
job.setUserId(userId);
if (account != null) {
job.setAccountId(ctx.getAccount().getId());
@@ -414,8 +421,36 @@ public class ApiServer implements HttpRequestHandler {
return ApiResponseSerializer.toSerializedString(asyncCmd.getResponse(jobId), asyncCmd.getResponseType());
} else {
_dispatcher.dispatch(cmdObj, params);
+
+ // if the command is of the listXXXCommand, we will need to also return the
+ // the job id and status if possible
+ if (cmdObj instanceof BaseListCmd) {
+ buildAsyncListResponse((BaseListCmd)cmdObj, account);
+ }
return ApiResponseSerializer.toSerializedString((ResponseObject)cmdObj.getResponseObject(), cmdObj.getResponseType());
}
+ }
+
+ private void buildAsyncListResponse(BaseListCmd command, Account account) {
+ List responses = ((ListResponse)command.getResponseObject()).getResponses();
+ if (responses != null && responses.size() > 0) {
+ List extends AsyncJob> jobs = _asyncMgr.findInstancePendingAsyncJobs(command.getInstanceType(), account.getId());
+ if (jobs.size() == 0) {
+ return;
+ }
+
+ // Using maps might possibly be more efficient if the set is large enough but for now, we'll just n squared
+ // comparison of two lists. Either way, there shouldn't be too many async jobs active for the account.
+ for (AsyncJob job : jobs) {
+ if (job.getInstanceId() == null) continue;
+ for (ResponseObject response : responses) {
+ if (job.getInstanceId() == response.getObjectId()) {
+ response.setJobId(job.getId());
+ response.setJobStatus(job.getStatus());
+ }
+ }
+ }
+ }
}
private void buildAuditTrail(StringBuffer auditTrailSb, String command, String result) {
diff --git a/server/src/com/cloud/async/AsyncJobManager.java b/server/src/com/cloud/async/AsyncJobManager.java
index 3292e573480..d34a833e3a0 100644
--- a/server/src/com/cloud/async/AsyncJobManager.java
+++ b/server/src/com/cloud/async/AsyncJobManager.java
@@ -18,16 +18,20 @@
package com.cloud.async;
+import java.util.List;
+
import com.cloud.api.commands.QueryAsyncJobResultCmd;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
+import com.cloud.user.UserAccount;
import com.cloud.utils.component.Manager;
public interface AsyncJobManager extends Manager {
public AsyncJobExecutorContext getExecutorContext();
public AsyncJobVO getAsyncJob(long jobId);
- public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId);
+ public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId);
+ public List extends AsyncJob> findInstancePendingAsyncJobs(AsyncJob.Type instanceType, long accountId);
public long submitAsyncJob(AsyncJobVO job);
public long submitAsyncJob(AsyncJobVO job, boolean scheduleJobExecutionInContext);
diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java
index 5e87f6a3404..78f7a061f12 100644
--- a/server/src/com/cloud/async/AsyncJobManagerImpl.java
+++ b/server/src/com/cloud/async/AsyncJobManagerImpl.java
@@ -99,6 +99,11 @@ public class AsyncJobManagerImpl implements AsyncJobManager {
@Override
public AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) {
return _jobDao.findInstancePendingAsyncJob(instanceType, instanceId);
+ }
+
+ @Override
+ public List findInstancePendingAsyncJobs(AsyncJob.Type instanceType, long accountId) {
+ return _jobDao.findInstancePendingAsyncJobs(instanceType, accountId);
}
@Override
@@ -111,7 +116,7 @@ public class AsyncJobManagerImpl implements AsyncJobManager {
Transaction txt = Transaction.currentTxn();
try {
txt.start();
- job.setInitMsid(getMsid());
+ job.setInitMsid(getMsid());
_jobDao.persist(job);
txt.commit();
@@ -210,7 +215,7 @@ public class AsyncJobManagerImpl implements AsyncJobManager {
txt.start();
AsyncJobVO job = _jobDao.createForUpdate();
- job.setInstanceType(instanceType);
+ //job.setInstanceType(instanceType);
job.setInstanceId(instanceId);
job.setLastUpdated(DateUtil.currentGMTTime());
_jobDao.update(jobId, job);
diff --git a/server/src/com/cloud/async/dao/AsyncJobDao.java b/server/src/com/cloud/async/dao/AsyncJobDao.java
index 192a6fa05b2..b3e27bc1fc1 100644
--- a/server/src/com/cloud/async/dao/AsyncJobDao.java
+++ b/server/src/com/cloud/async/dao/AsyncJobDao.java
@@ -21,10 +21,12 @@ package com.cloud.async.dao;
import java.util.Date;
import java.util.List;
+import com.cloud.async.AsyncJob;
import com.cloud.async.AsyncJobVO;
import com.cloud.utils.db.GenericDao;
public interface AsyncJobDao extends GenericDao {
AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId);
+ List findInstancePendingAsyncJobs(AsyncJob.Type instanceType, long accountId);
List getExpiredJobs(Date cutTime, int limit);
}
diff --git a/server/src/com/cloud/async/dao/AsyncJobDaoImpl.java b/server/src/com/cloud/async/dao/AsyncJobDaoImpl.java
index 13564f43961..54b2b4732e5 100644
--- a/server/src/com/cloud/async/dao/AsyncJobDaoImpl.java
+++ b/server/src/com/cloud/async/dao/AsyncJobDaoImpl.java
@@ -25,6 +25,7 @@ import javax.ejb.Local;
import org.apache.log4j.Logger;
+import com.cloud.async.AsyncJob;
import com.cloud.async.AsyncJobResult;
import com.cloud.async.AsyncJobVO;
import com.cloud.utils.db.Filter;
@@ -36,7 +37,8 @@ import com.cloud.utils.db.SearchCriteria;
public class AsyncJobDaoImpl extends GenericDaoBase implements AsyncJobDao {
private static final Logger s_logger = Logger.getLogger(AsyncJobDaoImpl.class.getName());
- private SearchBuilder pendingAsyncJobSearch;
+ private SearchBuilder pendingAsyncJobSearch;
+ private SearchBuilder pendingAsyncJobsSearch;
private SearchBuilder expiringAsyncJobSearch;
public AsyncJobDaoImpl() {
@@ -49,6 +51,15 @@ public class AsyncJobDaoImpl extends GenericDaoBase implements
SearchCriteria.Op.EQ);
pendingAsyncJobSearch.done();
+ pendingAsyncJobsSearch = createSearchBuilder();
+ pendingAsyncJobsSearch.and("instanceType", pendingAsyncJobsSearch.entity().getInstanceType(),
+ SearchCriteria.Op.EQ);
+ pendingAsyncJobsSearch.and("accountId", pendingAsyncJobsSearch.entity().getAccountId(),
+ SearchCriteria.Op.EQ);
+ pendingAsyncJobsSearch.and("status", pendingAsyncJobsSearch.entity().getStatus(),
+ SearchCriteria.Op.EQ);
+ pendingAsyncJobsSearch.done();
+
expiringAsyncJobSearch = createSearchBuilder();
expiringAsyncJobSearch.and("created", expiringAsyncJobSearch.entity().getCreated(),
SearchCriteria.Op.LTEQ);
@@ -72,6 +83,15 @@ public class AsyncJobDaoImpl extends GenericDaoBase implements
return null;
}
+ public List findInstancePendingAsyncJobs(AsyncJob.Type instanceType, long accountId) {
+ SearchCriteria sc = pendingAsyncJobsSearch.create();
+ sc.setParameters("instanceType", instanceType);
+ sc.setParameters("accountId", accountId);
+ sc.setParameters("status", AsyncJobResult.STATUS_IN_PROGRESS);
+
+ return listBy(sc);
+ }
+
public List getExpiredJobs(Date cutTime, int limit) {
SearchCriteria sc = expiringAsyncJobSearch.create();
sc.setParameters("created", cutTime);
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 4e3b69d5d1c..0b14e777626 100644
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -183,7 +183,6 @@ public enum Config {
VmwarePrivateNetworkVSwitch("Advanced", ManagementServer.class, String.class, "vmware.private.vswitch", null, "Specify the vSwitch on host for private network", null),
VmwarePublicNetworkVSwitch("Advanced", ManagementServer.class, String.class, "vmware.public.vswitch", null, "Specify the vSwitch on host for public network", null),
VmwareGuestNetworkVSwitch("Advanced", ManagementServer.class, String.class, "vmware.guest.vswitch", null, "Specify the vSwitch on host for guest network", null),
- VmwarePrivateNetwork("Advanced", ManagementServer.class, String.class, "vmware.private.network", null, "Specify the private network on the vSwitch", null),
// Premium
diff --git a/ui/index.jsp b/ui/index.jsp
index 90a0e573522..de626da15e2 100644
--- a/ui/index.jsp
+++ b/ui/index.jsp
@@ -423,9 +423,9 @@
");
$midmenuContainer.append($container_primarystorage);
var $header2 = $("#midmenu_itemheader_with_margin").clone().show(); //with margin on top
$header2.find("#name").text("Primary Storage");
$container_primarystorage.append($header2);
- listMidMenuItems2(("listStoragePools&clusterid="+clusterId), "liststoragepoolsresponse", "storagepool", primarystorageToMidmenu, primarystorageToRightPanel, primarystorageGetMidmenuId, false, false, $container_primarystorage);
+ //listMidMenuItems2(("listStoragePools&clusterid="+clusterId), "liststoragepoolsresponse", "storagepool", primarystorageToMidmenu, primarystorageToRightPanel, primarystorageGetMidmenuId, false, 1);
+ var count = 0;
+ $.ajax({
+ cache: false,
+ data: createURL("command=listStoragePools&clusterid="+clusterId),
+ dataType: "json",
+ async: false,
+ success: function(json) {
+ selectedItemsInMidMenu = {};
+ var items = json.liststoragepoolsresponse.storagepool;
+ if(items != null && items.length > 0) {
+ for(var i=0; i 0) {
+ jsonObj = items[0];
+ $midmenuItem1.data("jsonObj", jsonObj);
+ }
+ }
+ });
+
var $thisTab = $("#right_panel_content #tab_content_details");
$thisTab.find("#tab_container").hide();
$thisTab.find("#tab_spinning_wheel").show();
@@ -370,7 +383,7 @@ function hostClearDetailsTab() {
function populateForUpdateOSDialog(oscategoryid) {
$.ajax({
- data: createURL("command=listOsCategories"+maxPageSize),
+ data: createURL("command=listOsCategories"),
dataType: "json",
success: function(json) {
var categories = json.listoscategoriesresponse.oscategory;
diff --git a/ui/scripts/cloud.core.init.js b/ui/scripts/cloud.core.init.js
index 02c597428c8..0afa5e57d8f 100644
--- a/ui/scripts/cloud.core.init.js
+++ b/ui/scripts/cloud.core.init.js
@@ -210,8 +210,27 @@ $(document).ready(function() {
return;
}
+ //pagination
+ $("#middle_menu_pagination").unbind("clik").bind("click", function(event) {
+ var params = $(this).data("params");
+ if(params == null)
+ return;
+
+ var $target = $(event.target);
+ var targetId = $target.attr("id");
+
+ if(targetId == "midmenu_prevbutton") {
+ listMidMenuItems2(params.commandString, params.jsonResponse1, params.jsonResponse2, params.toMidmenuFn, params.toRightPanelFn, params.getMidmenuIdFn, params.isMultipleSelectionInMidMenu, (params.page-1));
+ }
+ else if(targetId == "midmenu_nextbutton") {
+ listMidMenuItems2(params.commandString, params.jsonResponse1, params.jsonResponse2, params.toMidmenuFn, params.toRightPanelFn, params.getMidmenuIdFn, params.isMultipleSelectionInMidMenu, (params.page+1));
+ }
+
+ return false;
+ });
+
// refresh button
- $("#refresh_link").bind("click", function(event) {
+ $("#refresh_link").unbind("clik").bind("click", function(event) {
var onRefreshFn = $("#right_panel").data("onRefreshFn");
if(onRefreshFn != null)
onRefreshFn();
@@ -219,13 +238,13 @@ $(document).ready(function() {
});
// Initialize help drop down dialog
- $("#help_link").bind("click", function(event) {
+ $("#help_link").unbind("clik").bind("click", function(event) {
$("#help_dropdown_dialog").show();
$("#help_button").addClass("selected");
return false;
});
- $("#help_dropdown_close").bind("click", function(event) {
+ $("#help_dropdown_close").unbind("clik").bind("click", function(event) {
$("#help_dropdown_dialog").hide();
$("#help_button").removeClass("selected");
return false;
diff --git a/ui/scripts/cloud.core.instance.js b/ui/scripts/cloud.core.instance.js
index 4256b3bee79..c418aa4ad93 100644
--- a/ui/scripts/cloud.core.instance.js
+++ b/ui/scripts/cloud.core.instance.js
@@ -507,7 +507,7 @@ function initVMWizard() {
return false; //event.preventDefault() + event.stopPropagation()
});
- var vmPopupStep2PageSize = 11; //max number of templates each page in step2 of New VM wizard is 11
+ var vmPopupTemplatePageSize = 6; //max number of templates in VM wizard
function listTemplatesInVmPopup() {
var zoneId = $vmPopup.find("#wizard_zone").val();
if(zoneId == null || zoneId.length == 0)
@@ -520,18 +520,20 @@ function initVMWizard() {
if (selectedTemplateTypeInVmPopup != "blank") { //*** template ***
templateType = "template";
if (searchInput != null && searchInput.length > 0)
- commandString = "command=listTemplates&templatefilter="+selectedTemplateTypeInVmPopup+"&zoneid="+zoneId+"&keyword="+searchInput+"&page="+currentPageInTemplateGridInVmPopup;
+ commandString = "command=listTemplates&templatefilter="+selectedTemplateTypeInVmPopup+"&zoneid="+zoneId+"&keyword="+searchInput;
else
- commandString = "command=listTemplates&templatefilter="+selectedTemplateTypeInVmPopup+"&zoneid="+zoneId+"&page="+currentPageInTemplateGridInVmPopup;
+ commandString = "command=listTemplates&templatefilter="+selectedTemplateTypeInVmPopup+"&zoneid="+zoneId;
}
else { //*** ISO ***
templateType = "ISO";
if (searchInput != null && searchInput.length > 0)
- commandString = "command=listIsos&isReady=true&bootable=true&zoneid="+zoneId+"&keyword="+searchInput+"&page="+currentPageInTemplateGridInVmPopup;
+ commandString = "command=listIsos&isReady=true&bootable=true&zoneid="+zoneId+"&keyword="+searchInput;
else
- commandString = "command=listIsos&isReady=true&bootable=true&zoneid="+zoneId+"&page="+currentPageInTemplateGridInVmPopup;
+ commandString = "command=listIsos&isReady=true&bootable=true&zoneid="+zoneId;
}
-
+
+ commandString += "&pagesize="+vmPopupTemplatePageSize+"&page="+currentPageInTemplateGridInVmPopup;
+
var loading = $vmPopup.find("#wiz_template_loading").show();
if(currentPageInTemplateGridInVmPopup==1)
$vmPopup.find("#prevPage").hide();
@@ -561,7 +563,7 @@ function initVMWizard() {
vmWizardTemplateJsonToTemplate(items[i], $newTemplate, templateType, i);
container.append($newTemplate.show());
}
- if(items.length < vmPopupStep2PageSize)
+ if(items.length < vmPopupTemplatePageSize)
$vmPopup.find("#nextPage").hide();
else
$vmPopup.find("#nextPage").show();
@@ -1422,7 +1424,7 @@ function vmJsonToVolumeTab() {
$.ajax({
cache: false,
- data: createURL("command=listVolumes&virtualMachineId="+jsonObj.id+maxPageSize),
+ data: createURL("command=listVolumes&virtualMachineId="+jsonObj.id),
dataType: "json",
success: function(json) {
var items = json.listvolumesresponse.volume;
@@ -1487,7 +1489,7 @@ function vmJsonToRouterTab() {
$.ajax({
cache: false,
- data: createURL("command=listRouters&domainid="+vmObj.domainid+"&account="+vmObj.account+maxPageSize),
+ data: createURL("command=listRouters&domainid="+vmObj.domainid+"&account="+vmObj.account),
dataType: "json",
success: function(json) {
var items = json.listroutersresponse.router;
@@ -1669,7 +1671,7 @@ function appendInstanceGroup(groupId, groupName) {
var groupId = $(this).data("groupId");
$.ajax({
cache: false,
- data: createURL("command=listVirtualMachines&groupid="+groupId+"&pagesize="+midmenuItemCount),
+ data: createURL("command=listVirtualMachines&groupid="+groupId+"&pagesize="+midmenuItemCount+"&page=1"),
dataType: "json",
success: function(json) {
var instances = json.listvirtualmachinesresponse.virtualmachine;
diff --git a/ui/scripts/cloud.core.ipaddress.js b/ui/scripts/cloud.core.ipaddress.js
index 5ed27be564f..77d88766ac5 100644
--- a/ui/scripts/cloud.core.ipaddress.js
+++ b/ui/scripts/cloud.core.ipaddress.js
@@ -35,7 +35,7 @@ function afterLoadIpJSP() {
//*** Acquire New IP (begin) ***
$.ajax({
- data: createURL("command=listZones&available=true"+maxPageSize),
+ data: createURL("command=listZones&available=true"),
dataType: "json",
success: function(json) {
var zones = json.listzonesresponse.zone;
diff --git a/ui/scripts/cloud.core.js b/ui/scripts/cloud.core.js
index aa0637821d1..d5f3ab8f158 100644
--- a/ui/scripts/cloud.core.js
+++ b/ui/scripts/cloud.core.js
@@ -567,7 +567,9 @@ function setBooleanEditField(value, $field) {
function clearMiddleMenu() {
$("#midmenu_container").empty();
$("#midmenu_action_link").hide();
- clearAddButtonsOnTop();
+ clearAddButtonsOnTop();
+ $("#midmenu_prevbutton, #midmenu_nextbutton").hide();
+ $("#middle_menu_pagination").data("params", null);
}
function clearAddButtonsOnTop() {
@@ -581,11 +583,7 @@ function clearAddButtonsOnTop() {
$("#midmenu_add_vlan_button").unbind("click").hide();
$("#midmenu_add_directIpRange_button").unbind("click").hide();
$("#midmenu_Update_SSL_Certificate_button").unbind("click").hide();
- /*
- $("#midmenu_add2_link").unbind("click").hide();
- $("#midmenu_add3_link").unbind("click").hide();
- */
-
+
$("#midmenu_startvm_link").unbind("click").hide();
$("#midmenu_stopvm_link").unbind("click").hide();
$("#midmenu_rebootvm_link").unbind("click").hide();
@@ -928,7 +926,21 @@ function getMidmenuId(jsonObj) {
return "midmenuItem_" + jsonObj.id;
}
-function listMidMenuItems2(commandString, jsonResponse1, jsonResponse2, toMidmenuFn, toRightPanelFn, getMidmenuIdFn, isMultipleSelectionInMidMenu, clickFirstItem, $midMenuContainer) {
+function listMidMenuItems2(commandString, jsonResponse1, jsonResponse2, toMidmenuFn, toRightPanelFn, getMidmenuIdFn, isMultipleSelectionInMidMenu, page) {
+ var params = {
+ "commandString": commandString,
+ "jsonResponse1": jsonResponse1,
+ "jsonResponse2": jsonResponse2,
+ "toMidmenuFn": toMidmenuFn,
+ "toRightPanelFn": toRightPanelFn,
+ "getMidmenuIdFn": getMidmenuIdFn,
+ "isMultipleSelectionInMidMenu": isMultipleSelectionInMidMenu,
+ "page": page
+ }
+ $("#middle_menu_pagination").data("params", params);
+
+ (page > 1)? $("#midmenu_prevbutton").show(): $("#midmenu_prevbutton").hide();
+
if(isMultipleSelectionInMidMenu == true)
enableMultipleSelectionInMidMenu();
else
@@ -937,24 +949,23 @@ function listMidMenuItems2(commandString, jsonResponse1, jsonResponse2, toMidmen
var count = 0;
$.ajax({
cache: false,
- data: createURL("command="+commandString+"&pagesize="+midmenuItemCount),
+ data: createURL("command="+commandString+"&pagesize="+midmenuItemCount+"&page="+page),
dataType: "json",
async: false,
- success: function(json) {
- selectedItemsInMidMenu = {};
+ success: function(json) {
+ selectedItemsInMidMenu = {};
+ $("#midmenu_container").empty();
var items = json[jsonResponse1][jsonResponse2];
if(items != null && items.length > 0) {
+ (items.length == midmenuItemCount)? $("#midmenu_nextbutton").show(): $("#midmenu_nextbutton").hide();
for(var i=0; i 0) {
@@ -1457,7 +1466,7 @@ function submenuContentEventBinder(submenuContent, listFunction) {
var zoneSelect = submenuContent.find("#advanced_search #adv_search_zone");
if(zoneSelect.length>0) { //if zone dropdown is found on Advanced Search dialog
$.ajax({
- data: createURL("command=listZones&available=true&response=json"+maxPageSize),
+ data: createURL("command=listZones&available=true&response=json"),
dataType: "json",
success: function(json) {
var zones = json.listzonesresponse.zone;
@@ -1484,7 +1493,7 @@ function submenuContentEventBinder(submenuContent, listFunction) {
podLabel.css("color", "black");
podSelect.removeAttr("disabled");
$.ajax({
- data: createURL("command=listPods&zoneId="+zoneId+"&response=json"+maxPageSize),
+ data: createURL("command=listPods&zoneId="+zoneId+"&response=json"),
dataType: "json",
async: false,
success: function(json) {
@@ -1509,7 +1518,7 @@ function submenuContentEventBinder(submenuContent, listFunction) {
if(domainSelect.length>0 && isAdmin()) {
var domainSelect = domainSelect.empty();
$.ajax({
- data: createURL("command=listDomains&available=true&response=json"+maxPageSize),
+ data: createURL("command=listDomains&available=true&response=json"),
dataType: "json",
success: function(json) {
var domains = json.listdomainsresponse.domain;
@@ -1527,7 +1536,7 @@ function submenuContentEventBinder(submenuContent, listFunction) {
vmSelect.empty();
vmSelect.append("");
$.ajax({
- data: createURL("command=listVirtualMachines&response=json"+maxPageSize),
+ data: createURL("command=listVirtualMachines&response=json"),
dataType: "json",
success: function(json) {
var items = json.listvirtualmachinesresponse.virtualmachine;
@@ -1540,6 +1549,7 @@ function submenuContentEventBinder(submenuContent, listFunction) {
});
}
}
+*/
// Validation functions
function showError(isValid, field, errMsgField, errMsg) {
diff --git a/ui/scripts/cloud.core.primarystorage.js b/ui/scripts/cloud.core.primarystorage.js
index bfb5946fcb9..2a2001e9056 100644
--- a/ui/scripts/cloud.core.primarystorage.js
+++ b/ui/scripts/cloud.core.primarystorage.js
@@ -60,6 +60,19 @@ function primarystorageJsonToDetailsTab() {
if(jsonObj == null)
return;
+ $.ajax({
+ data: createURL("command=listStoragePools&id="+jsonObj.id),
+ dataType: "json",
+ async: false,
+ success: function(json) {
+ var items = json.liststoragepoolsresponse.storagepool;
+ if(items != null && items.length > 0) {
+ jsonObj = items[0];
+ $midmenuItem1.data("jsonObj", jsonObj);
+ }
+ }
+ });
+
var $thisTab = $("#right_panel_content").find("#tab_content_details");
$thisTab.find("#tab_container").hide();
$thisTab.find("#tab_spinning_wheel").show();
diff --git a/ui/scripts/cloud.core.resource.js b/ui/scripts/cloud.core.resource.js
index 92f8017f429..7430f799eb3 100644
--- a/ui/scripts/cloud.core.resource.js
+++ b/ui/scripts/cloud.core.resource.js
@@ -22,7 +22,7 @@ function buildZoneTree() {
var $zoneTree = $("#leftmenu_zone_tree").find("#tree_container").hide();
$.ajax({
- data: createURL("command=listZones&available=true"+maxPageSize),
+ data: createURL("command=listZones&available=true"),
dataType: "json",
success: function(json) {
var items = json.listzonesresponse.zone;
@@ -55,7 +55,7 @@ function buildZoneTree() {
$zoneContent.show();
$.ajax({
- data: createURL("command=listPods&zoneid="+zoneObj.id+maxPageSize),
+ data: createURL("command=listPods&zoneid="+zoneObj.id),
dataType: "json",
async: false,
success: function(json) {
@@ -126,7 +126,7 @@ function buildZoneTree() {
function refreshClusterUnderPod($podNode, newClusterName, existingClusterId, noClicking) {
var podId = $podNode.data("podId");
$.ajax({
- data: createURL("command=listClusters&podid="+podId+maxPageSize),
+ data: createURL("command=listClusters&podid="+podId),
dataType: "json",
async: false,
success: function(json) {
@@ -176,7 +176,7 @@ function zoneJSONToTreeNode(json, $zoneNode) {
zoneName.data("jsonObj", json);
$.ajax({
- data: createURL("command=listPods&zoneid="+zoneid+maxPageSize),
+ data: createURL("command=listPods&zoneid="+zoneid),
dataType: "json",
async: false,
success: function(json) {
@@ -216,34 +216,38 @@ function resourceLoadPage(pageToShow, $midmenuItem1) { //$midmenuItem1 is eith
if(pageToShow == "jsp/resource.jsp") {
afterLoadResourceJSP($midmenuItem1);
}
- else if(pageToShow == "jsp/zone.jsp") {
- afterLoadZoneJSP($midmenuItem1);
-
+ else if(pageToShow == "jsp/zone.jsp") {
$(this).data("onRefreshFn", function() {
zoneJsonToDetailsTab();
- });
+ });
+ afterLoadZoneJSP($midmenuItem1);
}
- else if(pageToShow == "jsp/pod.jsp") {
- afterLoadPodJSP($midmenuItem1);
-
+ else if(pageToShow == "jsp/pod.jsp") {
$(this).data("onRefreshFn", function() {
podJsonToDetailsTab();
});
+ afterLoadPodJSP($midmenuItem1);
}
else if(pageToShow == "jsp/cluster.jsp") {
- afterLoadClusterJSP($midmenuItem1);
-
$(this).data("onRefreshFn", function() {
clusterJsonToDetailsTab();
- });
+ });
+ afterLoadClusterJSP($midmenuItem1);
}
- else if(pageToShow == "jsp/host.jsp") {
- afterLoadHostJSP($midmenuItem1);
+ else if(pageToShow == "jsp/host.jsp") {
+ $(this).data("onRefreshFn", function() {
+ hostJsonToDetailsTab();
+ });
+ afterLoadHostJSP($midmenuItem1);
+
copyActionInfoFromMidMenuToRightPanel($midmenuItem1);
$("#right_panel_content").data("$midmenuItem1", $midmenuItem1);
$("#tab_details").click();
}
else if(pageToShow == "jsp/primarystorage.jsp") {
+ $(this).data("onRefreshFn", function() {
+ primarystorageJsonToDetailsTab();
+ });
afterLoadPrimaryStorageJSP($midmenuItem1);
}
});
@@ -624,7 +628,7 @@ function initAddZoneWizard() {
var domainDropdown = $addZoneWizard.find("#domain_dropdown").empty();
$.ajax({
- data: createURL("command=listDomains"+maxPageSize),
+ data: createURL("command=listDomains"),
dataType: "json",
async: false,
success: function(json) {
diff --git a/ui/scripts/cloud.core.template.js b/ui/scripts/cloud.core.template.js
index 510cba5cdbd..10c3287d983 100644
--- a/ui/scripts/cloud.core.template.js
+++ b/ui/scripts/cloud.core.template.js
@@ -120,7 +120,7 @@ function afterLoadTemplateJSP() {
if (isAdmin())
addTemplateZoneField.append("");
$.ajax({
- data: createURL("command=listZones&available=true"+maxPageSize),
+ data: createURL("command=listZones&available=true"),
dataType: "json",
success: function(json) {
var zones = json.listzonesresponse.zone;
@@ -135,7 +135,7 @@ function afterLoadTemplateJSP() {
});
$.ajax({
- data: createURL("command=listOsTypes&response=json"+maxPageSize),
+ data: createURL("command=listOsTypes&response=json"),
dataType: "json",
success: function(json) {
types = json.listostypesresponse.ostype;
@@ -154,7 +154,7 @@ function afterLoadTemplateJSP() {
});
$.ajax({
- data: createURL("command=listServiceOfferings&response=json"+maxPageSize),
+ data: createURL("command=listServiceOfferings&response=json"),
dataType: "json",
success: function(json) {
var items = json.listserviceofferingsresponse.serviceoffering;
@@ -167,7 +167,7 @@ function afterLoadTemplateJSP() {
});
$.ajax({
- data: createURL("command=listDiskOfferings&response=json"+maxPageSize),
+ data: createURL("command=listDiskOfferings&response=json"),
dataType: "json",
success: function(json) {
var items = json.listdiskofferingsresponse.diskoffering;
diff --git a/ui/scripts/cloud.core.volume.js b/ui/scripts/cloud.core.volume.js
index 4cd619c8f09..437b27ac8f6 100644
--- a/ui/scripts/cloud.core.volume.js
+++ b/ui/scripts/cloud.core.volume.js
@@ -43,7 +43,7 @@ function afterLoadVolumeJSP() {
});
$.ajax({
- data: createURL("command=listZones&available=true"+maxPageSize),
+ data: createURL("command=listZones&available=true"),
dataType: "json",
success: function(json) {
var zones = json.listzonesresponse.zone;
@@ -773,7 +773,7 @@ function doRecurringSnapshot($actionLink, $detailsTab, $midmenuItem1) {
function populateVirtualMachineField(domainId, account, zoneId) {
$.ajax({
cache: false,
- data: createURL("command=listVirtualMachines&state=Running&zoneid="+zoneId+"&domainid="+domainId+"&account="+account+maxPageSize),
+ data: createURL("command=listVirtualMachines&state=Running&zoneid="+zoneId+"&domainid="+domainId+"&account="+account),
dataType: "json",
success: function(json) {
var instances = json.listvirtualmachinesresponse.virtualmachine;
@@ -785,7 +785,7 @@ function populateVirtualMachineField(domainId, account, zoneId) {
}
$.ajax({
cache: false,
- data: createURL("command=listVirtualMachines&state=Stopped&zoneid="+zoneId+"&domainid="+domainId+"&account="+account+maxPageSize),
+ data: createURL("command=listVirtualMachines&state=Stopped&zoneid="+zoneId+"&domainid="+domainId+"&account="+account),
dataType: "json",
success: function(json) {
var instances = json.listvirtualmachinesresponse.virtualmachine;
diff --git a/ui/scripts/cloud.core.zone.js b/ui/scripts/cloud.core.zone.js
index 99eb1bee2a6..70f9bcb4ceb 100644
--- a/ui/scripts/cloud.core.zone.js
+++ b/ui/scripts/cloud.core.zone.js
@@ -374,7 +374,7 @@ function initAddVLANButton($button, $leftmenuItem1) {
dialogAddVlanForZone.find("#add_publicip_vlan_type_container").show();
var podSelect = dialogAddVlanForZone.find("#add_publicip_vlan_pod").empty();
$.ajax({
- data: createURL("command=listPods&zoneId="+zoneObj.id+maxPageSize),
+ data: createURL("command=listPods&zoneId="+zoneObj.id),
dataType: "json",
async: false,
success: function(json) {
@@ -395,7 +395,7 @@ function initAddVLANButton($button, $leftmenuItem1) {
function populateDomainDropdown(id) {
$.ajax({
- data: createURL("command=listDomainChildren&id="+id+"&pageSize=-1"),
+ data: createURL("command=listDomainChildren&id="+id),
dataType: "json",
async: false,
success: function(json) {
diff --git a/utils/src/com/cloud/utils/UriUtils.java b/utils/src/com/cloud/utils/UriUtils.java
index 61e6f263e36..0515a09ef26 100644
--- a/utils/src/com/cloud/utils/UriUtils.java
+++ b/utils/src/com/cloud/utils/UriUtils.java
@@ -20,6 +20,7 @@ package com.cloud.utils;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
+import java.net.URLEncoder;
import com.cloud.utils.exception.CloudRuntimeException;
@@ -51,4 +52,31 @@ public class UriUtils {
return file.toURI().toString();
}
+
+ // a simple URI component helper (Note: it does not deal with URI paramemeter area)
+ public static String encodeURIComponent(String url) {
+ int schemeTail = url.indexOf("://");
+
+ int pathStart = 0;
+ if(schemeTail > 0)
+ pathStart = url.indexOf('/', schemeTail + 3);
+ else
+ pathStart = url.indexOf('/');
+
+ if(pathStart > 0) {
+ String[] tokens = url.substring(pathStart + 1).split("/");
+ if(tokens != null) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(url.substring(0, pathStart));
+ for(String token : tokens) {
+ sb.append("/").append(URLEncoder.encode(token));
+ }
+
+ return sb.toString();
+ }
+ }
+
+ // no need to do URL component encoding
+ return url;
+ }
}
diff --git a/wscript_configure b/wscript_configure
index 31198361bbd..d941510c5f0 100644
--- a/wscript_configure
+++ b/wscript_configure
@@ -38,6 +38,8 @@ systemjars = {
'CentOS':
(
"tomcat6-servlet-2.5-api.jar",
+ "tomcat6-jsp-2.1-api-6.0.24.jar",
+ "tomcat6-el-1.0-api-6.0.24.jar",
#"tomcat6/catalina.jar", # all supported distros put the file there
),
'Ubuntu':