Skip to content

Commit 3139ece

Browse files
committed
vm, template resource icons from category
Signed-off-by: Abhishek Kumar <[email protected]>
1 parent 039e1ec commit 3139ece

File tree

15 files changed

+274
-71
lines changed

15 files changed

+274
-71
lines changed

api/src/main/java/com/cloud/server/ResourceIconManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
// under the License.
1717
package com.cloud.server;
1818

19+
import java.util.Collection;
1920
import java.util.List;
21+
import java.util.Map;
2022

2123
public interface ResourceIconManager {
2224

@@ -25,4 +27,8 @@ public interface ResourceIconManager {
2527
boolean deleteResourceIcon(List<String> resourceIds, ResourceTag.ResourceObjectType resourceType);
2628

2729
ResourceIcon getByResourceTypeAndUuid(ResourceTag.ResourceObjectType type, String resourceId);
30+
31+
Map<Long, ResourceIcon> getByResourceTypeAndIds(ResourceTag.ResourceObjectType type, Collection<Long> resourceIds);
32+
33+
Map<String, ResourceIcon> getByResourceTypeAndUuids(ResourceTag.ResourceObjectType type, Collection<String> resourceUuids);
2834
}

api/src/main/java/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.user.iso;
1818

19-
import com.cloud.cpu.CPU;
20-
import com.cloud.server.ResourceIcon;
21-
import com.cloud.server.ResourceTag;
22-
23-
import org.apache.cloudstack.api.response.GuestOSCategoryResponse;
24-
import org.apache.cloudstack.api.response.ResourceIconResponse;
19+
import java.util.HashMap;
20+
import java.util.List;
21+
import java.util.Map;
22+
import java.util.Set;
23+
import java.util.stream.Collectors;
2524

2625
import org.apache.cloudstack.api.APICommand;
2726
import org.apache.cloudstack.api.ApiCommandResourceType;
@@ -30,16 +29,19 @@
3029
import org.apache.cloudstack.api.Parameter;
3130
import org.apache.cloudstack.api.ResponseObject.ResponseView;
3231
import org.apache.cloudstack.api.command.user.UserCmd;
32+
import org.apache.cloudstack.api.response.GuestOSCategoryResponse;
3333
import org.apache.cloudstack.api.response.ListResponse;
34+
import org.apache.cloudstack.api.response.ResourceIconResponse;
3435
import org.apache.cloudstack.api.response.TemplateResponse;
3536
import org.apache.cloudstack.api.response.ZoneResponse;
3637
import org.apache.cloudstack.context.CallContext;
38+
import org.apache.commons.lang3.StringUtils;
3739

40+
import com.cloud.cpu.CPU;
41+
import com.cloud.server.ResourceIcon;
42+
import com.cloud.server.ResourceTag;
3843
import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
3944
import com.cloud.user.Account;
40-
import org.apache.commons.lang3.StringUtils;
41-
42-
import java.util.List;
4345

4446
@APICommand(name = "listIsos", description = "Lists all available ISO files.", responseObject = TemplateResponse.class, responseView = ResponseView.Restricted,
4547
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -208,14 +210,33 @@ public void execute() {
208210
setResponseObject(response);
209211
}
210212

211-
private void updateIsoResponse(List<TemplateResponse> response) {
212-
for (TemplateResponse templateResponse : response) {
213-
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.ISO, templateResponse.getId());
214-
if (resourceIcon == null) {
213+
protected Map<String, ResourceIcon> getResourceIconsUsingOsCategory(List<TemplateResponse> responses) {
214+
Set<Long> guestOsCategoryIds = responses.stream().map(TemplateResponse::getOsTypeCategoryId).collect(Collectors.toSet());
215+
Map<Long, ResourceIcon> guestOsCategoryIcons =
216+
resourceIconManager.getByResourceTypeAndIds(ResourceTag.ResourceObjectType.GuestOsCategory,
217+
guestOsCategoryIds);
218+
Map<String, ResourceIcon> vmIcons = new HashMap<>();
219+
for (TemplateResponse response : responses) {
220+
vmIcons.put(response.getId(), guestOsCategoryIcons.get(response.getOsTypeCategoryId()));
221+
}
222+
return vmIcons;
223+
}
224+
225+
private void updateIsoResponse(List<TemplateResponse> responses) {
226+
Set<String> isoUuids = responses.stream().map(TemplateResponse::getId).collect(Collectors.toSet());
227+
Map<String, ResourceIcon> templateIcons = resourceIconManager.getByResourceTypeAndUuids(ResourceTag.ResourceObjectType.ISO, isoUuids);
228+
List<TemplateResponse> noTemplateIconResponses = responses
229+
.stream()
230+
.filter(r -> !templateIcons.containsKey(r.getId()))
231+
.collect(Collectors.toList());
232+
templateIcons.putAll(getResourceIconsUsingOsCategory(noTemplateIconResponses));
233+
for (TemplateResponse response : responses) {
234+
ResourceIcon icon = templateIcons.get(response.getId());
235+
if (icon == null) {
215236
continue;
216237
}
217-
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
218-
templateResponse.setResourceIconResponse(iconResponse);
238+
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(icon);
239+
response.setResourceIconResponse(iconResponse);
219240
}
220241
}
221242

api/src/main/java/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,38 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.user.template;
1818

19-
import com.cloud.cpu.CPU;
20-
import com.cloud.exception.InvalidParameterValueException;
21-
import com.cloud.server.ResourceIcon;
22-
import com.cloud.server.ResourceTag;
23-
24-
import org.apache.cloudstack.api.response.GuestOSCategoryResponse;
25-
import org.apache.cloudstack.api.response.ResourceIconResponse;
26-
import org.apache.commons.collections.CollectionUtils;
27-
2819
import java.util.ArrayList;
2920
import java.util.Collections;
3021
import java.util.EnumSet;
22+
import java.util.HashMap;
3123
import java.util.List;
24+
import java.util.Map;
25+
import java.util.Set;
26+
import java.util.stream.Collectors;
27+
3228
import org.apache.cloudstack.api.APICommand;
3329
import org.apache.cloudstack.api.ApiCommandResourceType;
3430
import org.apache.cloudstack.api.ApiConstants;
3531
import org.apache.cloudstack.api.BaseListTaggedResourcesCmd;
3632
import org.apache.cloudstack.api.Parameter;
3733
import org.apache.cloudstack.api.ResponseObject.ResponseView;
3834
import org.apache.cloudstack.api.command.user.UserCmd;
35+
import org.apache.cloudstack.api.response.GuestOSCategoryResponse;
3936
import org.apache.cloudstack.api.response.ListResponse;
37+
import org.apache.cloudstack.api.response.ResourceIconResponse;
4038
import org.apache.cloudstack.api.response.TemplateResponse;
4139
import org.apache.cloudstack.api.response.ZoneResponse;
4240
import org.apache.cloudstack.context.CallContext;
41+
import org.apache.commons.collections.CollectionUtils;
42+
import org.apache.commons.lang3.StringUtils;
4343

44+
import com.cloud.cpu.CPU;
45+
import com.cloud.exception.InvalidParameterValueException;
46+
import com.cloud.server.ResourceIcon;
47+
import com.cloud.server.ResourceTag;
4448
import com.cloud.template.VirtualMachineTemplate;
4549
import com.cloud.template.VirtualMachineTemplate.TemplateFilter;
4650
import com.cloud.user.Account;
47-
import org.apache.commons.lang3.StringUtils;
4851

4952
@APICommand(name = "listTemplates", description = "List all public, private, and privileged templates.", responseObject = TemplateResponse.class, entityType = {VirtualMachineTemplate.class}, responseView = ResponseView.Restricted,
5053
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@@ -236,14 +239,33 @@ public void execute() {
236239
setResponseObject(response);
237240
}
238241

239-
private void updateTemplateResponse(List<TemplateResponse> response) {
240-
for (TemplateResponse templateResponse : response) {
241-
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.Template, templateResponse.getId());
242-
if (resourceIcon == null) {
242+
protected Map<String, ResourceIcon> getResourceIconsUsingOsCategory(List<TemplateResponse> responses) {
243+
Set<Long> guestOsCategoryIds = responses.stream().map(TemplateResponse::getOsTypeCategoryId).collect(Collectors.toSet());
244+
Map<Long, ResourceIcon> guestOsCategoryIcons =
245+
resourceIconManager.getByResourceTypeAndIds(ResourceTag.ResourceObjectType.GuestOsCategory,
246+
guestOsCategoryIds);
247+
Map<String, ResourceIcon> vmIcons = new HashMap<>();
248+
for (TemplateResponse response : responses) {
249+
vmIcons.put(response.getId(), guestOsCategoryIcons.get(response.getOsTypeCategoryId()));
250+
}
251+
return vmIcons;
252+
}
253+
254+
private void updateTemplateResponse(List<TemplateResponse> responses) {
255+
Set<String> templateUuids = responses.stream().map(TemplateResponse::getId).collect(Collectors.toSet());
256+
Map<String, ResourceIcon> templateIcons = resourceIconManager.getByResourceTypeAndUuids(ResourceTag.ResourceObjectType.Template, templateUuids);
257+
List<TemplateResponse> noTemplateIconResponses = responses
258+
.stream()
259+
.filter(r -> !templateIcons.containsKey(r.getId()))
260+
.collect(Collectors.toList());
261+
templateIcons.putAll(getResourceIconsUsingOsCategory(noTemplateIconResponses));
262+
for (TemplateResponse response : responses) {
263+
ResourceIcon icon = templateIcons.get(response.getId());
264+
if (icon == null) {
243265
continue;
244266
}
245-
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
246-
templateResponse.setResourceIconResponse(iconResponse);
267+
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(icon);
268+
response.setResourceIconResponse(iconResponse);
247269
}
248270
}
249271

api/src/main/java/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command.user.vm;
1818

19+
import java.util.ArrayList;
1920
import java.util.EnumSet;
21+
import java.util.HashMap;
2022
import java.util.HashSet;
2123
import java.util.List;
24+
import java.util.Map;
2225
import java.util.Set;
26+
import java.util.function.Function;
27+
import java.util.stream.Collectors;
2328

2429
import org.apache.cloudstack.acl.RoleType;
2530
import org.apache.cloudstack.affinity.AffinityGroupResponse;
@@ -54,6 +59,7 @@
5459
import com.cloud.exception.InvalidParameterValueException;
5560
import com.cloud.server.ResourceIcon;
5661
import com.cloud.server.ResourceTag;
62+
import com.cloud.storage.GuestOS;
5763
import com.cloud.vm.VirtualMachine;
5864

5965

@@ -331,22 +337,75 @@ public void execute() {
331337
setResponseObject(response);
332338
}
333339

334-
protected void updateVMResponse(List<UserVmResponse> response) {
335-
for (UserVmResponse vmResponse : response) {
336-
ResourceIcon resourceIcon = resourceIconManager.getByResourceTypeAndUuid(ResourceTag.ResourceObjectType.UserVm, vmResponse.getId());
337-
if (resourceIcon == null) {
338-
ResourceTag.ResourceObjectType type = ResourceTag.ResourceObjectType.Template;
339-
String uuid = vmResponse.getTemplateId();
340-
if (vmResponse.getIsoId() != null) {
341-
uuid = vmResponse.getIsoId();
342-
type = ResourceTag.ResourceObjectType.ISO;
343-
}
344-
resourceIcon = resourceIconManager.getByResourceTypeAndUuid(type, uuid);
345-
if (resourceIcon == null) {
346-
continue;
347-
}
340+
protected Map<String, ResourceIcon> getResourceIconsUsingOsCategory(List<UserVmResponse> responses) {
341+
Set<String> guestOsIds = responses.stream().map(UserVmResponse::getGuestOsId).collect(Collectors.toSet());
342+
List<GuestOS> guestOSList = _entityMgr.listByUuids(GuestOS.class, guestOsIds);
343+
Map<String, GuestOS> guestOSMap = guestOSList.stream()
344+
.collect(Collectors.toMap(GuestOS::getUuid, Function.identity()));
345+
Set<Long> guestOsCategoryIds = guestOSMap.values().stream()
346+
.map(GuestOS::getCategoryId)
347+
.collect(Collectors.toSet());
348+
Map<Long, ResourceIcon> guestOsCategoryIcons =
349+
resourceIconManager.getByResourceTypeAndIds(ResourceTag.ResourceObjectType.GuestOsCategory,
350+
guestOsCategoryIds);
351+
Map<String, ResourceIcon> vmIcons = new HashMap<>();
352+
for (UserVmResponse response : responses) {
353+
GuestOS guestOS = guestOSMap.get(response.getGuestOsId());
354+
if (guestOS != null) {
355+
vmIcons.put(response.getId(), guestOsCategoryIcons.get(guestOS.getCategoryId()));
348356
}
349-
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(resourceIcon);
357+
}
358+
return vmIcons;
359+
}
360+
361+
protected Map<String, ResourceIcon> getResourceIconsForUsingTemplateIso(List<UserVmResponse> responses) {
362+
Map<String, String> vmTemplateIsoIdMap = new HashMap<>();
363+
Set<String> templateUuids = new HashSet<>();
364+
Set<String> isoUuids = new HashSet<>();
365+
for (UserVmResponse vmResponse : responses) {
366+
if (vmResponse.getTemplateId() != null) {
367+
templateUuids.add(vmResponse.getTemplateId());
368+
vmTemplateIsoIdMap.put(vmResponse.getId(), vmResponse.getTemplateId());
369+
}
370+
if (vmResponse.getIsoId() != null) {
371+
isoUuids.add(vmResponse.getIsoId());
372+
vmTemplateIsoIdMap.put(vmResponse.getId(), vmResponse.getIsoId());
373+
}
374+
}
375+
Map<String, ResourceIcon> templateOrIsoIcons = resourceIconManager.getByResourceTypeAndUuids(ResourceTag.ResourceObjectType.Template, templateUuids);
376+
templateOrIsoIcons.putAll(resourceIconManager.getByResourceTypeAndUuids(ResourceTag.ResourceObjectType.ISO, isoUuids));
377+
Map<String, ResourceIcon> vmIcons = new HashMap<>();
378+
List<UserVmResponse> noTemplateIsoIconResponses = new ArrayList<>();
379+
for (UserVmResponse response : responses) {
380+
String uuid = vmTemplateIsoIdMap.get(response.getId());
381+
if (StringUtils.isNotBlank(uuid) && templateOrIsoIcons.containsKey(uuid)) {
382+
vmIcons.put(response.getId(),
383+
templateOrIsoIcons.get(vmTemplateIsoIdMap.get(response.getId())));
384+
continue;
385+
}
386+
noTemplateIsoIconResponses.add(response);
387+
}
388+
vmIcons.putAll(getResourceIconsUsingOsCategory(noTemplateIsoIconResponses));
389+
return vmIcons;
390+
}
391+
392+
protected void updateVMResponse(List<UserVmResponse> responses) {
393+
if (CollectionUtils.isEmpty(responses)) {
394+
return;
395+
}
396+
Set<String> vmUuids = responses.stream().map(UserVmResponse::getId).collect(Collectors.toSet());
397+
Map<String, ResourceIcon> vmIcons = resourceIconManager.getByResourceTypeAndUuids(ResourceTag.ResourceObjectType.UserVm, vmUuids);
398+
List<UserVmResponse> noVmIconResponses = responses
399+
.stream()
400+
.filter(r -> !vmIcons.containsKey(r.getId()))
401+
.collect(Collectors.toList());
402+
vmIcons.putAll(getResourceIconsForUsingTemplateIso(noVmIconResponses));
403+
for (UserVmResponse vmResponse : responses) {
404+
ResourceIcon icon = vmIcons.get(vmResponse.getId());
405+
if (icon == null) {
406+
continue;
407+
}
408+
ResourceIconResponse iconResponse = _responseGenerator.createResourceIconResponse(icon);
350409
vmResponse.setResourceIconResponse(iconResponse);
351410
}
352411
}

api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements
9393
@Param(description = "the name of the OS type for this template.")
9494
private String osTypeName;
9595

96+
private transient Long osTypeCategoryId;
97+
9698
@SerializedName(ApiConstants.ACCOUNT_ID)
9799
@Param(description = "the account id to which the template belongs")
98100
private String accountId;
@@ -285,6 +287,14 @@ public void setOsTypeName(String osTypeName) {
285287
this.osTypeName = osTypeName;
286288
}
287289

290+
public Long getOsTypeCategoryId() {
291+
return osTypeCategoryId;
292+
}
293+
294+
public void setOsTypeCategoryId(Long osTypeCategoryId) {
295+
this.osTypeCategoryId = osTypeCategoryId;
296+
}
297+
288298
public void setId(String id) {
289299
this.id = id;
290300
}

engine/schema/src/main/java/com/cloud/resource/icon/dao/ResourceIconDao.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,13 @@
2222
import com.cloud.utils.db.GenericDao;
2323
import org.apache.cloudstack.api.response.ResourceIconResponse;
2424

25+
import java.util.Collection;
2526
import java.util.List;
2627

2728
public interface ResourceIconDao extends GenericDao<ResourceIconVO, Long> {
2829
ResourceIconResponse newResourceIconResponse(ResourceIcon resourceIconVO);
2930
ResourceIconVO findByResourceUuid(String resourceUuid, ResourceTag.ResourceObjectType resourceType);
31+
List<ResourceIconVO> listByResourceTypeAndIds(ResourceTag.ResourceObjectType resourceType, Collection<Long> resourceIds);
32+
List<ResourceIconVO> listByResourceTypeAndUuids(ResourceTag.ResourceObjectType resourceType, Collection<String> resourceUuids);
3033
List<ResourceIconResponse> listResourceIcons(List<String> resourceUuids, ResourceTag.ResourceObjectType resourceType);
3134
}

engine/schema/src/main/java/com/cloud/resource/icon/dao/ResourceIconDaoImpl.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import com.cloud.utils.db.SearchCriteria;
2525
import org.apache.cloudstack.api.ApiConstants;
2626
import org.apache.cloudstack.api.response.ResourceIconResponse;
27+
import org.apache.commons.collections.CollectionUtils;
2728

2829
import java.util.ArrayList;
30+
import java.util.Collection;
2931
import java.util.List;
3032

3133
public class ResourceIconDaoImpl extends GenericDaoBase<ResourceIconVO, Long> implements ResourceIconDao {
@@ -58,11 +60,36 @@ public ResourceIconVO findByResourceUuid(String resourceUuid, ResourceTag.Resour
5860
}
5961

6062
@Override
61-
public List<ResourceIconResponse> listResourceIcons(List<String> resourceUuids, ResourceTag.ResourceObjectType resourceType) {
63+
public List<ResourceIconVO> listByResourceTypeAndIds(ResourceTag.ResourceObjectType resourceType,
64+
Collection<Long> resourceIds) {
65+
if (CollectionUtils.isEmpty(resourceIds)) {
66+
return new ArrayList<>();
67+
}
68+
SearchBuilder<ResourceIconVO> sb = createSearchBuilder();
69+
sb.and("resourceId", sb.entity().getResourceId(), SearchCriteria.Op.IN);
70+
sb.and("resourceType", sb.entity().getResourceType(), SearchCriteria.Op.EQ);
71+
sb.done();
72+
SearchCriteria<ResourceIconVO> sc = sb.create();
73+
sc.setParameters("resourceId", resourceIds.toArray());
74+
sc.setParameters("resourceType", resourceType);
75+
return listBy(sc);
76+
}
77+
78+
@Override
79+
public List<ResourceIconVO> listByResourceTypeAndUuids(ResourceTag.ResourceObjectType resourceType,
80+
Collection<String> resourceUuids) {
81+
if (CollectionUtils.isEmpty(resourceUuids)) {
82+
return new ArrayList<>();
83+
}
6284
SearchCriteria<ResourceIconVO> sc = AllFieldsSearch.create();
6385
sc.setParameters("uuid", resourceUuids.toArray());
6486
sc.setParameters("resourceType", resourceType);
65-
List<ResourceIconVO> resourceIcons = listBy(sc);
87+
return listBy(sc);
88+
}
89+
90+
@Override
91+
public List<ResourceIconResponse> listResourceIcons(List<String> resourceUuids, ResourceTag.ResourceObjectType resourceType) {
92+
List<ResourceIconVO> resourceIcons = listByResourceTypeAndUuids(resourceType, resourceUuids);
6693
List<ResourceIconResponse> iconResponses = new ArrayList<>();
6794
for (ResourceIconVO resourceIcon : resourceIcons) {
6895
ResourceIconResponse response = new ResourceIconResponse();

engine/schema/src/main/resources/META-INF/db/views/cloud.template_view.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ SELECT
4141
`vm_template`.`guest_os_id` AS `guest_os_id`,
4242
`guest_os`.`uuid` AS `guest_os_uuid`,
4343
`guest_os`.`display_name` AS `guest_os_name`,
44+
`guest_os`.`category_id` AS `guest_os_category_id`,
4445
`vm_template`.`bootable` AS `bootable`,
4546
`vm_template`.`prepopulate` AS `prepopulate`,
4647
`vm_template`.`cross_zones` AS `cross_zones`,

0 commit comments

Comments
 (0)