From 7e9b210d5cb78743ebc516fcbc5fd16711dcae00 Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Thu, 3 Nov 2011 07:18:23 -0700 Subject: [PATCH] bug 6745: Fix problems in Async create commands --- api/src/com/cloud/api/BaseAsyncCreateCmd.java | 5 +- .../com/cloud/api/commands/AddVpnUserCmd.java | 4 ++ .../api/commands/AssociateIPAddrCmd.java | 4 ++ .../api/commands/CreateFirewallRuleCmd.java | 4 ++ .../commands/CreateIpForwardingRuleCmd.java | 6 ++- .../commands/CreateLoadBalancerRuleCmd.java | 4 ++ .../commands/CreatePortForwardingRuleCmd.java | 4 ++ .../cloud/api/commands/CreateProjectCmd.java | 4 ++ .../commands/CreateRemoteAccessVpnCmd.java | 4 ++ .../cloud/api/commands/CreateSnapshotCmd.java | 4 ++ .../cloud/api/commands/CreateTemplateCmd.java | 4 ++ .../cloud/api/commands/CreateVolumeCmd.java | 4 ++ .../com/cloud/api/commands/DeployVMCmd.java | 4 ++ .../com/cloud/api/response/AlertResponse.java | 1 + .../cloud/api/response/AsyncJobResponse.java | 20 ++++---- .../com/cloud/api/response/BaseResponse.java | 7 +-- .../cloud/api/response/CreateCmdResponse.java | 19 ++++++-- .../com/cloud/api/response/HostResponse.java | 12 +++-- .../cloud/api/response/IPAddressResponse.java | 15 ++++-- .../api/response/SecurityGroupResponse.java | 16 ++++--- .../cloud/api/response/SnapshotResponse.java | 11 +++-- .../api/response/StoragePoolResponse.java | 14 ++++-- .../cloud/api/response/TemplateResponse.java | 9 ++-- .../cloud/api/response/UserVmResponse.java | 9 ++-- .../cloud/api/response/VolumeResponse.java | 9 ++-- server/src/com/cloud/api/ApiGsonHelper.java | 1 + .../com/cloud/api/ApiResponseGsonHelper.java | 1 + .../src/com/cloud/api/ApiResponseHelper.java | 4 ++ server/src/com/cloud/api/ApiServer.java | 12 ++++- .../com/cloud/api/IdentityTypeAdapter.java | 48 ++++++++++++------- .../com/cloud/api/SerializationContext.java | 27 +++++++++++ .../api/response/ApiResponseSerializer.java | 4 +- .../src/com/cloud/vm/dao/UserVmDaoImpl.java | 4 +- .../test/com/cloud/keystore/KeystoreTest.java | 42 +++++++++++++++- 34 files changed, 263 insertions(+), 77 deletions(-) create mode 100644 server/src/com/cloud/api/SerializationContext.java diff --git a/api/src/com/cloud/api/BaseAsyncCreateCmd.java b/api/src/com/cloud/api/BaseAsyncCreateCmd.java index 22aafcff01e..602dc19e0fa 100644 --- a/api/src/com/cloud/api/BaseAsyncCreateCmd.java +++ b/api/src/com/cloud/api/BaseAsyncCreateCmd.java @@ -34,11 +34,14 @@ public abstract class BaseAsyncCreateCmd extends BaseAsyncCmd { public void setEntityId(Long id) { this.id = id; } + + public abstract String getEntityTable(); - public String getResponse(long jobId, long objectId) { + public String getResponse(long jobId, long objectId, String objectEntityTable) { CreateCmdResponse response = new CreateCmdResponse(); response.setJobId(jobId); response.setId(objectId); + response.setIdEntityTable(objectEntityTable); response.setResponseName(getCommandName()); return _responseGenerator.toSerializedString(response, getResponseType()); } diff --git a/api/src/com/cloud/api/commands/AddVpnUserCmd.java b/api/src/com/cloud/api/commands/AddVpnUserCmd.java index c56ac17f101..c605b328af1 100644 --- a/api/src/com/cloud/api/commands/AddVpnUserCmd.java +++ b/api/src/com/cloud/api/commands/AddVpnUserCmd.java @@ -103,6 +103,10 @@ public class AddVpnUserCmd extends BaseAsyncCreateCmd { return accountId; } + + public String getEntityTable() { + return "vpn_users"; + } @Override public String getEventDescription() { diff --git a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java index cd63502e6e7..788f17fc3e6 100644 --- a/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java +++ b/api/src/com/cloud/api/commands/AssociateIPAddrCmd.java @@ -77,6 +77,10 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// + public String getEntityTable() { + return "user_ip_address"; + } + public String getAccountName() { if (accountName != null) { return accountName; diff --git a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java index 730af9cd397..22715f7c1b1 100644 --- a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java @@ -78,6 +78,10 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// + + public String getEntityTable() { + return "firewall_rules"; + } public Long getIpAddressId() { return ipAddressId; diff --git a/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java index ce705ead6f4..891ec736d86 100644 --- a/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java @@ -75,7 +75,11 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// - + + public String getEntityTable() { + return "firewall_rules"; + } + public Long getIpAddressId() { return ipAddressId; } diff --git a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java index c7e76771754..b7b9f6a665e 100644 --- a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java @@ -109,6 +109,10 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements return privatePort; } + public String getEntityTable() { + return "firewall_rules"; + } + public Long getPublicIpId() { IpAddress ipAddr = _networkService.getIp(publicIpId); if (ipAddr == null || !ipAddr.readyToUse()) { diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index 340f69e5872..cf696c3e2d4 100644 --- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -83,6 +83,10 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// + + public String getEntityTable() { + return "firewall_rules"; + } public Long getIpAddressId() { return ipAddressId; diff --git a/api/src/com/cloud/api/commands/CreateProjectCmd.java b/api/src/com/cloud/api/commands/CreateProjectCmd.java index 88aa089f95a..86133ad3c21 100644 --- a/api/src/com/cloud/api/commands/CreateProjectCmd.java +++ b/api/src/com/cloud/api/commands/CreateProjectCmd.java @@ -62,6 +62,10 @@ public class CreateProjectCmd extends BaseAsyncCreateCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// + public String getEntityTable() { + return "projects"; + } + public String getAccountName() { if (accountName != null) { return accountName; diff --git a/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java b/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java index 9622cb0f2dd..8eef6dcdb9d 100644 --- a/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java +++ b/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java @@ -67,6 +67,10 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd { ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "user_ip_address"; + } public Long getPublicIpId() { return publicIpId; diff --git a/api/src/com/cloud/api/commands/CreateSnapshotCmd.java b/api/src/com/cloud/api/commands/CreateSnapshotCmd.java index 64eaa84f3d8..d10ae4899be 100755 --- a/api/src/com/cloud/api/commands/CreateSnapshotCmd.java +++ b/api/src/com/cloud/api/commands/CreateSnapshotCmd.java @@ -63,6 +63,10 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// + + public String getEntityTable() { + return "snapshots"; + } public String getAccountName() { return accountName; diff --git a/api/src/com/cloud/api/commands/CreateTemplateCmd.java b/api/src/com/cloud/api/commands/CreateTemplateCmd.java index afe09ef4ebb..6559dbdf344 100755 --- a/api/src/com/cloud/api/commands/CreateTemplateCmd.java +++ b/api/src/com/cloud/api/commands/CreateTemplateCmd.java @@ -96,6 +96,10 @@ import com.cloud.user.UserContext; // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// + + public String getEntityTable() { + return "vm_template"; + } public Integer getBits() { return bits; diff --git a/api/src/com/cloud/api/commands/CreateVolumeCmd.java b/api/src/com/cloud/api/commands/CreateVolumeCmd.java index f2b07642ad4..5cac715ddd0 100644 --- a/api/src/com/cloud/api/commands/CreateVolumeCmd.java +++ b/api/src/com/cloud/api/commands/CreateVolumeCmd.java @@ -78,6 +78,10 @@ public class CreateVolumeCmd extends BaseAsyncCreateCmd { ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// + + public String getEntityTable() { + return "volumes"; + } public String getAccountName() { return accountName; diff --git a/api/src/com/cloud/api/commands/DeployVMCmd.java b/api/src/com/cloud/api/commands/DeployVMCmd.java index 3b6be389d06..0db3d930b0f 100644 --- a/api/src/com/cloud/api/commands/DeployVMCmd.java +++ b/api/src/com/cloud/api/commands/DeployVMCmd.java @@ -143,6 +143,10 @@ public class DeployVMCmd extends BaseAsyncCreateCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// + public String getEntityTable() { + return "vm_instance"; + } + public String getAccountName() { if (accountName == null) { return UserContext.current().getCaller().getAccountName(); diff --git a/api/src/com/cloud/api/response/AlertResponse.java b/api/src/com/cloud/api/response/AlertResponse.java index 9d3d1d809f2..a8f7b759d5c 100644 --- a/api/src/com/cloud/api/response/AlertResponse.java +++ b/api/src/com/cloud/api/response/AlertResponse.java @@ -18,6 +18,7 @@ package com.cloud.api.response; import java.util.Date; +import java.util.List; import com.cloud.api.ApiConstants; import com.cloud.api.IdentityProxy; diff --git a/api/src/com/cloud/api/response/AsyncJobResponse.java b/api/src/com/cloud/api/response/AsyncJobResponse.java index f4a99d4c2b5..bd397da1963 100644 --- a/api/src/com/cloud/api/response/AsyncJobResponse.java +++ b/api/src/com/cloud/api/response/AsyncJobResponse.java @@ -26,8 +26,10 @@ import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; public class AsyncJobResponse extends BaseResponse { +/* @SerializedName(ApiConstants.JOB_ID) @Param(description="async job ID") private IdentityProxy id = new IdentityProxy("async_job"); +*/ @SerializedName("accountid") @Param(description="the account that executed the async command") private IdentityProxy accountId = new IdentityProxy("account"); @@ -57,18 +59,17 @@ public class AsyncJobResponse extends BaseResponse { private String jobInstanceType; @SerializedName("jobinstanceid") @Param(description="the unique ID of the instance/entity object related to the job") - // private Long jobInstanceId; - IdentityProxy jobInstanceIdProxy = new IdentityProxy(); + private IdentityProxy jobInstanceId = new IdentityProxy(); @SerializedName(ApiConstants.CREATED) @Param(description=" the created date of the job") private Date created; public Long getId() { - return id.getValue(); + return getJobId(); } public void setId(Long id) { - this.id.setValue(id); + setJobId(id); } public Long getAccountId() { @@ -141,13 +142,14 @@ public class AsyncJobResponse extends BaseResponse { public void setJobInstanceType(String jobInstanceType) { this.jobInstanceType = jobInstanceType; + if(jobInstanceType != null) { if(jobInstanceType.equalsIgnoreCase("volume")) { - this.jobInstanceIdProxy.setTableName("volumes"); + this.jobInstanceId.setTableName("volumes"); } else if(jobInstanceType.equalsIgnoreCase("template")) { - this.jobInstanceIdProxy.setTableName("vm_template"); + this.jobInstanceId.setTableName("vm_template"); } else if(jobInstanceType.equalsIgnoreCase("iso")) { - this.jobInstanceIdProxy.setTableName("vm_template"); + this.jobInstanceId.setTableName("vm_template"); } else { // TODO : when we hit here, we need to add instanceType -> UUID entity table mapping assert(false); @@ -156,11 +158,11 @@ public class AsyncJobResponse extends BaseResponse { } public Long getJobInstanceId() { - return jobInstanceIdProxy.getValue(); + return this.jobInstanceId.getValue(); } public void setJobInstanceId(Long jobInstanceId) { - this.jobInstanceIdProxy.setValue(jobInstanceId); + this.jobInstanceId.setValue(jobInstanceId); } public Date getCreated() { diff --git a/api/src/com/cloud/api/response/BaseResponse.java b/api/src/com/cloud/api/response/BaseResponse.java index b0e60b1a67f..94908f0330e 100755 --- a/api/src/com/cloud/api/response/BaseResponse.java +++ b/api/src/com/cloud/api/response/BaseResponse.java @@ -19,6 +19,7 @@ package com.cloud.api.response; import com.cloud.api.ApiConstants; +import com.cloud.api.IdentityProxy; import com.cloud.api.ResponseObject; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; @@ -53,17 +54,17 @@ public abstract class BaseResponse implements ResponseObject { // 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; + protected IdentityProxy jobId = new IdentityProxy("async_job"); @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; + return jobId.getValue(); } public void setJobId(Long jobId) { - this.jobId = jobId; + this.jobId.setValue(jobId); } public Integer getJobStatus() { diff --git a/api/src/com/cloud/api/response/CreateCmdResponse.java b/api/src/com/cloud/api/response/CreateCmdResponse.java index 88ce4753aab..82e0c23071e 100644 --- a/api/src/com/cloud/api/response/CreateCmdResponse.java +++ b/api/src/com/cloud/api/response/CreateCmdResponse.java @@ -19,28 +19,37 @@ package com.cloud.api.response; import com.cloud.api.ApiConstants; +import com.cloud.api.IdentityProxy; import com.google.gson.annotations.SerializedName; public class CreateCmdResponse extends BaseResponse { +/* @SerializedName(ApiConstants.JOB_ID) private Long jobId; +*/ @SerializedName(ApiConstants.ID) - private Long id; + private IdentityProxy id = new IdentityProxy(); +/* public Long getJobId() { - return jobId; + return super.getJobId(); } public void setJobId(Long jobId) { - this.jobId = jobId; + super.setJobId(jobId); } +*/ public Long getId() { - return id; + return id.getValue(); } public void setId(Long id) { - this.id = id; + this.id.setValue(id); + } + + public void setIdEntityTable(String entityTable) { + this.id.setTableName(entityTable); } } diff --git a/api/src/com/cloud/api/response/HostResponse.java b/api/src/com/cloud/api/response/HostResponse.java index 32633ba76ad..ed6c88cceaa 100755 --- a/api/src/com/cloud/api/response/HostResponse.java +++ b/api/src/com/cloud/api/response/HostResponse.java @@ -139,12 +139,14 @@ public class HostResponse extends BaseResponse { @SerializedName("events") @Param(description="events available for the host") private String events; +/* @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the host") private IdentityProxy jobId = new IdentityProxy("async_job"); + @SerializedName("jobstatus") @Param(description="shows the current pending asynchronous job status") private Integer jobStatus; - +*/ @SerializedName("hosttags") @Param(description="comma-separated list of tags for the host") private String hostTags; @@ -165,15 +167,16 @@ public class HostResponse extends BaseResponse { public Long getObjectId() { return getId(); } - + +/* @Override public Long getJobId() { - return jobId.getValue(); + return super.getJobId(); } @Override public void setJobId(Long jobId) { - this.jobId.setValue(jobId); + super.setJobId(jobId); } @Override @@ -185,6 +188,7 @@ public class HostResponse extends BaseResponse { public void setJobStatus(Integer jobStatus) { this.jobStatus = jobStatus; } +*/ public Long getId() { return id.getValue(); diff --git a/api/src/com/cloud/api/response/IPAddressResponse.java b/api/src/com/cloud/api/response/IPAddressResponse.java index 4b0d4b7da40..736fcdb5d8e 100644 --- a/api/src/com/cloud/api/response/IPAddressResponse.java +++ b/api/src/com/cloud/api/response/IPAddressResponse.java @@ -88,12 +88,16 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR @SerializedName(ApiConstants.STATE) @Param(description="State of the ip address. Can be: Allocatin, Allocated and Releasing") private String state; - + +/* @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume") private IdentityProxy jobId = new IdentityProxy("async_job"); +*/ +/* @SerializedName(ApiConstants.JOB_STATUS) @Param(description="shows the current pending asynchronous job status") private Integer jobStatus; +*/ public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; @@ -182,15 +186,16 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR public Long getObjectId() { return getId(); } - + +/* @Override public Long getJobId() { - return jobId.getValue(); + return super.getJobId(); } @Override public void setJobId(Long jobId) { - this.jobId.setValue(jobId); + super.setJobId(jobId); } @Override @@ -202,7 +207,7 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR public void setJobStatus(Integer jobStatus) { this.jobStatus = jobStatus; } - +*/ @Override public void setProjectId(Long projectId) { this.projectId.setValue(projectId); diff --git a/api/src/com/cloud/api/response/SecurityGroupResponse.java b/api/src/com/cloud/api/response/SecurityGroupResponse.java index 6ecfa2a2729..02d17d2c9c3 100644 --- a/api/src/com/cloud/api/response/SecurityGroupResponse.java +++ b/api/src/com/cloud/api/response/SecurityGroupResponse.java @@ -49,13 +49,15 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt @SerializedName(ApiConstants.DOMAIN) @Param(description="the domain name of the security group") private String domainName; - + +/* @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume") private IdentityProxy jobId = new IdentityProxy("async_job"); @SerializedName(ApiConstants.JOB_STATUS) @Param(description="shows the current pending asynchronous job status") private Integer jobStatus; - +*/ + @SerializedName("ingressrule") @Param(description="the list of ingress rules associated with the security group", responseObject = IngressRuleResponse.class) private List ingressRules; @@ -102,17 +104,18 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt public Long getObjectId() { return getId(); } - + +/* @Override public Long getJobId() { - return jobId.getValue(); + return super.getJobId(); } @Override public void setJobId(Long jobId) { - this.jobId.setValue(jobId); + super.setJobId(jobId); } - + @Override public Integer getJobStatus() { return jobStatus; @@ -122,6 +125,7 @@ public class SecurityGroupResponse extends BaseResponse implements ControlledEnt public void setJobStatus(Integer jobStatus) { this.jobStatus = jobStatus; } +*/ @Override public int hashCode() { diff --git a/api/src/com/cloud/api/response/SnapshotResponse.java b/api/src/com/cloud/api/response/SnapshotResponse.java index 028816c2e29..373e05781ef 100644 --- a/api/src/com/cloud/api/response/SnapshotResponse.java +++ b/api/src/com/cloud/api/response/SnapshotResponse.java @@ -73,14 +73,15 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe @Param(description = "name of the snapshot") private String name; +/* @SerializedName(ApiConstants.JOB_ID) @Param(description = "the job ID associated with the snapshot. This is only displayed if the snapshot listed is part of a currently running asynchronous job.") private IdentityProxy jobId = new IdentityProxy("async_job"); - + @SerializedName(ApiConstants.JOB_STATUS) @Param(description = "the job status associated with the snapshot. This is only displayed if the snapshot listed is part of a currently running asynchronous job.") private Integer jobStatus; - +*/ @SerializedName(ApiConstants.INTERVAL_TYPE) @Param(description = "valid types are hourly, daily, weekly, monthy, template, and none.") private String intervalType; @@ -146,14 +147,15 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe this.name = name; } +/* @Override public Long getJobId() { - return jobId.getValue(); + return super.getJobId(); } @Override public void setJobId(Long jobId) { - this.jobId.setValue(jobId); + super.setJobId(jobId); } @Override @@ -165,6 +167,7 @@ public class SnapshotResponse extends BaseResponse implements ControlledEntityRe public void setJobStatus(Integer jobStatus) { this.jobStatus = jobStatus; } +*/ public void setIntervalType(String intervalType) { this.intervalType = intervalType; diff --git a/api/src/com/cloud/api/response/StoragePoolResponse.java b/api/src/com/cloud/api/response/StoragePoolResponse.java index 157635f239c..6eb4935687a 100755 --- a/api/src/com/cloud/api/response/StoragePoolResponse.java +++ b/api/src/com/cloud/api/response/StoragePoolResponse.java @@ -76,26 +76,29 @@ public class StoragePoolResponse extends BaseResponse { @SerializedName(ApiConstants.STATE) @Param(description="the state of the storage pool") private StoragePoolStatus state; - + +/* @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the storage pool") private IdentityProxy jobId = new IdentityProxy("async_job"); + @SerializedName("jobstatus") @Param(description="shows the current pending asynchronous job status") private Integer jobStatus; - +*/ @Override public Long getObjectId() { return getId(); } - + +/* @Override public Long getJobId() { - return jobId.getValue(); + return super.getJobId(); } @Override public void setJobId(Long jobId) { - this.jobId.setValue(jobId); + super.setJobId(jobId); } @Override @@ -107,6 +110,7 @@ public class StoragePoolResponse extends BaseResponse { public void setJobStatus(Integer jobStatus) { this.jobStatus = jobStatus; } +*/ public Long getId() { return id.getValue(); diff --git a/api/src/com/cloud/api/response/TemplateResponse.java b/api/src/com/cloud/api/response/TemplateResponse.java index 3a35fd6d62c..f2c194be7bd 100755 --- a/api/src/com/cloud/api/response/TemplateResponse.java +++ b/api/src/com/cloud/api/response/TemplateResponse.java @@ -95,11 +95,13 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe @SerializedName(ApiConstants.HYPERVISOR) @Param(description="the hypervisor on which the template runs") private String hypervisor; +/* @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the template") private IdentityProxy jobId = new IdentityProxy("async_job"); @SerializedName(ApiConstants.JOB_STATUS) @Param(description="shows the current pending asynchronous job status") private Integer jobStatus; +*/ @SerializedName(ApiConstants.DOMAIN) @Param(description="the name of the domain to which the template belongs") private String domainName; @@ -227,13 +229,13 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe public void setHypervisor(String hypervisor) { this.hypervisor = hypervisor; } - +/* public Long getJobId() { - return jobId.getValue(); + return super.getJobId(); } public void setJobId(Long jobId) { - this.jobId.setValue(jobId); + super.setJobId(jobId); } public Integer getJobStatus() { @@ -243,6 +245,7 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe public void setJobStatus(Integer jobStatus) { this.jobStatus = jobStatus; } +*/ @Override public void setDomainName(String domainName) { diff --git a/api/src/com/cloud/api/response/UserVmResponse.java b/api/src/com/cloud/api/response/UserVmResponse.java index 99bfaf0c82e..66c355fbf47 100755 --- a/api/src/com/cloud/api/response/UserVmResponse.java +++ b/api/src/com/cloud/api/response/UserVmResponse.java @@ -144,12 +144,14 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp @SerializedName(ApiConstants.PASSWORD) @Param(description="the password (if exists) of the virtual machine") private String password; +/* @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the virtual machine") private IdentityProxy jobId = new IdentityProxy("async_job"); + @SerializedName("jobstatus") @Param(description="shows the current pending asynchronous job status") private Integer jobStatus; - +*/ @SerializedName("nic") @Param(description="the list of nics associated with vm", responseObject = NicResponse.class) private List nics; @@ -305,14 +307,15 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp this.password = password; } +/* public void setJobId(Long jobId) { - this.jobId.setValue(jobId); + super.setJobId(jobId); } public void setJobStatus(Integer jobStatus) { this.jobStatus = jobStatus; } - +*/ public void setForVirtualNetwork(Boolean forVirtualNetwork) { this.forVirtualNetwork = forVirtualNetwork; } diff --git a/api/src/com/cloud/api/response/VolumeResponse.java b/api/src/com/cloud/api/response/VolumeResponse.java index 74a68d6612d..af19e346a89 100755 --- a/api/src/com/cloud/api/response/VolumeResponse.java +++ b/api/src/com/cloud/api/response/VolumeResponse.java @@ -30,6 +30,7 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp @Param(description = "ID of the disk volume") private IdentityProxy id = new IdentityProxy("volumes"); +/* @SerializedName(ApiConstants.JOB_ID) @Param(description = "shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume") private IdentityProxy jobId = new IdentityProxy("async_job"); @@ -37,6 +38,7 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp @SerializedName(ApiConstants.JOB_STATUS) @Param(description = "shows the current pending asynchronous job status") private Integer jobStatus; +*/ @SerializedName(ApiConstants.NAME) @Param(description = "name of the disk volume") @@ -161,14 +163,15 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp return getId(); } +/* @Override public Long getJobId() { - return jobId.getValue(); + return super.getJobId(); } @Override public void setJobId(Long jobId) { - this.jobId.setValue(jobId); + super.setJobId(jobId); } @Override @@ -180,7 +183,7 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp public void setJobStatus(Integer jobStatus) { this.jobStatus = jobStatus; } - +*/ public Boolean getDestroyed() { return destroyed; } diff --git a/server/src/com/cloud/api/ApiGsonHelper.java b/server/src/com/cloud/api/ApiGsonHelper.java index 9fa41851a73..a52dcfcbe39 100644 --- a/server/src/com/cloud/api/ApiGsonHelper.java +++ b/server/src/com/cloud/api/ApiGsonHelper.java @@ -26,6 +26,7 @@ public class ApiGsonHelper { s_gBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); s_gBuilder.setVersion(1.3); s_gBuilder.registerTypeAdapter(ResponseObject.class, new ResponseObjectTypeAdapter()); + s_gBuilder.registerTypeAdapter(IdentityProxy.class, new IdentityTypeAdapter()); } public static GsonBuilder getBuilder() { diff --git a/server/src/com/cloud/api/ApiResponseGsonHelper.java b/server/src/com/cloud/api/ApiResponseGsonHelper.java index bc70888d6c4..10c3a762fed 100644 --- a/server/src/com/cloud/api/ApiResponseGsonHelper.java +++ b/server/src/com/cloud/api/ApiResponseGsonHelper.java @@ -28,6 +28,7 @@ import com.google.gson.GsonBuilder; public class ApiResponseGsonHelper { private static final GsonBuilder s_gBuilder; + static { s_gBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); s_gBuilder.setVersion(1.3); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index f23ce2d963f..2beac5526e6 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -2159,7 +2159,11 @@ public class ApiResponseHelper implements ResponseGenerator { response.setJobStatus(result.getJobStatus()); response.setJobProcStatus(result.getProcessStatus()); response.setJobResultCode(result.getResultCode()); + + boolean savedValue = SerializationContext.current().getUuidTranslation(); + SerializationContext.current().setUuidTranslation(false); response.setJobResult((ResponseObject) ApiSerializerHelper.fromSerializedString(result.getResult())); + SerializationContext.current().setUuidTranslation(savedValue); Object resultObject = result.getResultObject(); if (resultObject != null) { diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index ea2e7990497..841da430648 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -393,10 +393,12 @@ public class ApiServer implements HttpRequestHandler { Account caller = ctx.getCaller(); if (cmdObj instanceof BaseAsyncCmd) { Long objectId = null; + String objectEntityTable = null; if (cmdObj instanceof BaseAsyncCreateCmd) { BaseAsyncCreateCmd createCmd = (BaseAsyncCreateCmd) cmdObj; _dispatcher.dispatchCreateCmd(createCmd, params); objectId = createCmd.getEntityId(); + objectEntityTable = createCmd.getEntityTable(); params.put("id", objectId.toString()); } else { ApiDispatcher.setupParameters(cmdObj, params); @@ -444,8 +446,10 @@ public class ApiServer implements HttpRequestHandler { } if (objectId != null) { - return ((BaseAsyncCreateCmd) asyncCmd).getResponse(jobId, objectId); + return ((BaseAsyncCreateCmd) asyncCmd).getResponse(jobId, objectId, objectEntityTable); } + + SerializationContext.current().setUuidTranslation(true); return ApiResponseSerializer.toSerializedString(asyncCmd.getResponse(jobId), asyncCmd.getResponseType()); } else { _dispatcher.dispatch(cmdObj, params); @@ -455,7 +459,9 @@ public class ApiServer implements HttpRequestHandler { if (cmdObj instanceof BaseListCmd) { buildAsyncListResponse((BaseListCmd) cmdObj, caller); } - return ApiResponseSerializer.toSerializedString((ResponseObject) cmdObj.getResponseObject(), cmdObj.getResponseType()); + + SerializationContext.current().setUuidTranslation(true); + return ApiResponseSerializer.toSerializedString((ResponseObject) cmdObj.getResponseObject(), cmdObj.getResponseType()); } } @@ -925,6 +931,8 @@ public class ApiServer implements HttpRequestHandler { apiResponse.setErrorCode(errorCode); apiResponse.setErrorText(errorText); apiResponse.setResponseName(responseName); + + SerializationContext.current().setUuidTranslation(true); responseText = ApiResponseSerializer.toSerializedString(apiResponse, responseType); } catch (Exception e) { diff --git a/server/src/com/cloud/api/IdentityTypeAdapter.java b/server/src/com/cloud/api/IdentityTypeAdapter.java index 471dd94ec64..611863b1d9b 100644 --- a/server/src/com/cloud/api/IdentityTypeAdapter.java +++ b/server/src/com/cloud/api/IdentityTypeAdapter.java @@ -21,37 +21,49 @@ import java.lang.reflect.Type; import com.cloud.Identity.dao.IdentityDao; import com.cloud.Identity.dao.IdentityDaoImpl; +import com.google.gson.Gson; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; public class IdentityTypeAdapter implements JsonSerializer, JsonDeserializer { + @Override public JsonElement serialize(IdentityProxy src, Type srcType, JsonSerializationContext context) { - assert(src != null); - assert(src.getTableName() != null); - - if(src.getValue() == null) - return null; - - IdentityDao identityDao = new IdentityDaoImpl(); - if(src.getValue() == null) - return context.serialize(null); - - return new JsonPrimitive(identityDao.getIdentityUuid(src.getTableName(), String.valueOf(src.getValue()))); + if(SerializationContext.current().getUuidTranslation()) { + assert(src != null); + if(src.getValue() == null) + return context.serialize(null); + + IdentityDao identityDao = new IdentityDaoImpl(); + if(src.getTableName() != null) { + String uuid = identityDao.getIdentityUuid(src.getTableName(), String.valueOf(src.getValue())); + if(uuid == null) + return context.serialize(null); + + return new JsonPrimitive(uuid); + } else { + return new JsonPrimitive(String.valueOf(src.getValue())); + } + } else { + return new Gson().toJsonTree(src); + } } @Override - public IdentityProxy deserialize(JsonElement json, Type type, - JsonDeserializationContext context) throws JsonParseException { - - // this is a place holder implementation to guard our assumption - IdentityProxy is only used - // on one-direction - assert(false); - return null; + public IdentityProxy deserialize(JsonElement src, Type srcType, + JsonDeserializationContext context) throws JsonParseException { + + IdentityProxy obj = new IdentityProxy(); + JsonObject json = src.getAsJsonObject(); + obj.setTableName(json.get("_tableName").getAsString()); + if(json.get("_value") != null) + obj.setValue(json.get("_value").getAsLong()); + return obj; } } diff --git a/server/src/com/cloud/api/SerializationContext.java b/server/src/com/cloud/api/SerializationContext.java new file mode 100644 index 00000000000..8d5a2ca963c --- /dev/null +++ b/server/src/com/cloud/api/SerializationContext.java @@ -0,0 +1,27 @@ +package com.cloud.api; + +public class SerializationContext { + private static ThreadLocal s_currentContext = new ThreadLocal(); + + private boolean _doUuidTranslation = false; + + public SerializationContext() { + } + + public static SerializationContext current() { + SerializationContext context = s_currentContext.get(); + if(context == null) { + context = new SerializationContext(); + s_currentContext.set(context); + } + return context; + } + + public boolean getUuidTranslation() { + return _doUuidTranslation; + } + + public void setUuidTranslation(boolean value) { + _doUuidTranslation = value; + } +} diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java index d48f71e242e..67188fab457 100644 --- a/server/src/com/cloud/api/response/ApiResponseSerializer.java +++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java @@ -35,6 +35,7 @@ import com.cloud.api.ApiResponseGsonHelper; import com.cloud.api.ApiServer; import com.cloud.api.BaseCmd; import com.cloud.api.ResponseObject; +import com.cloud.api.ResponseObjectTypeAdapter; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.utils.component.ComponentLocator; @@ -65,9 +66,10 @@ public class ApiResponseSerializer { return str; } - private static String toJSONSerializedString(ResponseObject result) { + public static String toJSONSerializedString(ResponseObject result) { if (result != null) { Gson gson = ApiResponseGsonHelper.getBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).create(); + StringBuilder sb = new StringBuilder(); sb.append("{ \"" + result.getResponseName() + "\" : "); diff --git a/server/src/com/cloud/vm/dao/UserVmDaoImpl.java b/server/src/com/cloud/vm/dao/UserVmDaoImpl.java index 98479ecb4c6..90b6c45c7ec 100755 --- a/server/src/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/server/src/com/cloud/vm/dao/UserVmDaoImpl.java @@ -75,7 +75,7 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use "GROUP BY pod_id HAVING count(id) > 0 ORDER BY count(id) DESC"; private static final int VM_DETAILS_BATCH_SIZE=100; - + protected final UserVmDetailsDaoImpl _detailsDao = ComponentLocator.inject(UserVmDetailsDaoImpl.class); protected final NicDaoImpl _nicDao = ComponentLocator.inject(NicDaoImpl.class); @@ -393,8 +393,6 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use if (!userVmData.isInitialized()){ - userVmData.setUuid(rs.getString("vm_instance.uuid")); - //account.account_name, account.type, domain.name, instance_group.id, instance_group.name," userVmData.setAccountId(rs.getLong("account.id")); userVmData.setAccountName(rs.getString("account.account_name")); diff --git a/server/test/com/cloud/keystore/KeystoreTest.java b/server/test/com/cloud/keystore/KeystoreTest.java index d33bd906459..6a09d301847 100644 --- a/server/test/com/cloud/keystore/KeystoreTest.java +++ b/server/test/com/cloud/keystore/KeystoreTest.java @@ -18,6 +18,7 @@ package com.cloud.keystore; import java.security.KeyStore; +import java.util.Date; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -28,6 +29,11 @@ import org.apache.log4j.Logger; import org.junit.After; import org.junit.Before; +import com.cloud.api.ApiResponseHelper; +import com.cloud.api.ApiSerializerHelper; +import com.cloud.api.response.AlertResponse; +import com.cloud.api.response.ApiResponseSerializer; +import com.cloud.api.response.UserVmResponse; import com.cloud.configuration.DefaultInterceptorLibrary; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.component.MockComponentLocator; @@ -84,17 +90,20 @@ public class KeystoreTest extends TestCase { @Override @Before public void setUp() { +/* MockComponentLocator locator = new MockComponentLocator("management-server"); locator.addDao("keystoreDao", KeystoreDaoImpl.class); locator.addManager("KeystoreManager", KeystoreManagerImpl.class); locator.makeActive(new DefaultInterceptorLibrary()); +*/ } @Override @After public void tearDown() throws Exception { } - + +/* public void testKeystoreSave() throws Exception { KeystoreVO ksVo; @@ -154,4 +163,35 @@ public class KeystoreTest extends TestCase { KeystoreVO ksVo = ksDao.findByName("CPVMCertificate"); ksDao.expunge(ksVo.getId()); } +*/ + public void testUuid() { + UserVmResponse vm = new UserVmResponse(); + vm.setId(3L); +/* + vm.setAccountName("admin"); + vm.setName("i-2-3-KY"); + vm.setDisplayName("i-2-3-KY"); + vm.setDomainId(1L); + vm.setDomainName("ROOT"); + vm.setCreated(new Date()); + vm.setState("Running"); + vm.setZoneId(1L); + vm.setZoneName("KY"); + vm.setHostId(1L); + + vm.setObjectName("virtualmachine"); +*/ + String result = ApiSerializerHelper.toSerializedStringOld(vm); + // String result = "com.cloud.api.response.UserVmResponse/virtualmachine/{\"id\":{\"_tableName\":\"vm_instance\",\"_value\":3},\"name\":\"i-2-3-KY\",\"displayname\":\"i-2-3-KY\",\"account\":\"admin\",\"projectid\":{\"_tableName\":\"projects\"},\"domainid\":{\"_tableName\":\"domain\",\"_value\":1},\"domain\":\"ROOT\",\"created\":\"2011-11-02T21:54:07-0700\",\"state\":\"Running\",\"haenable\":false,\"groupid\":{\"_tableName\":\"instance_group\"},\"zoneid\":{\"_tableName\":\"data_center\",\"_value\":1},\"zonename\":\"KY\",\"hostid\":{\"_tableName\":\"host\",\"_value\":1},\"hostname\":\"xenserver-basic\",\"templateid\":{\"_tableName\":\"vm_template\",\"_value\":2},\"templatename\":\"CentOS 5.3(64-bit) no GUI (XenServer)\",\"templatedisplaytext\":\"CentOS 5.3(64-bit) no GUI (XenServer)\",\"passwordenabled\":false,\"isoid\":{\"_tableName\":\"vm_template\"},\"serviceofferingid\":{\"_tableName\":\"disk_offering\",\"_value\":7},\"serviceofferingname\":\"Small Instance\",\"cpunumber\":1,\"cpuspeed\":500,\"memory\":512,\"guestosid\":{\"_tableName\":\"guest_os\",\"_value\":12},\"rootdeviceid\":0,\"rootdevicetype\":\"NetworkFilesystem\",\"securitygroup\":[],\"jobid\":{\"_tableName\":\"async_job\"},\"nic\":[{\"id\":7,\"networkid\":200,\"netmask\":\"255.255.255.0\",\"gateway\":\"10.1.1.1\",\"ipaddress\":\"10.1.1.116\",\"isolationuri\":\"vlan://1699\",\"broadcasturi\":\"vlan://1699\",\"traffictype\":\"Guest\",\"type\":\"Virtual\",\"isdefault\":true,\"macaddress\":\"02:00:39:a7:00:01\"}],\"hypervisor\":\"XenServer\"}"; + System.out.println(result); + //Object obj = ApiSerializerHelper.fromSerializedString(result); + + AlertResponse alert = new AlertResponse(); + alert.setId(100L); + alert.setDescription("Hello"); + + result = ApiSerializerHelper.toSerializedStringOld(alert); + System.out.println(result); + ApiSerializerHelper.fromSerializedString(result); + } }