From f972ff2c1459ac06d602689a89dbd5d531de48b4 Mon Sep 17 00:00:00 2001 From: Ignasi Barrera Date: Tue, 9 Jul 2013 22:16:40 +0200 Subject: [PATCH] JCLOUDS-182: List all virtual machines in Abiquo Since Abiquo 2.4, all virtual machines for a user can be retrieved in a single API call. This change removes the strategy that fetched the details of all virtual appliances first (to then get the virtual machines in them), and updates the CloudService to use the single API call. --- .../java/org/jclouds/abiquo/features/CloudApi.java | 14 +++ .../jclouds/abiquo/internal/BaseCloudService.java | 15 ++- .../abiquo/strategy/cloud/ListVirtualMachines.java | 117 --------------------- .../domain/cloud/VirtualMachineLiveApiTest.java | 18 ++++ .../abiquo/features/CloudApiExpectTest.java | 25 +++++ .../abiquo/internal/BaseCloudServiceTest.java | 1 - .../cloud/ListVirtualMachinesLiveApiTest.java | 78 -------------- abiquo/src/test/resources/payloads/all-vms.xml | 27 +++++ 8 files changed, 90 insertions(+), 205 deletions(-) delete mode 100644 abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachines.java delete mode 100644 abiquo/src/test/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachinesLiveApiTest.java create mode 100644 abiquo/src/test/resources/payloads/all-vms.xml diff --git a/abiquo/src/main/java/org/jclouds/abiquo/features/CloudApi.java b/abiquo/src/main/java/org/jclouds/abiquo/features/CloudApi.java index c888f66..3906e63 100644 --- a/abiquo/src/main/java/org/jclouds/abiquo/features/CloudApi.java +++ b/abiquo/src/main/java/org/jclouds/abiquo/features/CloudApi.java @@ -60,6 +60,7 @@ import org.jclouds.rest.annotations.JAXBResponseParser; import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.SinceApiVersion; import org.jclouds.rest.binders.BindToXMLPayload; import com.abiquo.model.transport.AcceptedRequestDto; @@ -620,6 +621,19 @@ public interface CloudApi extends Closeable { /*********************** Virtual Machine ***********************/ /** + * List all virtual machines available to the current user. + * + * @return The list of all virtual machines available to the current user. + */ + @SinceApiVersion("2.4") + @Named("vm:listall") + @GET + @Path("/virtualmachines") + @Consumes(VirtualMachinesWithNodeExtendedDto.BASE_MEDIA_TYPE) + @JAXBResponseParser + VirtualMachinesWithNodeExtendedDto listAllVirtualMachines(); + + /** * List all virtual machines for a virtual appliance. * * @param virtualAppliance diff --git a/abiquo/src/main/java/org/jclouds/abiquo/internal/BaseCloudService.java b/abiquo/src/main/java/org/jclouds/abiquo/internal/BaseCloudService.java index 6d0ca53..1ef28af 100644 --- a/abiquo/src/main/java/org/jclouds/abiquo/internal/BaseCloudService.java +++ b/abiquo/src/main/java/org/jclouds/abiquo/internal/BaseCloudService.java @@ -34,10 +34,10 @@ import org.jclouds.abiquo.features.services.CloudService; import org.jclouds.abiquo.reference.ValidationErrors; import org.jclouds.abiquo.strategy.cloud.ListVirtualAppliances; import org.jclouds.abiquo.strategy.cloud.ListVirtualDatacenters; -import org.jclouds.abiquo.strategy.cloud.ListVirtualMachines; import org.jclouds.rest.ApiContext; import com.abiquo.server.core.cloud.VirtualDatacenterDto; +import com.abiquo.server.core.cloud.VirtualMachinesWithNodeExtendedDto; import com.google.common.annotations.VisibleForTesting; /** @@ -49,24 +49,20 @@ import com.google.common.annotations.VisibleForTesting; @Singleton public class BaseCloudService implements CloudService { @VisibleForTesting - protected ApiContext context; + protected final ApiContext context; @VisibleForTesting protected final ListVirtualDatacenters listVirtualDatacenters; @VisibleForTesting - protected ListVirtualAppliances listVirtualAppliances; - - @VisibleForTesting - protected ListVirtualMachines listVirtualMachines; + protected final ListVirtualAppliances listVirtualAppliances; @Inject protected BaseCloudService(final ApiContext context, final ListVirtualDatacenters listVirtualDatacenters, - final ListVirtualAppliances listVirtualAppliances, final ListVirtualMachines listVirtualMachines) { + final ListVirtualAppliances listVirtualAppliances) { this.context = checkNotNull(context, "context"); this.listVirtualDatacenters = checkNotNull(listVirtualDatacenters, "listVirtualDatacenters"); this.listVirtualAppliances = checkNotNull(listVirtualAppliances, "listVirtualAppliances"); - this.listVirtualMachines = checkNotNull(listVirtualMachines, "listVirtualMachines"); } /*********************** Virtual Datacenter ********************** */ @@ -108,6 +104,7 @@ public class BaseCloudService implements CloudService { @Override public Iterable listVirtualMachines() { - return listVirtualMachines.execute(); + VirtualMachinesWithNodeExtendedDto vms = context.getApi().getCloudApi().listAllVirtualMachines(); + return wrap(context, VirtualMachine.class, vms.getCollection()); } } diff --git a/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachines.java b/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachines.java deleted file mode 100644 index aeb8ac0..0000000 --- a/abiquo/src/main/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachines.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.abiquo.strategy.cloud; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.filter; -import static com.google.common.collect.Iterables.transform; -import static com.google.common.util.concurrent.Futures.allAsList; -import static com.google.common.util.concurrent.Futures.getUnchecked; -import static org.jclouds.abiquo.domain.DomainWrapper.wrap; - -import java.util.List; -import java.util.concurrent.Callable; - -import javax.annotation.Resource; -import javax.inject.Named; - -import org.jclouds.Constants; -import org.jclouds.abiquo.AbiquoApi; -import org.jclouds.abiquo.domain.DomainWrapper; -import org.jclouds.abiquo.domain.cloud.VirtualAppliance; -import org.jclouds.abiquo.domain.cloud.VirtualMachine; -import org.jclouds.abiquo.domain.cloud.options.VirtualMachineOptions; -import org.jclouds.abiquo.strategy.ListRootEntities; -import org.jclouds.logging.Logger; -import org.jclouds.rest.ApiContext; - -import com.abiquo.server.core.cloud.VirtualMachineWithNodeExtendedDto; -import com.abiquo.server.core.cloud.VirtualMachinesWithNodeExtendedDto; -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.inject.Inject; -import com.google.inject.Singleton; - -/** - * List virtual machines in each virtual datacenter and each virtual appliance. - * - * @author Ignasi Barrera - */ -@Singleton -public class ListVirtualMachines implements ListRootEntities { - protected final ApiContext context; - - protected final ListeningExecutorService userExecutor; - - protected final ListVirtualAppliances listVirtualAppliances; - - @Resource - protected Logger logger = Logger.NULL; - - @Inject - ListVirtualMachines(final ApiContext context, - @Named(Constants.PROPERTY_USER_THREADS) final ListeningExecutorService userExecutor, - final ListVirtualAppliances listVirtualAppliances) { - super(); - this.context = checkNotNull(context, "context"); - this.listVirtualAppliances = checkNotNull(listVirtualAppliances, "listVirtualAppliances"); - this.userExecutor = checkNotNull(userExecutor, "userExecutor"); - } - - @Override - public Iterable execute() { - return execute(userExecutor); - } - - public Iterable execute(ListeningExecutorService executor) { - return execute(executor, VirtualMachineOptions.builder().disablePagination().build()); - } - - public Iterable execute(ListeningExecutorService executor, final Predicate selector) { - return filter(execute(executor), selector); - } - - public Iterable execute(ListeningExecutorService executor, final VirtualMachineOptions options) { - // Find virtual machines in concurrent requests - Iterable vapps = listVirtualAppliances.execute(executor); - Iterable vms = listConcurrentVirtualMachines(executor, vapps, options); - - return wrap(context, VirtualMachine.class, vms); - } - - private Iterable listConcurrentVirtualMachines( - final ListeningExecutorService executor, final Iterable vapps, - final VirtualMachineOptions options) { - ListenableFuture> futures = allAsList(transform(vapps, - new Function>() { - @Override - public ListenableFuture apply(final VirtualAppliance input) { - return executor.submit(new Callable() { - @Override - public VirtualMachinesWithNodeExtendedDto call() throws Exception { - return context.getApi().getCloudApi().listVirtualMachines(input.unwrap(), options); - } - }); - } - })); - - logger.trace("getting virtual machines"); - return DomainWrapper.join(getUnchecked(futures)); - } -} diff --git a/abiquo/src/test/java/org/jclouds/abiquo/domain/cloud/VirtualMachineLiveApiTest.java b/abiquo/src/test/java/org/jclouds/abiquo/domain/cloud/VirtualMachineLiveApiTest.java index 7623675..d838438 100644 --- a/abiquo/src/test/java/org/jclouds/abiquo/domain/cloud/VirtualMachineLiveApiTest.java +++ b/abiquo/src/test/java/org/jclouds/abiquo/domain/cloud/VirtualMachineLiveApiTest.java @@ -16,12 +16,15 @@ */ package org.jclouds.abiquo.domain.cloud; +import static com.google.common.collect.Iterables.find; +import static com.google.common.collect.Iterables.size; import static org.jclouds.abiquo.reference.AbiquoTestConstants.PREFIX; import static org.jclouds.abiquo.util.Assert.assertHasError; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; import java.util.List; @@ -36,6 +39,7 @@ import org.testng.annotations.Test; import com.abiquo.server.core.cloud.VirtualMachineDto; import com.abiquo.server.core.cloud.VirtualMachineState; +import com.google.common.base.Predicate; /** * Live integration tests for the {@link VirtualMachine} domain class. @@ -44,6 +48,20 @@ import com.abiquo.server.core.cloud.VirtualMachineState; */ @Test(groups = "api", testName = "VirtualMachineLiveApiTest") public class VirtualMachineLiveApiTest extends BaseAbiquoApiLiveApiTest { + public void testListAllVirtualMachines() { + Iterable vms = env.context.getCloudService().listVirtualMachines(); + assertTrue(size(vms) > 1); + + // Verify that the VM created in the setup exists. This call will throw + // a NoSuchElementException if no macthing VM is found + find(vms, new Predicate() { + @Override + public boolean apply(VirtualMachine input) { + return input.getId().equals(env.virtualMachine.getId()); + } + }); + } + public void testHasDataFromNode() { assertNotNull(env.virtualMachine.getNameLabel()); assertNotNull(env.virtualMachine.getInternalName()); diff --git a/abiquo/src/test/java/org/jclouds/abiquo/features/CloudApiExpectTest.java b/abiquo/src/test/java/org/jclouds/abiquo/features/CloudApiExpectTest.java index 57f7cf6..57da385 100644 --- a/abiquo/src/test/java/org/jclouds/abiquo/features/CloudApiExpectTest.java +++ b/abiquo/src/test/java/org/jclouds/abiquo/features/CloudApiExpectTest.java @@ -18,6 +18,7 @@ */ package org.jclouds.abiquo.features; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import java.net.URI; @@ -31,6 +32,7 @@ import com.abiquo.model.rest.RESTLink; import com.abiquo.model.transport.AcceptedRequestDto; import com.abiquo.server.core.cloud.VirtualMachineDto; import com.abiquo.server.core.cloud.VirtualMachineInstanceDto; +import com.abiquo.server.core.cloud.VirtualMachinesWithNodeExtendedDto; /** * Expect tests for the {@link CloudApi} class. @@ -40,6 +42,29 @@ import com.abiquo.server.core.cloud.VirtualMachineInstanceDto; @Test(groups = "unit", testName = "CloudApiExpectTest") public class CloudApiExpectTest extends BaseAbiquoApiExpectTest { + public void testListAllVirtualMachinesWhenResponseIs2xx() { + CloudApi api = requestSendsResponse( + HttpRequest.builder() // + .method("GET") // + .endpoint(URI.create("http://localhost/api/cloud/virtualmachines")) // + .addHeader("Authorization", basicAuth) // + .addHeader("Accept", normalize(VirtualMachinesWithNodeExtendedDto.MEDIA_TYPE)) // + .build(), + HttpResponse + .builder() + .statusCode(200) + .payload( + payloadFromResourceWithContentType("/payloads/all-vms.xml", + normalize(VirtualMachinesWithNodeExtendedDto.MEDIA_TYPE))) // + .build()); + + VirtualMachinesWithNodeExtendedDto vms = api.listAllVirtualMachines(); + assertEquals(vms.getCollection().size(), 1); + assertEquals(vms.getCollection().get(0).getId(), Integer.valueOf(1)); + assertEquals(vms.getCollection().get(0).getName(), "VM"); + assertNotNull(vms.getCollection().get(0).getEditLink()); + } + public void testSnapshotVirtualMachineReturns2xx() { CloudApi api = requestSendsResponse( HttpRequest diff --git a/abiquo/src/test/java/org/jclouds/abiquo/internal/BaseCloudServiceTest.java b/abiquo/src/test/java/org/jclouds/abiquo/internal/BaseCloudServiceTest.java index ff95403..54f656b 100644 --- a/abiquo/src/test/java/org/jclouds/abiquo/internal/BaseCloudServiceTest.java +++ b/abiquo/src/test/java/org/jclouds/abiquo/internal/BaseCloudServiceTest.java @@ -35,6 +35,5 @@ public class BaseCloudServiceTest extends BaseInjectionTest { assertNotNull(service.context); assertNotNull(service.listVirtualDatacenters); assertNotNull(service.listVirtualAppliances); - assertNotNull(service.listVirtualMachines); } } diff --git a/abiquo/src/test/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachinesLiveApiTest.java b/abiquo/src/test/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachinesLiveApiTest.java deleted file mode 100644 index a5aed62..0000000 --- a/abiquo/src/test/java/org/jclouds/abiquo/strategy/cloud/ListVirtualMachinesLiveApiTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.abiquo.strategy.cloud; - -import static com.google.common.collect.Iterables.size; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; - -import java.util.List; - -import org.jclouds.abiquo.domain.cloud.VirtualMachine; -import org.jclouds.abiquo.strategy.BaseAbiquoStrategyLiveApiTest; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import com.google.common.collect.Lists; - -/** - * Live tests for the {@link ListVirtualMachines} strategy. - * - * @author Ignasi Barrera - */ -@Test(groups = "api", testName = "ListVirtualMachinesLiveApiTest") -public class ListVirtualMachinesLiveApiTest extends BaseAbiquoStrategyLiveApiTest { - private ListVirtualMachines strategy; - - @Override - @BeforeClass(groups = "api") - protected void setupStrategy() { - this.strategy = env.context.utils().injector().getInstance(ListVirtualMachines.class); - } - - public void testExecute() { - Iterable vms = strategy.execute(); - assertNotNull(vms); - assertTrue(size(vms) > 0); - } - - public void testExecuteWhenExceedsPagination() { - List vms = Lists.newArrayList(); - - // Pagination by default is set to 25 items per page, so create a few more - // to verify that - // all are returned when listing - int numVms = 30; - - for (int i = 0; i < numVms; i++) { - VirtualMachine vm = VirtualMachine.Builder.fromVirtualMachine(env.virtualMachine).build(); - vm.save(); - vms.add(vm); - } - - try { - Iterable all = strategy.execute(); - - assertNotNull(all); - assertTrue(size(all) >= numVms); - } finally { - for (VirtualMachine vm : vms) { - vm.delete(); - } - } - } -} diff --git a/abiquo/src/test/resources/payloads/all-vms.xml b/abiquo/src/test/resources/payloads/all-vms.xml new file mode 100644 index 0000000..329f202 --- /dev/null +++ b/abiquo/src/test/resources/payloads/all-vms.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + 0 + 0 + 0 + 1 + 0 + 0 + VM + 0 + 0 + + \ No newline at end of file -- 1.7.12.4 (Apple Git-37)