CLOUDSTACK-6052: List VM enhancement to support querying with multiple VM IDs New parameter 'ids' added to listVirtualMachine API. The syntax looks like http://localhost:8096/api?command=listVirtualMachines&listAll=true&ids=eddac053-9b12-4d2e-acb7-233de2e98112,009966fc-4d7b-4f84-8609-254979ba0134 The new parameter will be mutually exclusive with the existing 'id' parameter.
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/5779292e Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5779292e Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5779292e Branch: refs/heads/resize-root Commit: 5779292e93fe52a7fb5ec0abffe1e3f6b9c10121 Parents: bc4c805 Author: Koushik Das <[email protected]> Authored: Tue Mar 11 11:49:13 2014 +0530 Committer: Koushik Das <[email protected]> Committed: Thu Mar 13 17:05:35 2014 +0530 ---------------------------------------------------------------------- .../api/command/user/vm/ListVMsCmd.java | 8 +++ .../com/cloud/api/query/QueryManagerImpl.java | 20 ++++++-- test/integration/smoke/test_deploy_vm.py | 52 +++++++++++++++++++- 3 files changed, 76 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5779292e/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java ---------------------------------------------------------------------- diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java index 1a564f6..1ba2b23 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java @@ -64,6 +64,10 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd { @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserVmResponse.class, description = "the ID of the virtual machine") private Long id; + @Parameter(name=ApiConstants.IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=UserVmResponse.class, + description="the IDs of the virtual machines, mutually exclusive with id") + private List<Long> ids; + @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "name of the virtual machine") private String name; @@ -135,6 +139,10 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd { return id; } + public List<Long> getIds() { + return ids; + } + public String getName() { return name; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5779292e/server/src/com/cloud/api/query/QueryManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 4200799..47d2aec 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -728,11 +728,22 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { Boolean isRecursive = domainIdRecursiveListProject.second(); ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + List<Long> ids = null; + if (cmd.getId() != null) { + if (cmd.getIds() != null && !cmd.getIds().isEmpty()) { + throw new InvalidParameterValueException("Specify either id or ids but not both parameters"); + } + ids = new ArrayList<Long>(); + ids.add(cmd.getId()); + } else { + ids = cmd.getIds(); + } + Criteria c = new Criteria("id", Boolean.TRUE, cmd.getStartIndex(), cmd.getPageSizeVal()); // Criteria c = new Criteria(null, Boolean.FALSE, cmd.getStartIndex(), // cmd.getPageSizeVal()); //version without default sorting c.addCriteria(Criteria.KEYWORD, cmd.getKeyword()); - c.addCriteria(Criteria.ID, cmd.getId()); + c.addCriteria(Criteria.ID, ids); c.addCriteria(Criteria.NAME, cmd.getName()); c.addCriteria(Criteria.STATE, cmd.getState()); c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId()); @@ -805,7 +816,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { Object display = c.getCriteria(Criteria.DISPLAY); sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE); - sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN); sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); sb.and("stateEQ", sb.entity().getState(), SearchCriteria.Op.EQ); sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ); @@ -889,7 +900,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } if (id != null) { - sc.setParameters("id", id); + List<?> idList = (id instanceof List<?> ? (List<?>)id : null); + if (idList != null && !idList.isEmpty()) { + sc.setParameters("idIN", idList.toArray()); + } } if (templateId != null) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5779292e/test/integration/smoke/test_deploy_vm.py ---------------------------------------------------------------------- diff --git a/test/integration/smoke/test_deploy_vm.py b/test/integration/smoke/test_deploy_vm.py index 425aeb7..fcde229 100644 --- a/test/integration/smoke/test_deploy_vm.py +++ b/test/integration/smoke/test_deploy_vm.py @@ -51,6 +51,11 @@ class TestData(object): "name" : "testvm", "displayname" : "Test VM", }, + #data reqd for virtual machine creation + "virtual_machine2" : { + "name" : "testvm2", + "displayname" : "Test VM2", + }, #small service offering "service_offering": { "small": { @@ -149,8 +154,53 @@ class TestDeployVM(cloudstackTestCase): msg="VM is not in Running state" ) + @attr(tags = ['advanced', 'simulator', 'basic', 'sg']) + def test_deploy_vm_multiple(self): + """Test Multiple Deploy Virtual Machine + + # Validate the following: + # 1. deploy 2 virtual machines + # 2. listVirtualMachines using 'ids' parameter returns accurate information + """ + self.virtual_machine = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id + ) + + self.virtual_machine2 = VirtualMachine.create( + self.apiclient, + self.testdata["virtual_machine2"], + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + templateid=self.template.id + ) + + list_vms = VirtualMachine.list(self.apiclient, ids=[self.virtual_machine.id, self.virtual_machine2.id], listAll=True) + self.debug( + "Verify listVirtualMachines response for virtual machines: %s, %s" % (self.virtual_machine.id, self.virtual_machine2.id) + ) + + self.assertEqual( + isinstance(list_vms, list), + True, + "List VM response was not a valid list" + ) + self.assertEqual( + len(list_vms), + 2, + "List VM response was empty, expected 2 VMs" + ) + def tearDown(self): try: cleanup_resources(self.apiclient, self.cleanup) except Exception as e: - self.debug("Warning! Exception in tearDown: %s" % e) \ No newline at end of file + self.debug("Warning! Exception in tearDown: %s" % e) +
