You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2021/02/13 10:08:17 UTC

[cloudstack] branch master updated: add creation date as a value for domains and accounts. (#4649)

This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new 543f982  add creation date as a value for domains and accounts. (#4649)
543f982 is described below

commit 543f9827ff83e1b8f433d98fbe4d5518387b440d
Author: Sina Kashipazha <so...@users.noreply.github.com>
AuthorDate: Sat Feb 13 11:07:53 2021 +0100

    add creation date as a value for domains and accounts. (#4649)
---
 api/src/main/java/com/cloud/domain/Domain.java     |   2 +
 api/src/main/java/com/cloud/user/Account.java      |   2 +
 .../cloudstack/api/response/AccountResponse.java   |   9 +
 .../cloudstack/api/response/DomainResponse.java    |   8 +
 .../src/main/java/com/cloud/domain/DomainVO.java   |   8 +
 .../src/main/java/com/cloud/user/AccountVO.java    |   8 +
 .../resources/META-INF/db/schema-41510to41600.sql  | 282 +++++++++++++++++++++
 .../main/java/com/cloud/api/ApiResponseHelper.java |   1 +
 .../cloud/api/query/dao/AccountJoinDaoImpl.java    |   1 +
 .../com/cloud/api/query/dao/DomainJoinDaoImpl.java |   1 +
 .../java/com/cloud/api/query/vo/AccountJoinVO.java |   7 +
 .../java/com/cloud/api/query/vo/DomainJoinVO.java  |   7 +
 12 files changed, 336 insertions(+)

diff --git a/api/src/main/java/com/cloud/domain/Domain.java b/api/src/main/java/com/cloud/domain/Domain.java
index 365a705..7441507 100644
--- a/api/src/main/java/com/cloud/domain/Domain.java
+++ b/api/src/main/java/com/cloud/domain/Domain.java
@@ -42,6 +42,8 @@ public interface Domain extends OwnedBy, Identity, InternalIdentity {
 
     void setName(String name);
 
+    Date getCreated();
+
     Date getRemoved();
 
     String getPath();
diff --git a/api/src/main/java/com/cloud/user/Account.java b/api/src/main/java/com/cloud/user/Account.java
index 58cedcd..39e91fa 100644
--- a/api/src/main/java/com/cloud/user/Account.java
+++ b/api/src/main/java/com/cloud/user/Account.java
@@ -50,6 +50,8 @@ public interface Account extends ControlledEntity, InternalIdentity, Identity {
 
     public State getState();
 
+    public Date getCreated();
+
     public Date getRemoved();
 
     public String getNetworkDomain();
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/AccountResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/AccountResponse.java
index d22ee52..5cd2fd3 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/AccountResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/AccountResponse.java
@@ -16,6 +16,7 @@
 // under the License.
 package org.apache.cloudstack.api.response;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -238,6 +239,10 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
     @Param(description = "true if the account requires cleanup")
     private Boolean cleanupRequired;
 
+    @SerializedName(ApiConstants.CREATED)
+    @Param(description="the date when this account was created")
+    private Date created;
+
     @SerializedName("user")
     @Param(description = "the list of users associated with account", responseObject = UserResponse.class)
     private List<UserResponse> users;
@@ -398,6 +403,10 @@ public class AccountResponse extends BaseResponse implements ResourceLimitAndCou
         this.state = state;
     }
 
+    public void setCreated(Date created) {
+        this.created = created;
+    }
+
     public void setCleanupRequired(Boolean cleanupRequired) {
         this.cleanupRequired = cleanupRequired;
     }
diff --git a/api/src/main/java/org/apache/cloudstack/api/response/DomainResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/DomainResponse.java
index 7e5bd97..818822b 100644
--- a/api/src/main/java/org/apache/cloudstack/api/response/DomainResponse.java
+++ b/api/src/main/java/org/apache/cloudstack/api/response/DomainResponse.java
@@ -25,6 +25,8 @@ import org.apache.cloudstack.api.EntityReference;
 import com.cloud.domain.Domain;
 import com.cloud.serializer.Param;
 
+import java.util.Date;
+
 @EntityReference(value = Domain.class)
 public class DomainResponse extends BaseResponse implements ResourceLimitAndCountResponse {
     @SerializedName(ApiConstants.ID)
@@ -62,6 +64,9 @@ public class DomainResponse extends BaseResponse implements ResourceLimitAndCoun
     @SerializedName(ApiConstants.STATE) @Param(description="the state of the domain")
     private String state;
 
+    @SerializedName(ApiConstants.CREATED) @Param(description="the date when this domain was created")
+    private Date created;
+
     @SerializedName(ApiConstants.VM_LIMIT) @Param(description="the total number of virtual machines that can be deployed by this domain")
     private String vmLimit;
 
@@ -230,6 +235,9 @@ public class DomainResponse extends BaseResponse implements ResourceLimitAndCoun
         this.path = path;
     }
 
+    public void setCreated(Date created) {
+        this.created = created;
+    }
 
     @Override
     public void setVmLimit(String vmLimit) {
diff --git a/engine/schema/src/main/java/com/cloud/domain/DomainVO.java b/engine/schema/src/main/java/com/cloud/domain/DomainVO.java
index 34376c7..05cd4cc 100644
--- a/engine/schema/src/main/java/com/cloud/domain/DomainVO.java
+++ b/engine/schema/src/main/java/com/cloud/domain/DomainVO.java
@@ -55,6 +55,9 @@ public class DomainVO implements Domain {
     @Column(name = "level")
     private int level;
 
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
     @Column(name = GenericDao.REMOVED_COLUMN)
     private Date removed;
 
@@ -144,6 +147,11 @@ public class DomainVO implements Domain {
     }
 
     @Override
+    public Date getCreated() {
+        return created;
+    }
+
+    @Override
     public Date getRemoved() {
         return removed;
     }
diff --git a/engine/schema/src/main/java/com/cloud/user/AccountVO.java b/engine/schema/src/main/java/com/cloud/user/AccountVO.java
index a504d2f..9834989 100644
--- a/engine/schema/src/main/java/com/cloud/user/AccountVO.java
+++ b/engine/schema/src/main/java/com/cloud/user/AccountVO.java
@@ -54,6 +54,9 @@ public class AccountVO implements Account {
     @Enumerated(value = EnumType.STRING)
     private State state;
 
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
     @Column(name = GenericDao.REMOVED_COLUMN)
     private Date removed;
 
@@ -169,6 +172,11 @@ public class AccountVO implements Account {
     }
 
     @Override
+    public Date getCreated() {
+        return created;
+    }
+
+    @Override
     public Date getRemoved() {
         return removed;
     }
diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql b/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql
index 0588c6d..7168f88 100644
--- a/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql
+++ b/engine/schema/src/main/resources/META-INF/db/schema-41510to41600.sql
@@ -19,3 +19,285 @@
 -- Schema upgrade from 4.15.1.0 to 4.16.0.0
 --;
 
+
+--;
+-- Stored procedure to do idempotent column add;
+-- This is copied from schema-41000to41100.sql
+--;
+DROP PROCEDURE IF EXISTS `cloud`.`IDEMPOTENT_ADD_COLUMN`;
+
+CREATE PROCEDURE `cloud`.`IDEMPOTENT_ADD_COLUMN` (
+    IN in_table_name VARCHAR(200),
+    IN in_column_name VARCHAR(200),
+    IN in_column_definition VARCHAR(1000)
+)
+BEGIN
+
+    DECLARE CONTINUE HANDLER FOR 1060 BEGIN END; SET @ddl = CONCAT('ALTER TABLE ', in_table_name); SET @ddl = CONCAT(@ddl, ' ', 'ADD COLUMN') ; SET @ddl = CONCAT(@ddl, ' ', in_column_name); SET @ddl = CONCAT(@ddl, ' ', in_column_definition); PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt; END;
+
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.account','created', 'datetime DEFAULT NULL COMMENT ''date created'' AFTER `state` ');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.domain','created', 'datetime DEFAULT NULL COMMENT ''date created'' AFTER `next_child_seq` ');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud_usage.account','created', 'datetime DEFAULT NULL COMMENT ''date created'' AFTER `state` ');
+
+DROP VIEW IF EXISTS `cloud`.`account_view`;
+CREATE VIEW `cloud`.`account_view` AS
+select
+    `account`.`id` AS `id`,
+    `account`.`uuid` AS `uuid`,
+    `account`.`account_name` AS `account_name`,
+    `account`.`type` AS `type`,
+    `account`.`role_id` AS `role_id`,
+    `account`.`state` AS `state`,
+    `account`.`created` AS `created`,
+    `account`.`removed` AS `removed`,
+    `account`.`cleanup_needed` AS `cleanup_needed`,
+    `account`.`network_domain` AS `network_domain` ,
+    `account`.`default` AS `default`,
+    `domain`.`id` AS `domain_id`,
+    `domain`.`uuid` AS `domain_uuid`,
+    `domain`.`name` AS `domain_name`,
+    `domain`.`path` AS `domain_path`,
+    `data_center`.`id` AS `data_center_id`,
+    `data_center`.`uuid` AS `data_center_uuid`,
+    `data_center`.`name` AS `data_center_name`,
+    `account_netstats_view`.`bytesReceived` AS `bytesReceived`,
+    `account_netstats_view`.`bytesSent` AS `bytesSent`,
+    `vmlimit`.`max` AS `vmLimit`,
+    `vmcount`.`count` AS `vmTotal`,
+    `runningvm`.`vmcount` AS `runningVms`,
+    `stoppedvm`.`vmcount` AS `stoppedVms`,
+    `iplimit`.`max` AS `ipLimit`,
+    `ipcount`.`count` AS `ipTotal`,
+    `free_ip_view`.`free_ip` AS `ipFree`,
+    `volumelimit`.`max` AS `volumeLimit`,
+    `volumecount`.`count` AS `volumeTotal`,
+    `snapshotlimit`.`max` AS `snapshotLimit`,
+    `snapshotcount`.`count` AS `snapshotTotal`,
+    `templatelimit`.`max` AS `templateLimit`,
+    `templatecount`.`count` AS `templateTotal`,
+    `vpclimit`.`max` AS `vpcLimit`,
+    `vpccount`.`count` AS `vpcTotal`,
+    `projectlimit`.`max` AS `projectLimit`,
+    `projectcount`.`count` AS `projectTotal`,
+    `networklimit`.`max` AS `networkLimit`,
+    `networkcount`.`count` AS `networkTotal`,
+    `cpulimit`.`max` AS `cpuLimit`,
+    `cpucount`.`count` AS `cpuTotal`,
+    `memorylimit`.`max` AS `memoryLimit`,
+    `memorycount`.`count` AS `memoryTotal`,
+    `primary_storage_limit`.`max` AS `primaryStorageLimit`,
+    `primary_storage_count`.`count` AS `primaryStorageTotal`,
+    `secondary_storage_limit`.`max` AS `secondaryStorageLimit`,
+    `secondary_storage_count`.`count` AS `secondaryStorageTotal`,
+    `async_job`.`id` AS `job_id`,
+    `async_job`.`uuid` AS `job_uuid`,
+    `async_job`.`job_status` AS `job_status`,
+    `async_job`.`account_id` AS `job_account_id`
+from
+    `cloud`.`free_ip_view`,
+    `cloud`.`account`
+        inner join
+    `cloud`.`domain` ON account.domain_id = domain.id
+        left join
+    `cloud`.`data_center` ON account.default_zone_id = data_center.id
+        left join
+    `cloud`.`account_netstats_view` ON account.id = account_netstats_view.account_id
+        left join
+    `cloud`.`resource_limit` vmlimit ON account.id = vmlimit.account_id
+        and vmlimit.type = 'user_vm'
+        left join
+    `cloud`.`resource_count` vmcount ON account.id = vmcount.account_id
+        and vmcount.type = 'user_vm'
+        left join
+    `cloud`.`account_vmstats_view` runningvm ON account.id = runningvm.account_id
+        and runningvm.state = 'Running'
+        left join
+    `cloud`.`account_vmstats_view` stoppedvm ON account.id = stoppedvm.account_id
+        and stoppedvm.state = 'Stopped'
+        left join
+    `cloud`.`resource_limit` iplimit ON account.id = iplimit.account_id
+        and iplimit.type = 'public_ip'
+        left join
+    `cloud`.`resource_count` ipcount ON account.id = ipcount.account_id
+        and ipcount.type = 'public_ip'
+        left join
+    `cloud`.`resource_limit` volumelimit ON account.id = volumelimit.account_id
+        and volumelimit.type = 'volume'
+        left join
+    `cloud`.`resource_count` volumecount ON account.id = volumecount.account_id
+        and volumecount.type = 'volume'
+        left join
+    `cloud`.`resource_limit` snapshotlimit ON account.id = snapshotlimit.account_id
+        and snapshotlimit.type = 'snapshot'
+        left join
+    `cloud`.`resource_count` snapshotcount ON account.id = snapshotcount.account_id
+        and snapshotcount.type = 'snapshot'
+        left join
+    `cloud`.`resource_limit` templatelimit ON account.id = templatelimit.account_id
+        and templatelimit.type = 'template'
+        left join
+    `cloud`.`resource_count` templatecount ON account.id = templatecount.account_id
+        and templatecount.type = 'template'
+        left join
+    `cloud`.`resource_limit` vpclimit ON account.id = vpclimit.account_id
+        and vpclimit.type = 'vpc'
+        left join
+    `cloud`.`resource_count` vpccount ON account.id = vpccount.account_id
+        and vpccount.type = 'vpc'
+        left join
+    `cloud`.`resource_limit` projectlimit ON account.id = projectlimit.account_id
+        and projectlimit.type = 'project'
+        left join
+    `cloud`.`resource_count` projectcount ON account.id = projectcount.account_id
+        and projectcount.type = 'project'
+        left join
+    `cloud`.`resource_limit` networklimit ON account.id = networklimit.account_id
+        and networklimit.type = 'network'
+        left join
+    `cloud`.`resource_count` networkcount ON account.id = networkcount.account_id
+        and networkcount.type = 'network'
+        left join
+    `cloud`.`resource_limit` cpulimit ON account.id = cpulimit.account_id
+        and cpulimit.type = 'cpu'
+        left join
+    `cloud`.`resource_count` cpucount ON account.id = cpucount.account_id
+        and cpucount.type = 'cpu'
+        left join
+    `cloud`.`resource_limit` memorylimit ON account.id = memorylimit.account_id
+        and memorylimit.type = 'memory'
+        left join
+    `cloud`.`resource_count` memorycount ON account.id = memorycount.account_id
+        and memorycount.type = 'memory'
+        left join
+    `cloud`.`resource_limit` primary_storage_limit ON account.id = primary_storage_limit.account_id
+        and primary_storage_limit.type = 'primary_storage'
+        left join
+    `cloud`.`resource_count` primary_storage_count ON account.id = primary_storage_count.account_id
+        and primary_storage_count.type = 'primary_storage'
+        left join
+    `cloud`.`resource_limit` secondary_storage_limit ON account.id = secondary_storage_limit.account_id
+        and secondary_storage_limit.type = 'secondary_storage'
+        left join
+    `cloud`.`resource_count` secondary_storage_count ON account.id = secondary_storage_count.account_id
+        and secondary_storage_count.type = 'secondary_storage'
+        left join
+    `cloud`.`async_job` ON async_job.instance_id = account.id
+        and async_job.instance_type = 'Account'
+        and async_job.job_status = 0;
+
+
+DROP VIEW IF EXISTS `cloud`.`domain_view`;
+CREATE VIEW `cloud`.`domain_view` AS
+select
+    `domain`.`id` AS `id`,
+    `domain`.`parent` AS `parent`,
+    `domain`.`name` AS `name`,
+    `domain`.`uuid` AS `uuid`,
+    `domain`.`owner` AS `owner`,
+    `domain`.`path` AS `path`,
+    `domain`.`level` AS `level`,
+    `domain`.`child_count` AS `child_count`,
+    `domain`.`next_child_seq` AS `next_child_seq`,
+    `domain`.`created` AS `created`,
+    `domain`.`removed` AS `removed`,
+    `domain`.`state` AS `state`,
+    `domain`.`network_domain` AS `network_domain`,
+    `domain`.`type` AS `type`,
+    `vmlimit`.`max` AS `vmLimit`,
+    `vmcount`.`count` AS `vmTotal`,
+    `iplimit`.`max` AS `ipLimit`,
+    `ipcount`.`count` AS `ipTotal`,
+    `volumelimit`.`max` AS `volumeLimit`,
+    `volumecount`.`count` AS `volumeTotal`,
+    `snapshotlimit`.`max` AS `snapshotLimit`,
+    `snapshotcount`.`count` AS `snapshotTotal`,
+    `templatelimit`.`max` AS `templateLimit`,
+    `templatecount`.`count` AS `templateTotal`,
+    `vpclimit`.`max` AS `vpcLimit`,
+    `vpccount`.`count` AS `vpcTotal`,
+    `projectlimit`.`max` AS `projectLimit`,
+    `projectcount`.`count` AS `projectTotal`,
+    `networklimit`.`max` AS `networkLimit`,
+    `networkcount`.`count` AS `networkTotal`,
+    `cpulimit`.`max` AS `cpuLimit`,
+    `cpucount`.`count` AS `cpuTotal`,
+    `memorylimit`.`max` AS `memoryLimit`,
+    `memorycount`.`count` AS `memoryTotal`,
+    `primary_storage_limit`.`max` AS `primaryStorageLimit`,
+    `primary_storage_count`.`count` AS `primaryStorageTotal`,
+    `secondary_storage_limit`.`max` AS `secondaryStorageLimit`,
+    `secondary_storage_count`.`count` AS `secondaryStorageTotal`
+from
+    `cloud`.`domain`
+        left join
+    `cloud`.`resource_limit` vmlimit ON domain.id = vmlimit.domain_id
+        and vmlimit.type = 'user_vm'
+        left join
+    `cloud`.`resource_count` vmcount ON domain.id = vmcount.domain_id
+        and vmcount.type = 'user_vm'
+        left join
+    `cloud`.`resource_limit` iplimit ON domain.id = iplimit.domain_id
+        and iplimit.type = 'public_ip'
+        left join
+    `cloud`.`resource_count` ipcount ON domain.id = ipcount.domain_id
+        and ipcount.type = 'public_ip'
+        left join
+    `cloud`.`resource_limit` volumelimit ON domain.id = volumelimit.domain_id
+        and volumelimit.type = 'volume'
+        left join
+    `cloud`.`resource_count` volumecount ON domain.id = volumecount.domain_id
+        and volumecount.type = 'volume'
+        left join
+    `cloud`.`resource_limit` snapshotlimit ON domain.id = snapshotlimit.domain_id
+        and snapshotlimit.type = 'snapshot'
+        left join
+    `cloud`.`resource_count` snapshotcount ON domain.id = snapshotcount.domain_id
+        and snapshotcount.type = 'snapshot'
+        left join
+    `cloud`.`resource_limit` templatelimit ON domain.id = templatelimit.domain_id
+        and templatelimit.type = 'template'
+        left join
+    `cloud`.`resource_count` templatecount ON domain.id = templatecount.domain_id
+        and templatecount.type = 'template'
+        left join
+    `cloud`.`resource_limit` vpclimit ON domain.id = vpclimit.domain_id
+        and vpclimit.type = 'vpc'
+        left join
+    `cloud`.`resource_count` vpccount ON domain.id = vpccount.domain_id
+        and vpccount.type = 'vpc'
+        left join
+    `cloud`.`resource_limit` projectlimit ON domain.id = projectlimit.domain_id
+        and projectlimit.type = 'project'
+        left join
+    `cloud`.`resource_count` projectcount ON domain.id = projectcount.domain_id
+        and projectcount.type = 'project'
+        left join
+    `cloud`.`resource_limit` networklimit ON domain.id = networklimit.domain_id
+        and networklimit.type = 'network'
+        left join
+    `cloud`.`resource_count` networkcount ON domain.id = networkcount.domain_id
+        and networkcount.type = 'network'
+        left join
+    `cloud`.`resource_limit` cpulimit ON domain.id = cpulimit.domain_id
+        and cpulimit.type = 'cpu'
+        left join
+    `cloud`.`resource_count` cpucount ON domain.id = cpucount.domain_id
+        and cpucount.type = 'cpu'
+        left join
+    `cloud`.`resource_limit` memorylimit ON domain.id = memorylimit.domain_id
+        and memorylimit.type = 'memory'
+        left join
+    `cloud`.`resource_count` memorycount ON domain.id = memorycount.domain_id
+        and memorycount.type = 'memory'
+        left join
+    `cloud`.`resource_limit` primary_storage_limit ON domain.id = primary_storage_limit.domain_id
+        and primary_storage_limit.type = 'primary_storage'
+        left join
+    `cloud`.`resource_count` primary_storage_count ON domain.id = primary_storage_count.domain_id
+        and primary_storage_count.type = 'primary_storage'
+        left join
+    `cloud`.`resource_limit` secondary_storage_limit ON domain.id = secondary_storage_limit.domain_id
+        and secondary_storage_limit.type = 'secondary_storage'
+        left join
+    `cloud`.`resource_count` secondary_storage_count ON domain.id = secondary_storage_count.domain_id
+        and secondary_storage_count.type = 'secondary_storage';
diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
index 730130f..edbd649 100644
--- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java
@@ -425,6 +425,7 @@ public class ApiResponseHelper implements ResponseGenerator {
         domainResponse.setDomainName(domain.getName());
         domainResponse.setId(domain.getUuid());
         domainResponse.setLevel(domain.getLevel());
+        domainResponse.setCreated(domain.getCreated());
         domainResponse.setNetworkDomain(domain.getNetworkDomain());
         Domain parentDomain = ApiDBUtils.findDomainById(domain.getParent());
         if (parentDomain != null) {
diff --git a/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java
index c5f8ad5..fa2049e 100644
--- a/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/AccountJoinDaoImpl.java
@@ -70,6 +70,7 @@ public class AccountJoinDaoImpl extends GenericDaoBase<AccountJoinVO, Long> impl
         (domainPath.append(account.getDomainPath())).deleteCharAt(domainPath.length() - 1);
         accountResponse.setDomainPath(domainPath.toString());
         accountResponse.setState(account.getState().toString());
+        accountResponse.setCreated(account.getCreated());
         accountResponse.setNetworkDomain(account.getNetworkDomain());
         accountResponse.setDefaultZone(account.getDataCenterUuid());
         accountResponse.setIsDefault(account.isDefault());
diff --git a/server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java
index a613fcb..d65afd2 100644
--- a/server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java
+++ b/server/src/main/java/com/cloud/api/query/dao/DomainJoinDaoImpl.java
@@ -71,6 +71,7 @@ public class DomainJoinDaoImpl extends GenericDaoBase<DomainJoinVO, Long> implem
         }
 
         domainResponse.setState(domain.getState().toString());
+        domainResponse.setCreated(domain.getCreated());
         domainResponse.setNetworkDomain(domain.getNetworkDomain());
 
         if (details.contains(DomainDetails.all) || details.contains(DomainDetails.resource)) {
diff --git a/server/src/main/java/com/cloud/api/query/vo/AccountJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/AccountJoinVO.java
index f251abc..146de0c 100644
--- a/server/src/main/java/com/cloud/api/query/vo/AccountJoinVO.java
+++ b/server/src/main/java/com/cloud/api/query/vo/AccountJoinVO.java
@@ -55,6 +55,9 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
     @Enumerated(value = EnumType.STRING)
     private State state;
 
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
     @Column(name = GenericDao.REMOVED_COLUMN)
     private Date removed;
 
@@ -213,6 +216,10 @@ public class AccountJoinVO extends BaseViewVO implements InternalIdentity, Ident
         return state;
     }
 
+    public Date getCreated() {
+        return created;
+    }
+
     public Date getRemoved() {
         return removed;
     }
diff --git a/server/src/main/java/com/cloud/api/query/vo/DomainJoinVO.java b/server/src/main/java/com/cloud/api/query/vo/DomainJoinVO.java
index 6f4d6b7..84456e4 100644
--- a/server/src/main/java/com/cloud/api/query/vo/DomainJoinVO.java
+++ b/server/src/main/java/com/cloud/api/query/vo/DomainJoinVO.java
@@ -53,6 +53,9 @@ public class DomainJoinVO extends BaseViewVO implements InternalIdentity, Identi
     @Column(name="level")
     private int level;
 
+    @Column(name=GenericDao.CREATED_COLUMN)
+    private Date created;
+
     @Column(name=GenericDao.REMOVED_COLUMN)
     private Date removed;
 
@@ -208,6 +211,10 @@ public class DomainJoinVO extends BaseViewVO implements InternalIdentity, Identi
         return accountId;
     }
 
+    public Date getCreated() {
+        return created;
+    }
+
     public Date getRemoved() {
         return removed;
     }