cloudstack-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (CLOUDSTACK-9958) Include tags of resources in listUsageRecords API
Date Tue, 07 Nov 2017 04:23:00 GMT

    [ https://issues.apache.org/jira/browse/CLOUDSTACK-9958?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16241460#comment-16241460
] 

ASF GitHub Bot commented on CLOUDSTACK-9958:
--------------------------------------------

rhtyd closed pull request #2242: CLOUDSTACK-9958:Include tags of resources in listUsageRecords
API
URL: https://github.com/apache/cloudstack/pull/2242
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 0a8a112d737..4a0d610feec 100644
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -297,6 +297,7 @@
     public static final String VIRTUAL_MACHINE_COUNT = "virtualmachinecount";
     public static final String USAGE_ID = "usageid";
     public static final String USAGE_TYPE = "usagetype";
+    public static final String INCLUDE_TAGS = "includetags";
 
     public static final String VLAN = "vlan";
     public static final String VLAN_RANGE = "vlanrange";
diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
index 9fd4d847344..7b33ebbea7a 100644
--- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
@@ -20,6 +20,7 @@
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.cloudstack.affinity.AffinityGroup;
 import org.apache.cloudstack.affinity.AffinityGroupResponse;
@@ -430,6 +431,10 @@
 
     UsageRecordResponse createUsageResponse(Usage usageRecord);
 
+    UsageRecordResponse createUsageResponse(Usage usageRecord, Map<String, Set<ResourceTagResponse>>
resourceTagResponseMap);
+
+    public Map<String, Set<ResourceTagResponse>> getUsageResourceTags();
+
     TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor);
 
     VMSnapshotResponse createVMSnapshotResponse(VMSnapshot vmSnapshot);
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/GetUsageRecordsCmd.java
b/api/src/org/apache/cloudstack/api/command/admin/usage/GetUsageRecordsCmd.java
index 4cceb3b5f9f..90bc4f2153a 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/usage/GetUsageRecordsCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/usage/GetUsageRecordsCmd.java
@@ -19,6 +19,8 @@
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.apache.log4j.Logger;
 
@@ -31,6 +33,7 @@
 import org.apache.cloudstack.api.response.ListResponse;
 import org.apache.cloudstack.api.response.ProjectResponse;
 import org.apache.cloudstack.api.response.UsageRecordResponse;
+import org.apache.cloudstack.api.response.ResourceTagResponse;
 import org.apache.cloudstack.usage.Usage;
 
 import com.cloud.utils.Pair;
@@ -76,6 +79,9 @@
     @Parameter(name = ApiConstants.USAGE_ID, type = CommandType.STRING, description = "List
usage records for the specified usage UUID. Can be used only together with TYPE parameter.")
     private String usageId;
 
+    @Parameter(name = ApiConstants.INCLUDE_TAGS, type = CommandType.BOOLEAN, description
= "Flag to enable display of Tags for a resource")
+    private Boolean includeTags;
+
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -115,6 +121,10 @@ public void setAccountName(String accountName) {
         this.accountName = accountName;
     }
 
+    public Boolean getIncludeTags() {
+        return includeTags;
+    }
+
     public void setDomainId(Long domainId) {
         this.domainId = domainId;
     }
@@ -150,12 +160,18 @@ public void execute() {
         Pair<List<? extends Usage>, Integer> usageRecords = _usageService.getUsageRecords(this);
         ListResponse<UsageRecordResponse> response = new ListResponse<UsageRecordResponse>();
         List<UsageRecordResponse> usageResponses = new ArrayList<UsageRecordResponse>();
+        Map<String, Set<ResourceTagResponse>> resourceTagResponseMap = null;
         if (usageRecords != null) {
+            //read the resource tags details for all the resources in usage data and store
in Map
+            if(null != includeTags && includeTags) {
+                resourceTagResponseMap =  _responseGenerator.getUsageResourceTags();
+            }
             for (Usage usageRecord : usageRecords.first()) {
-                UsageRecordResponse usageResponse = _responseGenerator.createUsageResponse(usageRecord);
+                UsageRecordResponse usageResponse = _responseGenerator.createUsageResponse(usageRecord,
resourceTagResponseMap);
                 usageResponse.setObjectName("usagerecord");
                 usageResponses.add(usageResponse);
             }
+
             response.setResponses(usageResponses, usageRecords.second());
         }
 
diff --git a/api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java b/api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java
index e51475b3810..c53f2b99e0b 100644
--- a/api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/UsageRecordResponse.java
@@ -19,12 +19,15 @@
 import com.google.gson.annotations.SerializedName;
 
 import org.apache.cloudstack.api.ApiConstants;
-import org.apache.cloudstack.api.BaseResponse;
 
 import com.cloud.serializer.Param;
+import org.apache.cloudstack.api.BaseResponseWithTagInformation;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
 
 @SuppressWarnings("unused")
-public class UsageRecordResponse extends BaseResponse implements ControlledEntityResponse
{
+public class UsageRecordResponse extends BaseResponseWithTagInformation implements ControlledEntityResponse
{
     @SerializedName(ApiConstants.ACCOUNT)
     @Param(description = "the user account name")
     private String accountName;
@@ -137,6 +140,14 @@
     @Param(description = "True if the resource is default")
     private Boolean isDefault;
 
+    public UsageRecordResponse() {
+        tags = new LinkedHashSet<ResourceTagResponse>();
+    }
+
+    public void setTags(Set<ResourceTagResponse> tags) {
+        this.tags = tags;
+    }
+
     @Override
     public void setAccountName(String accountName) {
         this.accountName = accountName;
diff --git a/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java b/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java
index 87662ef0679..b7884342a53 100644
--- a/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java
+++ b/engine/schema/src/com/cloud/tags/dao/ResourceTagDao.java
@@ -17,11 +17,14 @@
 package com.cloud.tags.dao;
 
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import com.cloud.server.ResourceTag;
 import com.cloud.server.ResourceTag.ResourceObjectType;
 import com.cloud.tags.ResourceTagVO;
 import com.cloud.utils.db.GenericDao;
+import org.apache.cloudstack.api.response.ResourceTagResponse;
 
 public interface ResourceTagDao extends GenericDao<ResourceTagVO, Long> {
 
@@ -35,4 +38,6 @@
     List<? extends ResourceTag> listBy(long resourceId, ResourceObjectType resourceType);
 
     void updateResourceId(long srcId, long destId, ResourceObjectType resourceType);
+
+    Map<String, Set<ResourceTagResponse>> listTags();
 }
diff --git a/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java b/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
index 0e23eff900f..d5578a8fded 100644
--- a/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
+++ b/engine/schema/src/com/cloud/tags/dao/ResourceTagsDaoImpl.java
@@ -17,8 +17,12 @@
 package com.cloud.tags.dao;
 
 import java.util.List;
+import java.util.Set;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.HashSet;
 
-
+import org.apache.cloudstack.api.response.ResourceTagResponse;
 import org.springframework.stereotype.Component;
 
 import com.cloud.server.ResourceTag;
@@ -67,4 +71,26 @@ public boolean removeByIdAndType(long resourceId, ResourceTag.ResourceObjectType
             update(tag.getId(), tag);
         }
     }
+
+    @Override
+    public Map<String, Set<ResourceTagResponse>> listTags() {
+        SearchCriteria<ResourceTagVO> sc = AllFieldsSearch.create();
+        List<ResourceTagVO> resourceTagList = listBy(sc);
+        Map<String, Set<ResourceTagResponse>> resourceTagMap = new HashMap();
+        String resourceKey = null;
+        ResourceTagResponse resourceTagResponse = null;
+        for (ResourceTagVO resourceTagVO : resourceTagList) {
+            resourceTagResponse = new ResourceTagResponse();
+            resourceTagResponse.setKey(resourceTagVO.getKey());
+            resourceTagResponse.setValue(resourceTagVO.getValue());
+            Set<ResourceTagResponse> resourceTagSet = new HashSet();
+            resourceKey = resourceTagVO.getResourceId() + ":" + resourceTagVO.getResourceType();
+            if(resourceTagMap.get(resourceKey) != null) {
+                resourceTagSet = resourceTagMap.get(resourceKey);
+            }
+            resourceTagSet.add(resourceTagResponse);
+            resourceTagMap.put(resourceKey, resourceTagSet);
+        }
+        return resourceTagMap;
+    }
 }
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 82f93978088..99f1b471265 100644
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -17,6 +17,7 @@
 package com.cloud.api;
 
 import com.cloud.utils.crypt.DBEncryptionUtil;
+import com.cloud.tags.dao.ResourceTagDao;
 import com.cloud.agent.api.VgpuTypesInfo;
 import com.cloud.api.query.ViewResponseHelper;
 import com.cloud.api.query.vo.AccountJoinVO;
@@ -346,6 +347,8 @@
     private PrimaryDataStoreDao _storagePoolDao;
     @Inject
     private ClusterDetailsDao _clusterDetailsDao;
+    @Inject
+    private ResourceTagDao _resourceTagDao;
 
     @Override
     public UserResponse createUserResponse(User user) {
@@ -3193,9 +3196,24 @@ public SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule
     }
 
     @Override
+    public Map<String, Set<ResourceTagResponse>> getUsageResourceTags()
+    {
+        try {
+            return _resourceTagDao.listTags();
+        } catch(Exception ex) {
+            s_logger.warn("Failed to get resource details for Usage data due to exception
: ", ex);
+        }
+        return null;
+    }
+
+    @Override
     public UsageRecordResponse createUsageResponse(Usage usageRecord) {
-        UsageRecordResponse usageRecResponse = new UsageRecordResponse();
+        return createUsageResponse(usageRecord, null);
+    }
 
+    @Override
+    public UsageRecordResponse createUsageResponse(Usage usageRecord, Map<String, Set<ResourceTagResponse>>
resourceTagResponseMap) {
+        UsageRecordResponse usageRecResponse = new UsageRecordResponse();
         Account account = ApiDBUtils.findAccountById(usageRecord.getAccountId());
         if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
             //find the project
@@ -3238,14 +3256,20 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord)
{
             }
         }
 
+        ResourceTag.ResourceObjectType resourceType = null;
+        Long resourceId = null;
         if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM || usageRecord.getUsageType()
== UsageTypes.ALLOCATED_VM) {
             ServiceOfferingVO svcOffering = _entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class,
usageRecord.getOfferingId().toString());
             //Service Offering Id
-            usageRecResponse.setOfferingId(svcOffering.getUuid());
+            if(svcOffering != null) {
+                usageRecResponse.setOfferingId(svcOffering.getUuid());
+            }
             //VM Instance ID
             VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
             if (vm != null) {
+                resourceType = ResourceTag.ResourceObjectType.UserVm;
                 usageRecResponse.setUsageId(vm.getUuid());
+                resourceId = vm.getId();
             }
             //Hypervisor Type
             usageRecResponse.setType(usageRecord.getType());
@@ -3274,16 +3298,20 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord)
{
             //IP Address ID
             IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId().toString());
             if (ip != null) {
+                resourceType = ResourceObjectType.PublicIpAddress;
+                resourceId = ip.getId();
                 usageRecResponse.setUsageId(ip.getUuid());
             }
 
         } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType()
== UsageTypes.NETWORK_BYTES_RECEIVED) {
             //Device Type
+            resourceType = ResourceObjectType.UserVm;
             usageRecResponse.setType(usageRecord.getType());
             if (usageRecord.getType().equals("DomainRouter") || usageRecord.getType().equals("UserVm"))
{
                 //Domain Router Id
                 VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class,
usageRecord.getUsageId().toString());
                 if (vm != null) {
+                    resourceId = vm.getId();
                     usageRecResponse.setUsageId(vm.getUuid());
                 }
             } else {
@@ -3297,14 +3325,16 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord)
{
             if((usageRecord.getNetworkId() != null) && (usageRecord.getNetworkId()
!= 0)) {
                 NetworkVO network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class,
usageRecord.getNetworkId().toString());
                 if (network != null) {
+                    resourceType = ResourceObjectType.Network;
+                    resourceId = network.getId();
                     usageRecResponse.setNetworkId(network.getUuid());
                 }
             }
-
         } else if (usageRecord.getUsageType() == UsageTypes.VM_DISK_IO_READ || usageRecord.getUsageType()
== UsageTypes.VM_DISK_IO_WRITE
                 || usageRecord.getUsageType() == UsageTypes.VM_DISK_BYTES_READ || usageRecord.getUsageType()
== UsageTypes.VM_DISK_BYTES_WRITE) {
             //Device Type
             usageRecResponse.setType(usageRecord.getType());
+            resourceType = ResourceObjectType.Volume;
             //VM Instance Id
             VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString());
             if (vm != null) {
@@ -3314,13 +3344,16 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord)
{
             VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
             if (volume != null) {
                 usageRecResponse.setUsageId(volume.getUuid());
+                resourceId = volume.getId();
             }
 
         } else if (usageRecord.getUsageType() == UsageTypes.VOLUME) {
             //Volume ID
             VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.Volume;
             if (volume != null) {
                 usageRecResponse.setUsageId(volume.getUuid());
+                resourceId = volume.getId();
             }
             //Volume Size
             usageRecResponse.setSize(usageRecord.getSize());
@@ -3335,20 +3368,25 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord)
{
             VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString());
             if (tmpl != null) {
                 usageRecResponse.setUsageId(tmpl.getUuid());
+                resourceId = tmpl.getId();
             }
             //Template/ISO Size
             usageRecResponse.setSize(usageRecord.getSize());
             if (usageRecord.getUsageType() == UsageTypes.ISO) {
                 usageRecResponse.setVirtualSize(usageRecord.getSize());
+                resourceType = ResourceObjectType.ISO;
             } else {
                 usageRecResponse.setVirtualSize(usageRecord.getVirtualSize());
+                resourceType = ResourceObjectType.Template;
             }
 
         } else if (usageRecord.getUsageType() == UsageTypes.SNAPSHOT) {
             //Snapshot ID
             SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.Snapshot;
             if (snap != null) {
                 usageRecResponse.setUsageId(snap.getUuid());
+                resourceId = snap.getId();
             }
             //Snapshot Size
             usageRecResponse.setSize(usageRecord.getSize());
@@ -3356,14 +3394,18 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord)
{
         } else if (usageRecord.getUsageType() == UsageTypes.LOAD_BALANCER_POLICY) {
             //Load Balancer Policy ID
             LoadBalancerVO lb = _entityMgr.findByIdIncludingRemoved(LoadBalancerVO.class,
usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.LoadBalancer;
             if (lb != null) {
                 usageRecResponse.setUsageId(lb.getUuid());
+                resourceId = lb.getId();
             }
         } else if (usageRecord.getUsageType() == UsageTypes.PORT_FORWARDING_RULE) {
             //Port Forwarding Rule ID
             PortForwardingRuleVO pf = _entityMgr.findByIdIncludingRemoved(PortForwardingRuleVO.class,
usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.PortForwardingRule;
             if (pf != null) {
                 usageRecResponse.setUsageId(pf.getUuid());
+                resourceId = pf.getId();
             }
 
         } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING) {
@@ -3379,16 +3421,19 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord)
{
             if (vpnUser != null) {
                 usageRecResponse.setUsageId(vpnUser.getUuid());
             }
-
         } else if (usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP) {
             //Security Group Id
             SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class,
usageRecord.getUsageId().toString());
+            resourceType = ResourceObjectType.SecurityGroup;
             if (sg != null) {
+                resourceId = sg.getId();
                 usageRecResponse.setUsageId(sg.getUuid());
             }
         } else if (usageRecord.getUsageType() == UsageTypes.VM_SNAPSHOT) {
             VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId().toString());
+            resourceType = ResourceObjectType.UserVm;
             if (vm != null) {
+                resourceId = vm.getId();
                 usageRecResponse.setVmName(vm.getInstanceName());
                 usageRecResponse.setUsageId(vm.getUuid());
             }
@@ -3398,6 +3443,10 @@ public UsageRecordResponse createUsageResponse(Usage usageRecord) {
             }
         }
 
+        if(resourceTagResponseMap != null && resourceTagResponseMap.get(resourceId
+ ":" + resourceType) != null) {
+             usageRecResponse.setTags(resourceTagResponseMap.get(resourceId + ":" + resourceType));
+        }
+
         if (usageRecord.getRawUsage() != null) {
             DecimalFormat decimalFormat = new DecimalFormat("###########.######");
             usageRecResponse.setRawUsage(decimalFormat.format(usageRecord.getRawUsage()));


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


> Include tags of resources in listUsageRecords API
> -------------------------------------------------
>
>                 Key: CLOUDSTACK-9958
>                 URL: https://issues.apache.org/jira/browse/CLOUDSTACK-9958
>             Project: CloudStack
>          Issue Type: Improvement
>      Security Level: Public(Anyone can view this level - this is the default.) 
>            Reporter: mrunalini
>
>  Tags field to be included in the listusagerecords response such that it can be used
in billing report. E.g.
> "tags":[{"key":"city","value":"Toronto","resourcetype":"UserVm","resourceid":"a0cca906-f985-4b56-ad11-f33e59c4c733","account":"admin","domainid":"dec39eb8-4f81-11e7-8315-067fa0000031","domain":"ROOT"},{"key":"region","value":"canada","resourcetype":"UserVm","resourceid":"a0cca906-f985-4b56-ad11-f33e59c4c733","account":"admin","domainid":"dec39eb8-4f81-11e7-8315-067fa0000031","domain":"ROOT"}



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Mime
View raw message