diff --git a/labs/abiquo/README.md b/labs/abiquo/README.md index bb545d52b6..cdf6b8489d 100644 --- a/labs/abiquo/README.md +++ b/labs/abiquo/README.md @@ -3,19 +3,8 @@ Jclouds Abiquo Provider This is the jclouds Abiquo provider. It enables compute features for the Abiquo cloud platform. -Documentation -------------- - Detailed information about the Abiquo REST API can be found in the [Abiquo documentation page](http://community.abiquo.com). -All information about building and using the **jclouds-abiquo** provider in your own project -can be found in the [Project Wiki](https://github.com/abiquo/jclouds-abiquo/wiki). - - -Issue Tracking --------------- - -If you find any issue in the provider api, please submit it to the [Bug tracking system](http://jira.abiquo.com/browse/ABIQUOJC) -and we will do our best to fix it. +If you find any issue in the provider api, please submit it to the [Bug tracking system](http://jira.abiquo.com/browse/ABIQUOJC) and we will do our best to fix it. diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/config/AbiquoComputeServiceContextModule.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/config/AbiquoComputeServiceContextModule.java index 4007b0afd6..14dcc708f2 100644 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/config/AbiquoComputeServiceContextModule.java +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/config/AbiquoComputeServiceContextModule.java @@ -20,13 +20,16 @@ package org.jclouds.abiquo.compute.config; import org.jclouds.abiquo.compute.functions.DatacenterToLocation; -import org.jclouds.abiquo.compute.functions.VirtualMachineTemplateToHardware; +import org.jclouds.abiquo.compute.functions.VirtualDatacenterToLocation; import org.jclouds.abiquo.compute.functions.VirtualMachineTemplateToImage; +import org.jclouds.abiquo.compute.functions.VirtualMachineTemplateWithZoneToHardware; import org.jclouds.abiquo.compute.functions.VirtualMachineToNodeMetadata; import org.jclouds.abiquo.compute.options.AbiquoTemplateOptions; import org.jclouds.abiquo.compute.strategy.AbiquoComputeServiceAdapter; +import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; import org.jclouds.abiquo.domain.cloud.VirtualMachine; import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplateWithZone; import org.jclouds.abiquo.domain.infrastructure.Datacenter; import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.config.ComputeServiceAdapterContextModule; @@ -49,7 +52,7 @@ import com.google.inject.TypeLiteral; */ public class AbiquoComputeServiceContextModule extends - ComputeServiceAdapterContextModule + ComputeServiceAdapterContextModule { @Override @@ -57,7 +60,7 @@ public class AbiquoComputeServiceContextModule { super.configure(); bind( - new TypeLiteral>() + new TypeLiteral>() { }).to(AbiquoComputeServiceAdapter.class); bind(new TypeLiteral>() @@ -66,15 +69,18 @@ public class AbiquoComputeServiceContextModule bind(new TypeLiteral>() { }).to(VirtualMachineTemplateToImage.class); - bind(new TypeLiteral>() + bind(new TypeLiteral>() { - }).to(VirtualMachineTemplateToHardware.class); + }).to(VirtualMachineTemplateWithZoneToHardware.class); bind(new TypeLiteral>() { }).to(DatacenterToLocation.class); + bind(new TypeLiteral>() + { + }).to(VirtualDatacenterToLocation.class); bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON); bind(TemplateOptions.class).to(AbiquoTemplateOptions.class); - install(new LocationsFromComputeServiceAdapterModule() + install(new LocationsFromComputeServiceAdapterModule() { }); } diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/DatacenterToLocation.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/DatacenterToLocation.java index e0039fa80b..57a872ea94 100644 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/DatacenterToLocation.java +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/DatacenterToLocation.java @@ -32,6 +32,8 @@ import com.google.common.collect.ImmutableSet; /** * Converts a {@link Datacenter} to a {@link Location} one. + *

+ * Physical datacenters will be considered regions. * * @author Ignasi Barrera */ @@ -46,8 +48,7 @@ public class DatacenterToLocation implements Function builder.id(datacenter.getId().toString()); builder.description(datacenter.getName() + " [" + datacenter.getLocation() + "]"); builder.metadata(ImmutableMap. of()); - builder.scope(LocationScope.ZONE); - // TODO: Convert to ISO3166 code? + builder.scope(LocationScope.REGION); builder.iso3166Codes(ImmutableSet. of()); builder.parent(new LocationBuilder().scope(LocationScope.PROVIDER).id("abiquo") diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualDatacenterToLocation.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualDatacenterToLocation.java new file mode 100644 index 0000000000..d5fb7ff22c --- /dev/null +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualDatacenterToLocation.java @@ -0,0 +1,81 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.compute.functions; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; +import org.jclouds.abiquo.domain.infrastructure.Datacenter; +import org.jclouds.abiquo.reference.rest.ParentLinkName; +import org.jclouds.collect.Memoized; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +/** + * Converts a {@link VirtualDatacenter} to a {@link Location} one. + *

+ * Virtual datacenters will be considered zones, since images will be deployed in a virtual + * datacenter. Each zone will be scoped into a physical datacenter (region). + * + * @author Ignasi Barrera + */ +@Singleton +public class VirtualDatacenterToLocation implements Function +{ + private final Function datacenterToLocation; + + private final Supplier> regionMap; + + @Inject + public VirtualDatacenterToLocation(final Function datacenterToLocation, + @Memoized final Supplier> regionMap) + { + this.datacenterToLocation = checkNotNull(datacenterToLocation, "datacenterToLocation"); + this.regionMap = checkNotNull(regionMap, "regionMap"); + } + + @Override + public Location apply(final VirtualDatacenter vdc) + { + LocationBuilder builder = new LocationBuilder(); + builder.id(vdc.getId().toString()); + builder.description(vdc.getName()); + builder.metadata(ImmutableMap. of()); + builder.scope(LocationScope.ZONE); + builder.iso3166Codes(ImmutableSet. of()); + + Datacenter parent = + regionMap.get().get(vdc.unwrap().getIdFromLink(ParentLinkName.DATACENTER)); + builder.parent(datacenterToLocation.apply(parent)); + + return builder.build(); + } +} diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualMachineStateToNodeState.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualMachineStateToNodeState.java index 806c6ef616..f7c8c951e5 100644 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualMachineStateToNodeState.java +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualMachineStateToNodeState.java @@ -43,15 +43,13 @@ public class VirtualMachineStateToNodeState implements Function + * Images are scoped to a region (physical datacenter). * * @author Ignasi Barrera */ @Singleton public class VirtualMachineTemplateToImage implements Function { + private final Function datacenterToLocation; + + private final Supplier> regionMap; + + @Inject + public VirtualMachineTemplateToImage(final Function datacenterToLocation, + @Memoized final Supplier> reginoMap) + { + this.datacenterToLocation = checkNotNull(datacenterToLocation, "datacenterToLocation"); + this.regionMap = checkNotNull(reginoMap, "reginoMap"); + } @Override public Image apply(final VirtualMachineTemplate template) @@ -49,6 +71,11 @@ public class VirtualMachineTemplateToImage implements Function + * Each {@link Image} ({@link VirtualMachineTemplate}) will have one {@link Hardware} entity for + * each zone (scoped to a virtualization technology) supported by the image. * * @author Ignasi Barrera */ @Singleton -public class VirtualMachineTemplateToHardware implements Function +public class VirtualMachineTemplateWithZoneToHardware implements + Function { /** The default core speed, 2.0Ghz. */ public static final double DEFAULT_CORE_SPEED = 2.0; - @Override - public Hardware apply(final VirtualMachineTemplate template) + private final Function virtualDatacenterToLocation; + + @Inject + public VirtualMachineTemplateWithZoneToHardware( + final Function virtualDatacenterToLocation) { + this.virtualDatacenterToLocation = + checkNotNull(virtualDatacenterToLocation, "virtualDatacenterToLocation"); + } + + @Override + public Hardware apply(final VirtualMachineTemplateWithZone templateWithZone) + { + VirtualMachineTemplate template = templateWithZone.getTemplate(); + VirtualDatacenter zone = templateWithZone.getZone(); + HardwareBuilder builder = new HardwareBuilder(); - builder.ids(template.getId().toString()); + builder.providerId(template.getId().toString()); + builder.id(template.getId().toString() + "-" + zone.getId()); builder.uri(template.getURI()); builder.name(template.getName()); builder.processor(new Processor(template.getCpuRequired(), DEFAULT_CORE_SPEED)); builder.ram(template.getRamRequired()); - // Currently we consider each template as a hardware profile + // Location information + builder.location(virtualDatacenterToLocation.apply(zone)); + builder.hypervisor(zone.getHypervisorType().name()); builder.supportsImage(ImagePredicates.idEquals(template.getId().toString())); VolumeBuilder volumeBuilder = new VolumeBuilder(); diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualMachineToNodeMetadata.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualMachineToNodeMetadata.java index b7cbe8cd8e..5582e23c9d 100644 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualMachineToNodeMetadata.java +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/functions/VirtualMachineToNodeMetadata.java @@ -32,7 +32,7 @@ import javax.inject.Singleton; import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; import org.jclouds.abiquo.domain.cloud.VirtualMachine; import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; -import org.jclouds.abiquo.domain.infrastructure.Datacenter; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplateWithZone; import org.jclouds.abiquo.domain.network.Ip; import org.jclouds.abiquo.domain.network.PrivateIp; import org.jclouds.compute.domain.Hardware; @@ -41,12 +41,13 @@ import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.Processor; +import org.jclouds.domain.Location; import org.jclouds.logging.Logger; -import org.jclouds.rest.AuthorizationException; import com.abiquo.server.core.cloud.VirtualMachineState; import com.google.common.base.Function; import com.google.common.base.Predicates; +import com.google.common.collect.Lists; /** * Links a {@link VirtualMachine} object to a {@link NodeMetadata} one. @@ -61,18 +62,18 @@ public class VirtualMachineToNodeMetadata implements Function virtualDatacenterToLocation; @Inject public VirtualMachineToNodeMetadata( final VirtualMachineTemplateToImage virtualMachineTemplateToImage, - final VirtualMachineTemplateToHardware virtualMachineTemplateToHardware, + final VirtualMachineTemplateWithZoneToHardware virtualMachineTemplateToHardware, final VirtualMachineStateToNodeState virtualMachineStateToNodeState, - final DatacenterToLocation datacenterToLocation) + final Function virtualDatacenterToLocation) { this.virtualMachineTemplateToImage = checkNotNull(virtualMachineTemplateToImage, "virtualMachineTemplateToImage"); @@ -80,7 +81,8 @@ public class VirtualMachineToNodeMetadata implements Function[] ips; - - private UnmanagedNetwork[] unmanagedIps; - - private Network< ? > gatewayNetwork; - @Override public TemplateOptions clone() { @@ -69,8 +58,6 @@ public class AbiquoTemplateOptions extends TemplateOptions implements Cloneable options.overrideCores(overrideCores); options.overrideRam(overrideRam); options.vncPassword(vncPassword); - options.virtualDatacenter(virtualDatacenter); - options.ips(ips); } } @@ -124,71 +111,6 @@ public class AbiquoTemplateOptions extends TemplateOptions implements Cloneable return vncPassword; } - /** - * Set the virtual datacenter where the virtual machine must be deployed. - * - * @return The template options with the virtual machine must be deployed. - */ - public AbiquoTemplateOptions virtualDatacenter(final String virtualDatacenter) - { - this.virtualDatacenter = virtualDatacenter; - return this; - } - - public String getVirtualDatacenter() - { - return virtualDatacenter; - } - - /** - * Set the ip addresses for the virtual machine. - * - * @return The template options with the ip addresses configuration. - */ - public AbiquoTemplateOptions ips(final Ip< ? , ? >... ips) - { - this.ips = ips; - return this; - } - - public Ip< ? , ? >[] getIps() - { - return ips; - } - - /** - * Set the ip addresses that must be selected from unmanaged networks. - * - * @return The template options with the ip addresses that must be selected from unmanaged - * networks. - */ - public AbiquoTemplateOptions unmanagedIps(final UnmanagedNetwork... unmanagedIps) - { - this.unmanagedIps = unmanagedIps; - return this; - } - - public UnmanagedNetwork[] getUnmanagedIps() - { - return unmanagedIps; - } - - /** - * Set the gateway network for the virtual machine. - * - * @return The template options with the gateway network configuration. - */ - public AbiquoTemplateOptions gatewayNetwork(final Network< ? > gatewayNetwork) - { - this.gatewayNetwork = gatewayNetwork; - return this; - } - - public Network< ? > getGatewayNetwork() - { - return gatewayNetwork; - } - public static class Builder { /** @@ -217,41 +139,5 @@ public class AbiquoTemplateOptions extends TemplateOptions implements Cloneable AbiquoTemplateOptions options = new AbiquoTemplateOptions(); return options.vncPassword(vncPassword); } - - /** - * @see AbiquoTemplateOptions#virtualDatacenter(String) - */ - public static AbiquoTemplateOptions virtualDatacenter(final String virtualDatacenter) - { - AbiquoTemplateOptions options = new AbiquoTemplateOptions(); - return options.virtualDatacenter(virtualDatacenter); - } - - /** - * @see AbiquoTemplateOptions#ips(Ip...) - */ - public static AbiquoTemplateOptions ips(final Ip< ? , ? >... ips) - { - AbiquoTemplateOptions options = new AbiquoTemplateOptions(); - return options.ips(ips); - } - - /** - * @see AbiquoTemplateOptions#unmanagedIps(UnmanagedNetwork...) - */ - public AbiquoTemplateOptions unmanagedIps(final UnmanagedNetwork... unmanagedIps) - { - AbiquoTemplateOptions options = new AbiquoTemplateOptions(); - return options.unmanagedIps(unmanagedIps); - } - - /** - * @see AbiquoTemplateOptions#gatewayNetwork(Network) - */ - public static AbiquoTemplateOptions gatewayNetwork(final Network< ? > gatewayNetwork) - { - AbiquoTemplateOptions options = new AbiquoTemplateOptions(); - return options.gatewayNetwork(gatewayNetwork); - } } } diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/AbiquoComputeServiceAdapter.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/AbiquoComputeServiceAdapter.java index b8f0e5247e..a21b80fe81 100644 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/AbiquoComputeServiceAdapter.java +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/AbiquoComputeServiceAdapter.java @@ -20,11 +20,13 @@ package org.jclouds.abiquo.compute.strategy; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Iterables.transform; -import java.util.Arrays; +import java.util.List; +import java.util.Map; import javax.annotation.Resource; -import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; @@ -35,16 +37,18 @@ import org.jclouds.abiquo.domain.cloud.VirtualAppliance; import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; import org.jclouds.abiquo.domain.cloud.VirtualMachine; import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplateWithZone; import org.jclouds.abiquo.domain.enterprise.Enterprise; -import org.jclouds.abiquo.domain.enterprise.User; import org.jclouds.abiquo.domain.infrastructure.Datacenter; +import org.jclouds.abiquo.domain.network.PublicIp; import org.jclouds.abiquo.features.services.AdministrationService; import org.jclouds.abiquo.features.services.CloudService; import org.jclouds.abiquo.features.services.MonitoringService; import org.jclouds.abiquo.monitor.VirtualMachineMonitor; import org.jclouds.abiquo.predicates.cloud.VirtualAppliancePredicates; import org.jclouds.abiquo.predicates.cloud.VirtualMachineTemplatePredicates; -import org.jclouds.abiquo.predicates.infrastructure.DatacenterPredicates; +import org.jclouds.abiquo.predicates.network.IpPredicates; +import org.jclouds.collect.Memoized; import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.domain.Hardware; @@ -55,7 +59,11 @@ import org.jclouds.logging.Logger; import org.jclouds.rest.RestContext; import com.abiquo.server.core.cloud.VirtualMachineState; +import com.google.common.base.Function; import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.collect.Lists; +import com.google.inject.Inject; /** * Defines the connection between the {@link AbiquoApi} implementation and the jclouds @@ -66,7 +74,7 @@ import com.google.common.base.Predicate; @Singleton public class AbiquoComputeServiceAdapter implements - ComputeServiceAdapter + ComputeServiceAdapter { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) @@ -80,19 +88,24 @@ public class AbiquoComputeServiceAdapter private final MonitoringService monitoringService; - private AbiquoComputeServiceHelper helper; + private final FindCompatibleVirtualDatacenters compatibleVirtualDatacenters; + + private final Supplier> regionMap; @Inject public AbiquoComputeServiceAdapter(final RestContext context, final AdministrationService adminService, final CloudService cloudService, - final MonitoringService monitoringService, final AbiquoComputeServiceHelper helper) + final MonitoringService monitoringService, + final FindCompatibleVirtualDatacenters compatibleVirtualDatacenters, + @Memoized final Supplier> regionMap) { - super(); this.context = checkNotNull(context, "context"); this.adminService = checkNotNull(adminService, "adminService"); this.cloudService = checkNotNull(cloudService, "cloudService"); this.monitoringService = checkNotNull(monitoringService, "monitoringService"); - this.helper = checkNotNull(helper, "helper"); + this.compatibleVirtualDatacenters = + checkNotNull(compatibleVirtualDatacenters, "compatibleVirtualDatacenters"); + this.regionMap = checkNotNull(regionMap, "regionMap"); } @Override @@ -100,23 +113,23 @@ public class AbiquoComputeServiceAdapter final String tag, final String name, final Template template) { AbiquoTemplateOptions options = template.getOptions().as(AbiquoTemplateOptions.class); - - User user = adminService.getCurrentUser(); Enterprise enterprise = adminService.getCurrentEnterprise(); + // Get the region where the template is available Datacenter datacenter = - enterprise.findAllowedDatacenter(DatacenterPredicates.id(Integer.valueOf(template - .getLocation().getId()))); + regionMap.get().get(Integer.valueOf(template.getImage().getLocation().getId())); + // Load the template VirtualMachineTemplate virtualMachineTemplate = enterprise.getTemplateInRepository(datacenter, Integer.valueOf(template.getImage().getId())); + // Get the zone where the template will be deployed VirtualDatacenter vdc = - helper.getOrCreateVirtualDatacenter(user, enterprise, datacenter, - virtualMachineTemplate, options); + cloudService.getVirtualDatacenter(Integer.valueOf(template.getHardware().getLocation() + .getId())); - // Load the virtual appliance or create it + // Load the virtual appliance or create it if it does not exist VirtualAppliance vapp = vdc.findVirtualAppliance(VirtualAppliancePredicates.name(tag)); if (vapp == null) { @@ -137,24 +150,51 @@ public class AbiquoComputeServiceAdapter vm.save(); // Once the virtual machine is created, override the default network settings if needed - helper.configureNetwork(vm, options.getGatewayNetwork(), options.getIps() == null ? null - : Arrays.asList(options.getIps()), - options.getUnmanagedIps() == null ? null : Arrays.asList(options.getUnmanagedIps())); + // If no public ip is available in the virtual datacenter, the virtual machine will be + // assigned by default an ip address in the default private VLAN for the virtual datacenter + PublicIp publicIp = vdc.findPurchasedPublicIp(IpPredicates. notUsed()); + if (publicIp != null) + { + List ips = Lists.newArrayList(); + ips.add(publicIp); + vm.setNics(ips); + } - VirtualMachineMonitor monitor = monitoringService.getVirtualMachineMonitor(); + // This is an async operation, but jclouds already waits until the node is RUNNING, so there + // is no need to block here vm.deploy(); - monitor.awaitCompletionDeploy(vm); - return new NodeAndInitialCredentials(vm, vm.getId().toString(), template - .getImage().getDefaultCredentials()); + return new NodeAndInitialCredentials(vm, vm.getId().toString(), null); } @Override - public Iterable listHardwareProfiles() + public Iterable listHardwareProfiles() { - // Abiquo does not have the hardwre profiles concept. Users can consume CPU and RAM - // resources limited only by the Enterprise or Virtual datacenter limits. - return listImages(); + // In Abiquo, images are scoped to a region (physical datacenter), and hardware profiles are + // scoped to a zone (a virtual datacenter in the region, with a concrete virtualization + // technology) + + return concat(transform(listImages(), + new Function>() + { + @Override + public Iterable apply( + final VirtualMachineTemplate template) + { + Iterable compatibleZones = + compatibleVirtualDatacenters.execute(template); + + return transform(compatibleZones, + new Function() + { + @Override + public VirtualMachineTemplateWithZone apply(final VirtualDatacenter vdc) + { + return new VirtualMachineTemplateWithZone(template, vdc); + } + }); + } + })); } @Override @@ -172,17 +212,14 @@ public class AbiquoComputeServiceAdapter } @Override - public Iterable listLocations() + public Iterable listLocations() { - Enterprise enterprise = adminService.getCurrentEnterprise(); - return enterprise.listAllowedDatacenters(); + return cloudService.listVirtualDatacenters(); } @Override public VirtualMachine getNode(final String id) { - // FIXME: Try to avoid calling the cloudService.findVirtualMachine. Navigate the hierarchy - // instead. return cloudService.findVirtualMachine(vmId(id)); } diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/AbiquoComputeServiceHelper.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/AbiquoComputeServiceHelper.java deleted file mode 100644 index 289b39c9e1..0000000000 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/AbiquoComputeServiceHelper.java +++ /dev/null @@ -1,256 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds 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.compute.strategy; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.filter; -import static com.google.common.collect.Iterables.find; -import static com.google.common.collect.Iterables.getFirst; - -import java.util.List; - -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.abiquo.AbiquoApi; -import org.jclouds.abiquo.AbiquoAsyncApi; -import org.jclouds.abiquo.compute.exception.NotEnoughResourcesException; -import org.jclouds.abiquo.compute.options.AbiquoTemplateOptions; -import org.jclouds.abiquo.domain.cloud.Conversion; -import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; -import org.jclouds.abiquo.domain.cloud.VirtualMachine; -import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; -import org.jclouds.abiquo.domain.enterprise.Enterprise; -import org.jclouds.abiquo.domain.enterprise.User; -import org.jclouds.abiquo.domain.exception.AbiquoException; -import org.jclouds.abiquo.domain.infrastructure.Datacenter; -import org.jclouds.abiquo.domain.network.Ip; -import org.jclouds.abiquo.domain.network.Network; -import org.jclouds.abiquo.domain.network.PrivateNetwork; -import org.jclouds.abiquo.domain.network.UnmanagedNetwork; -import org.jclouds.abiquo.features.services.CloudService; -import org.jclouds.abiquo.predicates.cloud.VirtualDatacenterPredicates; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.javax.annotation.Nullable; -import org.jclouds.logging.Logger; -import org.jclouds.rest.RestContext; - -import com.abiquo.model.enumerator.ConversionState; -import com.abiquo.model.enumerator.HypervisorType; -import com.google.common.base.Predicate; - -/** - * Helper methods to perform {@link AbiquoComputeServiceAdapter} operations. - * - * @author Ignasi Barrera - */ -@Singleton -public class AbiquoComputeServiceHelper -{ - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private RestContext context; - - private CloudService cloudService; - - @Inject - public AbiquoComputeServiceHelper(final RestContext context, - final CloudService cloudService) - { - super(); - this.context = checkNotNull(context, "context"); - this.cloudService = checkNotNull(cloudService, "cloudService"); - } - - /** - * Gets a virtual datacenter where the given template can be deployed. - *

- * If no compatible virtual datacenter is found, one will be created, if possible. - * - * @param user The current user. - * @param enterprise The enterprise of the current user. - * @param datacenter The datacenter of the template. - * @param template The template to deploy. - * @param options The template options - * @return The virtual datacenter to be used to deploy the template or null if none - * was found and a compatible one could not be created. - */ - public VirtualDatacenter getOrCreateVirtualDatacenter(final User user, - final Enterprise enterprise, final Datacenter datacenter, - final VirtualMachineTemplate template, final AbiquoTemplateOptions options) - { - Iterable compatibles = - findCompatibleVirtualDatacenters(datacenter, template); - - VirtualDatacenter vdc = - options.getVirtualDatacenter() == null ? getFirst(compatibles, null) : find( - compatibles, VirtualDatacenterPredicates.name(options.getVirtualDatacenter())); - - if (vdc == null) - { - vdc = - createCompatibleVirtualDatacenter(user, enterprise, datacenter, template, - options.getVirtualDatacenter()); - if (vdc == null) - { - throw new NotEnoughResourcesException("There are not resources to deploy the given template"); - } - } - - return vdc; - } - - /** - * Find the virtual datacenters compatible with the given template. - * - * @param datacenter The datacenter of the template. - * @param template The template to deploy. - * @return The virtual datacenters compatible with the given template. - */ - public Iterable findCompatibleVirtualDatacenters( - final Datacenter datacenter, final VirtualMachineTemplate template) - { - Iterable vdcs = - cloudService.listVirtualDatacenters(VirtualDatacenterPredicates.datacenter(datacenter)); - - return filter(vdcs, new Predicate() - { - @Override - public boolean apply(final VirtualDatacenter vdc) - { - return isTemplateCompatibleWithHypervisor(template, vdc.getHypervisorType()); - } - }); - } - - /** - * Configure networking resources for the given virtual machine. - * - * @param vm The virtual machine to configure. - * @param gatewayNetwork The network to be used as a gateway. - * @param ips The ips to attach to the virtual machine. - */ - public void configureNetwork(final VirtualMachine vm, - @Nullable final Network< ? > gatewayNetwork, - @Nullable final List>> ips, - @Nullable final List unmanagedIps) - { - if (ips != null) - { - // TODO: External ips don't have the right link - // (http://jira.abiquo.com/browse/ABICLOUDPREMIUM-3650) - - if (gatewayNetwork == null) - { - // By default the network of the first ip will be used as a gateway - vm.setNics(ips, unmanagedIps); - } - else - { - vm.setNics(gatewayNetwork, ips, unmanagedIps); - } - } - } - - /** - * Create a new virtual datacenter compatible with the given template. - * - * @param user The current user. - * @param enterprise The enterprise of the current user. - * @param datacenter The datacenter of the template. - * @param template The template to deploy. - * @return - */ - private VirtualDatacenter createCompatibleVirtualDatacenter(final User user, - final Enterprise enterprise, final Datacenter datacenter, - final VirtualMachineTemplate template, final String name) - { - PrivateNetwork defaultNetwork = - PrivateNetwork.builder(context).name("DefaultNetwork").gateway("192.168.1.1") - .address("192.168.1.0").mask(24).build(); - - VirtualDatacenter vdc = - VirtualDatacenter.builder(context, datacenter, enterprise).network(defaultNetwork) - .build(); - - // Find the first hypervisor in the datacenter compatible with the template - for (HypervisorType type : HypervisorType.values()) - { - if (isTemplateCompatibleWithHypervisor(template, type)) - { - try - { - logger.info("Trying to create a virtual datacenter of type %s", type.name()); - vdc.setName(name != null ? name : "JC-" + type.name()); - vdc.setHypervisorType(type); - vdc.save(); - - logger.info("Virtual datacenter created"); - - return vdc; - } - catch (AbiquoException ex) - { - // Just catch the error thrown when no hypervisors of the given type are - // available in the datacenter - if (ex.hasError("VDC-1")) - { - continue; - } - else - { - throw ex; - } - } - } - } - - logger.warn("Could not create a compatible virtual datacenter for template of type %s", - template.getDiskFormatType().name()); - - return null; - } - - /** - * Check if the given template type is compatible with the given hypervisor type. - * - * @param template The template to check. - * @param type The type of the hypervisor. - * @return Boolean indicating if the given template type is compatible with the given hypervisor - * type. - */ - private static boolean isTemplateCompatibleWithHypervisor( - final VirtualMachineTemplate template, final HypervisorType type) - { - boolean compatible = type.isCompatible(template.getDiskFormatType()); - if (!compatible) - { - List compatibleConversions = - template.listConversions(type, ConversionState.FINISHED); - compatible = compatibleConversions != null && !compatibleConversions.isEmpty(); - } - return compatible; - } - -} diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/exception/NotEnoughResourcesException.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/FindCompatibleVirtualDatacenters.java similarity index 55% rename from labs/abiquo/src/main/java/org/jclouds/abiquo/compute/exception/NotEnoughResourcesException.java rename to labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/FindCompatibleVirtualDatacenters.java index 0ffd63534a..b069f98d79 100644 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/exception/NotEnoughResourcesException.java +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/FindCompatibleVirtualDatacenters.java @@ -17,37 +17,21 @@ * under the License. */ -package org.jclouds.abiquo.compute.exception; +package org.jclouds.abiquo.compute.strategy; + +import org.jclouds.abiquo.compute.strategy.internal.FindCompatibleVirtualDatacentersForImageAndConversions; +import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; + +import com.google.inject.ImplementedBy; /** - * Exception thrown when there are not enough resources in the infrastructure to deploy the desired - * template. + * Finds all virtual datacenters where the given {@link VirtualMachineTemplate} can be deployed. * * @author Ignasi Barrera */ -public class NotEnoughResourcesException extends RuntimeException +@ImplementedBy(FindCompatibleVirtualDatacentersForImageAndConversions.class) +public interface FindCompatibleVirtualDatacenters { - /** Serial UID. */ - private static final long serialVersionUID = 1L; - - public NotEnoughResourcesException() - { - super(); - } - - public NotEnoughResourcesException(final String arg0, final Throwable arg1) - { - super(arg0, arg1); - } - - public NotEnoughResourcesException(final String arg0) - { - super(arg0); - } - - public NotEnoughResourcesException(final Throwable arg0) - { - super(arg0); - } - + Iterable execute(VirtualMachineTemplate template); } diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/internal/FindCompatibleVirtualDatacentersForImageAndConversions.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/internal/FindCompatibleVirtualDatacentersForImageAndConversions.java new file mode 100644 index 0000000000..aee3195b01 --- /dev/null +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/internal/FindCompatibleVirtualDatacentersForImageAndConversions.java @@ -0,0 +1,82 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.compute.strategy.internal; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.filter; +import static org.jclouds.abiquo.domain.DomainWrapper.wrap; +import static org.jclouds.abiquo.predicates.cloud.VirtualDatacenterPredicates.compatibleWithTemplateOrConversions; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.abiquo.AbiquoApi; +import org.jclouds.abiquo.AbiquoAsyncApi; +import org.jclouds.abiquo.compute.strategy.FindCompatibleVirtualDatacenters; +import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; +import org.jclouds.abiquo.domain.infrastructure.Datacenter; +import org.jclouds.abiquo.features.services.CloudService; +import org.jclouds.abiquo.predicates.cloud.VirtualDatacenterPredicates; +import org.jclouds.abiquo.reference.rest.ParentLinkName; +import org.jclouds.rest.RestContext; + +import com.abiquo.server.core.infrastructure.DatacenterDto; + +/** + * Default implementation for the {@link FindCompatibleVirtualDatacenters} strategy. + *

+ * This strategy assumes that the datacenter will have different hypervisor technologies, and images + * will have conversions to each of them. + * + * @author Ignasi Barrera + */ +@Singleton +public class FindCompatibleVirtualDatacentersForImageAndConversions implements + FindCompatibleVirtualDatacenters +{ + private final RestContext context; + + private final CloudService cloudService; + + @Inject + public FindCompatibleVirtualDatacentersForImageAndConversions( + final RestContext context, final CloudService cloudService) + { + this.context = checkNotNull(context, "context"); + this.cloudService = checkNotNull(cloudService, "cloudService"); + } + + @Override + public Iterable execute(final VirtualMachineTemplate template) + { + // Build the transport object with the available information to avoid making an unnecessary + // call to the target API (we only need the id of the datacenter, and it is present in the + // link). + DatacenterDto datacenterDto = new DatacenterDto(); + datacenterDto.setId(template.unwrap().getIdFromLink(ParentLinkName.DATACENTER_REPOSITORY)); + Datacenter datacenter = wrap(context, Datacenter.class, datacenterDto); + + Iterable vdcs = + cloudService.listVirtualDatacenters(VirtualDatacenterPredicates.datacenter(datacenter)); + + return filter(vdcs, compatibleWithTemplateOrConversions(template)); + } + +} diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/internal/FindCompatibleVirtualDatacentersForImageBaseFormat.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/internal/FindCompatibleVirtualDatacentersForImageBaseFormat.java new file mode 100644 index 0000000000..f0e25b73ab --- /dev/null +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/compute/strategy/internal/FindCompatibleVirtualDatacentersForImageBaseFormat.java @@ -0,0 +1,94 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.compute.strategy.internal; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.filter; +import static org.jclouds.abiquo.domain.DomainWrapper.wrap; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.abiquo.AbiquoApi; +import org.jclouds.abiquo.AbiquoAsyncApi; +import org.jclouds.abiquo.compute.strategy.FindCompatibleVirtualDatacenters; +import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; +import org.jclouds.abiquo.domain.infrastructure.Datacenter; +import org.jclouds.abiquo.features.services.CloudService; +import org.jclouds.abiquo.predicates.cloud.VirtualDatacenterPredicates; +import org.jclouds.abiquo.reference.rest.ParentLinkName; +import org.jclouds.rest.RestContext; + +import com.abiquo.model.enumerator.HypervisorType; +import com.abiquo.server.core.infrastructure.DatacenterDto; +import com.google.common.base.Predicate; + +/** + * Implementation for the {@link FindCompatibleVirtualDatacenters} strategy to be used in + * homogeneous datacenters. + *

+ * For providers that only have one hypervisor technology in the physical datacenter and use + * compatible images, there is no need to check if the images have conversions to other formats. + *

+ * This strategy will only consider the base disk format of the image. + * + * @author Ignasi Barrera + */ +@Singleton +public class FindCompatibleVirtualDatacentersForImageBaseFormat implements + FindCompatibleVirtualDatacenters +{ + private final RestContext context; + + private final CloudService cloudService; + + @Inject + public FindCompatibleVirtualDatacentersForImageBaseFormat( + final RestContext context, final CloudService cloudService) + { + this.context = checkNotNull(context, "context"); + this.cloudService = checkNotNull(cloudService, "cloudService"); + } + + @Override + public Iterable execute(final VirtualMachineTemplate template) + { + // Build the transport object with the available information to avoid making an unnecessary + // call to the target API (we only need the id of the datacenter, and it is present in the + // link). + DatacenterDto datacenterDto = new DatacenterDto(); + datacenterDto.setId(template.unwrap().getIdFromLink(ParentLinkName.DATACENTER_REPOSITORY)); + Datacenter datacenter = wrap(context, Datacenter.class, datacenterDto); + + Iterable vdcs = + cloudService.listVirtualDatacenters(VirtualDatacenterPredicates.datacenter(datacenter)); + + return filter(vdcs, new Predicate() + { + @Override + public boolean apply(final VirtualDatacenter vdc) + { + HypervisorType type = vdc.getHypervisorType(); + return type.isCompatible(template.getDiskFormatType()); + } + }); + } + +} diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/config/AbiquoRestClientModule.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/config/AbiquoRestClientModule.java index abe9785ed3..a15e53e931 100644 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/config/AbiquoRestClientModule.java +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/config/AbiquoRestClientModule.java @@ -20,18 +20,20 @@ package org.jclouds.abiquo.config; import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; +import static org.jclouds.abiquo.domain.DomainWrapper.wrap; +import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Named; -import javax.inject.Singleton; import org.jclouds.abiquo.AbiquoApi; import org.jclouds.abiquo.AbiquoAsyncApi; import org.jclouds.abiquo.domain.enterprise.Enterprise; import org.jclouds.abiquo.domain.enterprise.User; +import org.jclouds.abiquo.domain.infrastructure.Datacenter; import org.jclouds.abiquo.features.AdminApi; import org.jclouds.abiquo.features.AdminAsyncApi; import org.jclouds.abiquo.features.CloudApi; @@ -54,8 +56,6 @@ import org.jclouds.abiquo.handlers.AbiquoErrorHandler; import org.jclouds.abiquo.rest.internal.AbiquoHttpAsyncClient; import org.jclouds.abiquo.rest.internal.AbiquoHttpClient; import org.jclouds.abiquo.rest.internal.ExtendedUtils; -import org.jclouds.abiquo.suppliers.GetCurrentEnterprise; -import org.jclouds.abiquo.suppliers.GetCurrentUser; import org.jclouds.collect.Memoized; import org.jclouds.http.HttpErrorHandler; import org.jclouds.http.annotation.ClientError; @@ -63,14 +63,19 @@ import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.ServerError; import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.RestContext; import org.jclouds.rest.Utils; import org.jclouds.rest.config.BinderUtils; import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier; +import org.jclouds.util.Suppliers2; +import com.google.common.base.Function; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.google.inject.Provides; +import com.google.inject.Singleton; /** * Configures the Abiquo connection. @@ -134,10 +139,19 @@ public class AbiquoRestClientModule extends RestClientModule getCurrentUser( final AtomicReference authException, - @Named(PROPERTY_SESSION_INTERVAL) final long seconds, final GetCurrentUser getCurrentUser) + @Named(PROPERTY_SESSION_INTERVAL) final long seconds, + final RestContext context) { return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, - getCurrentUser, seconds, TimeUnit.SECONDS); + new Supplier() + { + @Override + public User get() + { + return wrap(context, User.class, context.getApi().getAdminApi() + .getCurrentUser()); + } + }, seconds, TimeUnit.SECONDS); } @Provides @@ -146,10 +160,54 @@ public class AbiquoRestClientModule extends RestClientModule getCurrentEnterprise( final AtomicReference authException, @Named(PROPERTY_SESSION_INTERVAL) final long seconds, - final GetCurrentEnterprise getCurrentEnterprise) + final @Memoized Supplier currentUser) { return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, - getCurrentEnterprise, seconds, TimeUnit.SECONDS); + new Supplier() + { + @Override + public Enterprise get() + { + return currentUser.get().getEnterprise(); + } + }, seconds, TimeUnit.SECONDS); } + @Provides + @Singleton + @Memoized + public Supplier> getAvailableRegionsIndexedById( + final AtomicReference authException, + @Named(PROPERTY_SESSION_INTERVAL) final long seconds, + @Memoized final Supplier currentEnterprise) + { + Supplier> availableRegionsMapSupplier = + Suppliers2.compose(new Function, Map>() + { + @Override + public Map apply(final List datacenters) + { + // Index available regions by id + return Maps.uniqueIndex(datacenters, new Function() + { + @Override + public Integer apply(final Datacenter input) + { + return input.getId(); + } + }); + } + }, new Supplier>() + { + @Override + public List get() + { + // Get the list of regions available for the user's tenant + return currentEnterprise.get().listAllowedDatacenters(); + } + }); + + return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException, + availableRegionsMapSupplier, seconds, TimeUnit.SECONDS); + } } diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/domain/cloud/VirtualMachine.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/domain/cloud/VirtualMachine.java index e45d817f79..24d9a684d8 100644 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/domain/cloud/VirtualMachine.java +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/domain/cloud/VirtualMachine.java @@ -35,6 +35,8 @@ import org.jclouds.abiquo.domain.network.Network; import org.jclouds.abiquo.domain.network.UnmanagedNetwork; import org.jclouds.abiquo.domain.task.AsyncTask; import org.jclouds.abiquo.domain.util.LinkUtils; +import org.jclouds.abiquo.features.services.MonitoringService; +import org.jclouds.abiquo.monitor.VirtualMachineMonitor; import org.jclouds.abiquo.predicates.LinkPredicates; import org.jclouds.abiquo.reference.ValidationErrors; import org.jclouds.abiquo.reference.rest.ParentLinkName; @@ -55,6 +57,8 @@ import com.abiquo.server.core.cloud.VirtualMachineTaskDto; import com.abiquo.server.core.cloud.VirtualMachineWithNodeExtendedDto; import com.abiquo.server.core.enterprise.EnterpriseDto; import com.abiquo.server.core.infrastructure.network.UnmanagedIpDto; +import com.abiquo.server.core.infrastructure.network.VMNetworkConfigurationDto; +import com.abiquo.server.core.infrastructure.network.VMNetworkConfigurationsDto; import com.abiquo.server.core.infrastructure.storage.DiskManagementDto; import com.abiquo.server.core.infrastructure.storage.DisksManagementDto; import com.abiquo.server.core.infrastructure.storage.DvdManagementDto; @@ -492,13 +496,13 @@ public class VirtualMachine extends DomainWithTasksWrapper> ips) + public AsyncTask setNics(final List< ? extends Ip< ? , ? >> ips) { // By default the network of the first ip will be used as a gateway return setNics(ips != null && !ips.isEmpty() ? ips.get(0).getNetwork() : null, ips, null); } - public AsyncTask setNics(final List> ips, + public AsyncTask setNics(final List< ? extends Ip< ? , ? >> ips, final List unmanagetNetworks) { // By default the network of the first ip will be used as a gateway @@ -515,18 +519,15 @@ public class VirtualMachine extends DomainWithTasksWrapper gatewayNetwork, final List> ips) + public AsyncTask setNics(final Network< ? > gatewayNetwork, + final List< ? extends Ip< ? , ? >> ips) { return setNics(gatewayNetwork, ips, null); } - public AsyncTask setNics(final Network< ? > gatewayNetwork, final List> ips, - final List unmanagetNetworks) + public AsyncTask setNics(final Network< ? > gatewayNetwork, + final List< ? extends Ip< ? , ? >> ips, final List unmanagetNetworks) { - RESTLink configLink = - checkNotNull(target.searchLink(ParentLinkName.NETWORK_CONFIGURATIONS), - ValidationErrors.MISSING_REQUIRED_LINK + ParentLinkName.NETWORK_CONFIGURATIONS); - // Remove the gateway configuration and the current nics Iterables.removeIf( target.getLinks(), @@ -562,11 +563,40 @@ public class VirtualMachine extends DomainWithTasksWrapper +public class VirtualMachineTemplateWithZone { - private final GetCurrentUser currentUserSupplier; + private VirtualMachineTemplate template; - @Inject - public GetCurrentEnterprise(final GetCurrentUser currentUserSupplier) + private VirtualDatacenter zone; + + public VirtualMachineTemplateWithZone(final VirtualMachineTemplate template, + final VirtualDatacenter zone) { - this.currentUserSupplier = checkNotNull(currentUserSupplier, "currentUserSupplier"); + super(); + this.template = checkNotNull(template, "template"); + this.zone = checkNotNull(zone, "zone"); } - @Override - public Enterprise get() + public VirtualMachineTemplate getTemplate() { - return currentUserSupplier.get().getEnterprise(); + return template; } + + public VirtualDatacenter getZone() + { + return zone; + } + } diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/predicates/cloud/VirtualDatacenterPredicates.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/predicates/cloud/VirtualDatacenterPredicates.java index d515db40d4..5cb2aacd94 100644 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/predicates/cloud/VirtualDatacenterPredicates.java +++ b/labs/abiquo/src/main/java/org/jclouds/abiquo/predicates/cloud/VirtualDatacenterPredicates.java @@ -25,11 +25,14 @@ import static com.google.common.collect.Iterables.transform; import java.util.Arrays; import java.util.List; +import org.jclouds.abiquo.domain.cloud.Conversion; import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; import org.jclouds.abiquo.domain.infrastructure.Datacenter; import org.jclouds.abiquo.reference.ValidationErrors; import org.jclouds.abiquo.reference.rest.ParentLinkName; +import com.abiquo.model.enumerator.ConversionState; import com.abiquo.model.enumerator.HypervisorType; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -101,4 +104,33 @@ public class VirtualDatacenterPredicates } }; } + + /** + * Check if the given template type is compatible with the given virtual datacenter type taking + * into account the conversions of the template. + * + * @param template The template to check. + * @return Predicate to check if the template or its conversions are compatibles with the given + * virtual datacenter. + */ + public static Predicate compatibleWithTemplateOrConversions( + final VirtualMachineTemplate template) + { + return new Predicate() + { + @Override + public boolean apply(final VirtualDatacenter vdc) + { + HypervisorType type = vdc.getHypervisorType(); + boolean compatible = type.isCompatible(template.getDiskFormatType()); + if (!compatible) + { + List compatibleConversions = + template.listConversions(type, ConversionState.FINISHED); + compatible = compatibleConversions != null && !compatibleConversions.isEmpty(); + } + return compatible; + } + }; + } } diff --git a/labs/abiquo/src/main/java/org/jclouds/abiquo/suppliers/GetCurrentUser.java b/labs/abiquo/src/main/java/org/jclouds/abiquo/suppliers/GetCurrentUser.java deleted file mode 100644 index 185a660c35..0000000000 --- a/labs/abiquo/src/main/java/org/jclouds/abiquo/suppliers/GetCurrentUser.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds 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.suppliers; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.abiquo.domain.DomainWrapper.wrap; - -import javax.inject.Inject; - -import org.jclouds.abiquo.AbiquoAsyncApi; -import org.jclouds.abiquo.AbiquoApi; -import org.jclouds.abiquo.domain.enterprise.User; -import org.jclouds.rest.RestContext; - -import com.abiquo.server.core.enterprise.UserDto; -import com.google.common.base.Supplier; - -/** - * Gets the current user. - * - * @author Ignasi Barrera - */ -public class GetCurrentUser implements Supplier -{ - private RestContext context; - - @Inject - public GetCurrentUser(final RestContext context) - { - this.context = checkNotNull(context, "context"); - } - - @Override - public User get() - { - UserDto user = context.getApi().getAdminApi().getCurrentUser(); - return wrap(context, User.class, user); - } - -} diff --git a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/DatacenterToLocationTest.java b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/DatacenterToLocationTest.java index 2edbc1fa1f..8350d47b4d 100644 --- a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/DatacenterToLocationTest.java +++ b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/DatacenterToLocationTest.java @@ -49,6 +49,6 @@ public class DatacenterToLocationTest Location location = function.apply(datacenter); assertEquals(location.getId(), "5"); - assertEquals(location.getScope(), LocationScope.ZONE); + assertEquals(location.getScope(), LocationScope.REGION); } } diff --git a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualDatacenterToLocationTest.java b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualDatacenterToLocationTest.java new file mode 100644 index 0000000000..90e8d06ae1 --- /dev/null +++ b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualDatacenterToLocationTest.java @@ -0,0 +1,105 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.compute.functions; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.testng.Assert.assertEquals; + +import java.util.Collections; +import java.util.Map; + +import org.easymock.EasyMock; +import org.jclouds.abiquo.AbiquoApi; +import org.jclouds.abiquo.AbiquoAsyncApi; +import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; +import org.jclouds.abiquo.domain.enterprise.Enterprise; +import org.jclouds.abiquo.domain.infrastructure.Datacenter; +import org.jclouds.abiquo.domain.network.PrivateNetwork; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationScope; +import org.jclouds.rest.RestContext; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; + +/** + * Unit tests for the {@link VirtualDatacenterToLocation} function. + * + * @author Ignasi Barrera + */ +@Test(groups = "unit", testName = "VirtualDatacenterToLocationTest") +public class VirtualDatacenterToLocationTest +{ + public void testVirtualDatacenterToLocation() + { + Function dcToLocation = mockDatacenterToLocation(); + Supplier> regionMap = mockRegionMap(); + VirtualDatacenterToLocation function = + new VirtualDatacenterToLocation(dcToLocation, regionMap); + + VirtualDatacenter vdc = mockVirtualDatacenter(); + + Location location = function.apply(vdc); + + verify(regionMap); + verify(dcToLocation); + + assertEquals(location.getId(), "5"); + assertEquals(location.getScope(), LocationScope.ZONE); + } + + @SuppressWarnings("unchecked") + private static VirtualDatacenter mockVirtualDatacenter() + { + RestContext context = EasyMock.createMock(RestContext.class); + Datacenter datacenter = EasyMock.createMock(Datacenter.class); + Enterprise enterprise = EasyMock.createMock(Enterprise.class); + PrivateNetwork network = EasyMock.createMock(PrivateNetwork.class); + + VirtualDatacenter vdc = VirtualDatacenter.builder(context, datacenter, enterprise) // + .network(network) // + .name("mock").build(); + vdc.unwrap().setId(5); + + return vdc; + } + + @SuppressWarnings("unchecked") + private static Function mockDatacenterToLocation() + { + Function mock = EasyMock.createMock(Function.class); + expect(mock.apply(anyObject(Datacenter.class))).andReturn(null); + replay(mock); + return mock; + } + + @SuppressWarnings("unchecked") + private static Supplier> mockRegionMap() + { + Supplier> mock = EasyMock.createMock(Supplier.class); + expect(mock.get()).andReturn(Collections.EMPTY_MAP); + replay(mock); + return mock; + } +} diff --git a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineStateToNodeStateTest.java b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineStateToNodeStateTest.java index ea31bbc06d..e130f52796 100644 --- a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineStateToNodeStateTest.java +++ b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineStateToNodeStateTest.java @@ -44,7 +44,7 @@ public class VirtualMachineStateToNodeStateTest assertEquals(function.apply(VirtualMachineState.ON), Status.RUNNING); assertEquals(function.apply(VirtualMachineState.OFF), Status.SUSPENDED); assertEquals(function.apply(VirtualMachineState.PAUSED), Status.SUSPENDED); - assertEquals(function.apply(VirtualMachineState.NOT_ALLOCATED), Status.TERMINATED); + assertEquals(function.apply(VirtualMachineState.NOT_ALLOCATED), Status.PENDING); assertEquals(function.apply(VirtualMachineState.UNKNOWN), Status.UNRECOGNIZED); } } diff --git a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateToHardwareTest.java b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateToHardwareTest.java deleted file mode 100644 index 3c6d812a80..0000000000 --- a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateToHardwareTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds 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.compute.functions; - -import static org.jclouds.abiquo.domain.DomainWrapper.wrap; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNull; - -import java.net.URI; - -import org.easymock.EasyMock; -import org.jclouds.abiquo.AbiquoApi; -import org.jclouds.abiquo.AbiquoAsyncApi; -import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; -import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.domain.Volume; -import org.jclouds.rest.RestContext; -import org.testng.annotations.Test; - -import com.abiquo.model.rest.RESTLink; -import com.abiquo.server.core.appslibrary.VirtualMachineTemplateDto; - -/** - * Unit tests for the {@link VirtualMachineTemplateToHardware} function. - * - * @author Ignasi Barrera - */ -@Test(groups = "unit", testName = "VirtualMachineTemplateToHardwareTest") -public class VirtualMachineTemplateToHardwareTest -{ - @SuppressWarnings("unchecked") - public void testVirtualMachineTemplateToHardware() - { - RestContext context = EasyMock.createMock(RestContext.class); - VirtualMachineTemplateToHardware function = new VirtualMachineTemplateToHardware(); - - // VirtualMachineTemplate domain object does not have a builder, it is read only - VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); - dto.setId(5); - dto.setName("Template"); - dto.setDescription("Template description"); - dto.setHdRequired(50L * 1024 * 1024 * 1024); // 50 GB - dto.setCpuRequired(5); - dto.setRamRequired(2048); - dto.addLink(new RESTLink("edit", "http://foo/bar")); - - Hardware hardware = function.apply(wrap(context, VirtualMachineTemplate.class, dto)); - - assertEquals(hardware.getId(), dto.getId().toString()); - assertEquals(hardware.getName(), dto.getName()); - assertEquals(hardware.getUri(), URI.create("http://foo/bar")); - - assertEquals(hardware.getRam(), dto.getRamRequired()); - assertEquals(hardware.getProcessors().size(), 1); - assertEquals(hardware.getProcessors().get(0).getCores(), (double) dto.getCpuRequired()); - assertEquals(hardware.getProcessors().get(0).getSpeed(), - VirtualMachineTemplateToHardware.DEFAULT_CORE_SPEED); - - assertEquals(hardware.getVolumes().size(), 1); - assertEquals(hardware.getVolumes().get(0).getSize(), 50F); - assertEquals(hardware.getVolumes().get(0).getType(), Volume.Type.LOCAL); - assertEquals(hardware.getVolumes().get(0).isBootDevice(), true); - assertEquals(hardware.getVolumes().get(0).isDurable(), false); - } - - @SuppressWarnings("unchecked") - public void testConvertWithoutEditLink() - { - RestContext context = EasyMock.createMock(RestContext.class); - VirtualMachineTemplateToHardware function = new VirtualMachineTemplateToHardware(); - - // VirtualMachineTemplate domain object does not have a builder, it is read only - VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); - dto.setId(5); - dto.setName("Template"); - dto.setDescription("Template description"); - dto.setHdRequired(50L * 1024 * 1024 * 1024); // 50 GB - dto.setCpuRequired(5); - dto.setRamRequired(2048); - - Hardware hardware = function.apply(wrap(context, VirtualMachineTemplate.class, dto)); - - assertNull(hardware.getUri()); - } - - @SuppressWarnings("unchecked") - @Test(expectedExceptions = NullPointerException.class) - public void testConvertWithoutId() - { - RestContext context = EasyMock.createMock(RestContext.class); - VirtualMachineTemplateToHardware function = new VirtualMachineTemplateToHardware(); - - // VirtualMachineTemplate domain object does not have a builder, it is read only - VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); - function.apply(wrap(context, VirtualMachineTemplate.class, dto)); - } - - @SuppressWarnings("unchecked") - public void testConvertWithoutCpu() - { - RestContext context = EasyMock.createMock(RestContext.class); - VirtualMachineTemplateToHardware function = new VirtualMachineTemplateToHardware(); - - // VirtualMachineTemplate domain object does not have a builder, it is read only - VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); - dto.setId(5); - dto.setName("Template"); - dto.setDescription("Template description"); - dto.setHdRequired(50L * 1024 * 1024 * 1024); // 50 GB - dto.setRamRequired(2048); - - Hardware hardware = function.apply(wrap(context, VirtualMachineTemplate.class, dto)); - - assertEquals(hardware.getProcessors().size(), 1); - assertEquals(hardware.getProcessors().get(0).getCores(), 0D); - } - - @SuppressWarnings("unchecked") - public void testConvertWithoutRam() - { - RestContext context = EasyMock.createMock(RestContext.class); - VirtualMachineTemplateToHardware function = new VirtualMachineTemplateToHardware(); - - // VirtualMachineTemplate domain object does not have a builder, it is read only - VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); - dto.setId(5); - dto.setName("Template"); - dto.setDescription("Template description"); - dto.setHdRequired(50L * 1024 * 1024 * 1024); // 50 GB - dto.setCpuRequired(5); - - Hardware hardware = function.apply(wrap(context, VirtualMachineTemplate.class, dto)); - - assertEquals(hardware.getRam(), 0); - } - - @SuppressWarnings("unchecked") - public void testConvertWithoutHd() - { - RestContext context = EasyMock.createMock(RestContext.class); - VirtualMachineTemplateToHardware function = new VirtualMachineTemplateToHardware(); - - // VirtualMachineTemplate domain object does not have a builder, it is read only - VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); - dto.setId(5); - dto.setName("Template"); - dto.setDescription("Template description"); - dto.setCpuRequired(5); - dto.setRamRequired(2048); - - Hardware hardware = function.apply(wrap(context, VirtualMachineTemplate.class, dto)); - - assertEquals(hardware.getVolumes().size(), 1); - assertEquals(hardware.getVolumes().get(0).getSize(), 0F); - } -} diff --git a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateToImageTest.java b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateToImageTest.java index 95e79e1006..6cf6c2d935 100644 --- a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateToImageTest.java +++ b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateToImageTest.java @@ -19,23 +19,33 @@ package org.jclouds.abiquo.compute.functions; +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; import static org.jclouds.abiquo.domain.DomainWrapper.wrap; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import java.net.URI; +import java.util.Collections; +import java.util.Map; import org.easymock.EasyMock; import org.jclouds.abiquo.AbiquoApi; import org.jclouds.abiquo.AbiquoAsyncApi; import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; +import org.jclouds.abiquo.domain.infrastructure.Datacenter; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.domain.Location; import org.jclouds.rest.RestContext; import org.testng.annotations.Test; import com.abiquo.model.rest.RESTLink; import com.abiquo.server.core.appslibrary.VirtualMachineTemplateDto; +import com.google.common.base.Function; +import com.google.common.base.Supplier; /** * Unit tests for the {@link VirtualMachineTemplateToImage} class. @@ -49,17 +59,23 @@ public class VirtualMachineTemplateToImageTest public void testVirtualMachineTemplateToImage() { RestContext context = EasyMock.createMock(RestContext.class); - VirtualMachineTemplateToImage function = new VirtualMachineTemplateToImage(); + Function dcToLocation = mockDatacenterToLocation(); + Supplier> regionMap = mockRegionMap(); + VirtualMachineTemplateToImage function = + new VirtualMachineTemplateToImage(dcToLocation, regionMap); - // VirtualMachineTemplate domain object does not have a builder, it is read only VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); dto.setId(5); dto.setName("Template"); dto.setDescription("Template description"); dto.addLink(new RESTLink("diskfile", "http://foo/bar")); + dto.addLink(new RESTLink("datacenter", "http://foo/bar/4")); Image image = function.apply(wrap(context, VirtualMachineTemplate.class, dto)); + verify(regionMap); + verify(dcToLocation); + assertEquals(image.getId(), dto.getId().toString()); assertEquals(image.getName(), dto.getName()); assertEquals(image.getDescription(), dto.getDescription()); @@ -72,16 +88,22 @@ public class VirtualMachineTemplateToImageTest public void testConvertWithoutDownloadLink() { RestContext context = EasyMock.createMock(RestContext.class); - VirtualMachineTemplateToImage function = new VirtualMachineTemplateToImage(); + Function dcToLocation = mockDatacenterToLocation(); + Supplier> regionMap = mockRegionMap(); + VirtualMachineTemplateToImage function = + new VirtualMachineTemplateToImage(dcToLocation, regionMap); - // VirtualMachineTemplate domain object does not have a builder, it is read only VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); dto.setId(5); dto.setName("Template"); dto.setDescription("Template description"); + dto.addLink(new RESTLink("datacenter", "http://foo/bar/4")); Image image = function.apply(wrap(context, VirtualMachineTemplate.class, dto)); + verify(regionMap); + verify(dcToLocation); + assertNull(image.getUri()); } @@ -90,10 +112,30 @@ public class VirtualMachineTemplateToImageTest public void testConvertWithoutId() { RestContext context = EasyMock.createMock(RestContext.class); - VirtualMachineTemplateToImage function = new VirtualMachineTemplateToImage(); + Function dcToLocation = mockDatacenterToLocation(); + Supplier> regionMap = mockRegionMap(); + VirtualMachineTemplateToImage function = + new VirtualMachineTemplateToImage(dcToLocation, regionMap); - // VirtualMachineTemplate domain object does not have a builder, it is read only VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); function.apply(wrap(context, VirtualMachineTemplate.class, dto)); } + + @SuppressWarnings("unchecked") + private static Function mockDatacenterToLocation() + { + Function mock = EasyMock.createMock(Function.class); + expect(mock.apply(anyObject(Datacenter.class))).andReturn(null); + replay(mock); + return mock; + } + + @SuppressWarnings("unchecked") + private static Supplier> mockRegionMap() + { + Supplier> mock = EasyMock.createMock(Supplier.class); + expect(mock.get()).andReturn(Collections.EMPTY_MAP); + replay(mock); + return mock; + } } diff --git a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateWithZoneToHardwareTest.java b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateWithZoneToHardwareTest.java new file mode 100644 index 0000000000..cd51233de7 --- /dev/null +++ b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineTemplateWithZoneToHardwareTest.java @@ -0,0 +1,243 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds 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.compute.functions; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.jclouds.abiquo.domain.DomainWrapper.wrap; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.net.URI; + +import org.easymock.EasyMock; +import org.jclouds.abiquo.AbiquoApi; +import org.jclouds.abiquo.AbiquoAsyncApi; +import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplateWithZone; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Volume; +import org.jclouds.domain.Location; +import org.jclouds.rest.RestContext; +import org.testng.annotations.Test; + +import com.abiquo.model.enumerator.HypervisorType; +import com.abiquo.model.rest.RESTLink; +import com.abiquo.server.core.appslibrary.VirtualMachineTemplateDto; +import com.abiquo.server.core.cloud.VirtualDatacenterDto; +import com.google.common.base.Function; + +/** + * Unit tests for the {@link VirtualMachineTemplateWithZoneToHardware} function. + * + * @author Ignasi Barrera + */ +@Test(groups = "unit", testName = "VirtualMachineTemplateToHardwareTest") +public class VirtualMachineTemplateWithZoneToHardwareTest +{ + @SuppressWarnings("unchecked") + public void testVirtualMachineTemplateToHardware() + { + RestContext context = EasyMock.createMock(RestContext.class); + Function vdcToLocation = mockVirtualDatacenterToLocation(); + VirtualMachineTemplateWithZoneToHardware function = + new VirtualMachineTemplateWithZoneToHardware(vdcToLocation); + + VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); + dto.setId(5); + dto.setName("Template"); + dto.setDescription("Template description"); + dto.setHdRequired(50L * 1024 * 1024 * 1024); // 50 GB + dto.setCpuRequired(5); + dto.setRamRequired(2048); + dto.addLink(new RESTLink("edit", "http://foo/bar")); + VirtualMachineTemplate template = wrap(context, VirtualMachineTemplate.class, dto); + + VirtualDatacenterDto vdcDto = new VirtualDatacenterDto(); + vdcDto.setId(6); + vdcDto.setHypervisorType(HypervisorType.VMX_04); + VirtualDatacenter vdc = wrap(context, VirtualDatacenter.class, vdcDto); + + Hardware hardware = function.apply(new VirtualMachineTemplateWithZone(template, vdc)); + + verify(vdcToLocation); + + assertEquals(hardware.getProviderId(), template.getId().toString()); + assertEquals(hardware.getId(), template.getId() + "-" + vdc.getId()); + assertEquals(hardware.getName(), template.getName()); + assertEquals(hardware.getUri(), URI.create("http://foo/bar")); + + assertEquals(hardware.getRam(), template.getRamRequired()); + assertEquals(hardware.getProcessors().size(), 1); + assertEquals(hardware.getProcessors().get(0).getCores(), (double) template.getCpuRequired()); + assertEquals(hardware.getProcessors().get(0).getSpeed(), + VirtualMachineTemplateWithZoneToHardware.DEFAULT_CORE_SPEED); + + assertEquals(hardware.getVolumes().size(), 1); + assertEquals(hardware.getVolumes().get(0).getSize(), 50F); + assertEquals(hardware.getVolumes().get(0).getType(), Volume.Type.LOCAL); + assertEquals(hardware.getVolumes().get(0).isBootDevice(), true); + assertEquals(hardware.getVolumes().get(0).isDurable(), false); + } + + @SuppressWarnings("unchecked") + public void testConvertWithoutEditLink() + { + RestContext context = EasyMock.createMock(RestContext.class); + Function vdcToLocation = mockVirtualDatacenterToLocation(); + VirtualMachineTemplateWithZoneToHardware function = + new VirtualMachineTemplateWithZoneToHardware(vdcToLocation); + + VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); + dto.setId(5); + dto.setName("Template"); + dto.setDescription("Template description"); + dto.setHdRequired(50L * 1024 * 1024 * 1024); // 50 GB + dto.setCpuRequired(5); + dto.setRamRequired(2048); + VirtualMachineTemplate template = wrap(context, VirtualMachineTemplate.class, dto); + + VirtualDatacenterDto vdcDto = new VirtualDatacenterDto(); + vdcDto.setId(6); + vdcDto.setHypervisorType(HypervisorType.VMX_04); + VirtualDatacenter vdc = wrap(context, VirtualDatacenter.class, vdcDto); + + Hardware hardware = function.apply(new VirtualMachineTemplateWithZone(template, vdc)); + + verify(vdcToLocation); + + assertNull(hardware.getUri()); + } + + @SuppressWarnings("unchecked") + @Test(expectedExceptions = NullPointerException.class) + public void testConvertWithoutId() + { + RestContext context = EasyMock.createMock(RestContext.class); + Function vdcToLocation = mockVirtualDatacenterToLocation(); + VirtualMachineTemplateWithZoneToHardware function = + new VirtualMachineTemplateWithZoneToHardware(vdcToLocation); + + VirtualMachineTemplate template = + wrap(context, VirtualMachineTemplate.class, new VirtualMachineTemplateDto()); + VirtualDatacenter vdc = wrap(context, VirtualDatacenter.class, new VirtualDatacenterDto()); + + function.apply(new VirtualMachineTemplateWithZone(template, vdc)); + } + + @SuppressWarnings("unchecked") + public void testConvertWithoutCpu() + { + RestContext context = EasyMock.createMock(RestContext.class); + Function vdcToLocation = mockVirtualDatacenterToLocation(); + VirtualMachineTemplateWithZoneToHardware function = + new VirtualMachineTemplateWithZoneToHardware(vdcToLocation); + + VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); + dto.setId(5); + dto.setName("Template"); + dto.setDescription("Template description"); + dto.setHdRequired(50L * 1024 * 1024 * 1024); // 50 GB + dto.setRamRequired(2048); + VirtualMachineTemplate template = wrap(context, VirtualMachineTemplate.class, dto); + + VirtualDatacenterDto vdcDto = new VirtualDatacenterDto(); + vdcDto.setId(6); + vdcDto.setHypervisorType(HypervisorType.VMX_04); + VirtualDatacenter vdc = wrap(context, VirtualDatacenter.class, vdcDto); + + Hardware hardware = function.apply(new VirtualMachineTemplateWithZone(template, vdc)); + + verify(vdcToLocation); + + assertEquals(hardware.getProcessors().size(), 1); + assertEquals(hardware.getProcessors().get(0).getCores(), 0D); + } + + @SuppressWarnings("unchecked") + public void testConvertWithoutRam() + { + RestContext context = EasyMock.createMock(RestContext.class); + Function vdcToLocation = mockVirtualDatacenterToLocation(); + VirtualMachineTemplateWithZoneToHardware function = + new VirtualMachineTemplateWithZoneToHardware(vdcToLocation); + + VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); + dto.setId(5); + dto.setName("Template"); + dto.setDescription("Template description"); + dto.setHdRequired(50L * 1024 * 1024 * 1024); // 50 GB + dto.setCpuRequired(5); + VirtualMachineTemplate template = wrap(context, VirtualMachineTemplate.class, dto); + + VirtualDatacenterDto vdcDto = new VirtualDatacenterDto(); + vdcDto.setId(6); + vdcDto.setHypervisorType(HypervisorType.VMX_04); + VirtualDatacenter vdc = wrap(context, VirtualDatacenter.class, vdcDto); + + Hardware hardware = function.apply(new VirtualMachineTemplateWithZone(template, vdc)); + + verify(vdcToLocation); + + assertEquals(hardware.getRam(), 0); + } + + @SuppressWarnings("unchecked") + public void testConvertWithoutHd() + { + RestContext context = EasyMock.createMock(RestContext.class); + Function vdcToLocation = mockVirtualDatacenterToLocation(); + VirtualMachineTemplateWithZoneToHardware function = + new VirtualMachineTemplateWithZoneToHardware(vdcToLocation); + + // VirtualMachineTemplate domain object does not have a builder, it is read only + VirtualMachineTemplateDto dto = new VirtualMachineTemplateDto(); + dto.setId(5); + dto.setName("Template"); + dto.setDescription("Template description"); + dto.setCpuRequired(5); + dto.setRamRequired(2048); + VirtualMachineTemplate template = wrap(context, VirtualMachineTemplate.class, dto); + + VirtualDatacenterDto vdcDto = new VirtualDatacenterDto(); + vdcDto.setId(6); + vdcDto.setHypervisorType(HypervisorType.VMX_04); + VirtualDatacenter vdc = wrap(context, VirtualDatacenter.class, vdcDto); + + Hardware hardware = function.apply(new VirtualMachineTemplateWithZone(template, vdc)); + + verify(vdcToLocation); + + assertEquals(hardware.getVolumes().size(), 1); + assertEquals(hardware.getVolumes().get(0).getSize(), 0F); + } + + @SuppressWarnings("unchecked") + private static Function mockVirtualDatacenterToLocation() + { + Function mock = EasyMock.createMock(Function.class); + expect(mock.apply(anyObject(VirtualDatacenter.class))).andReturn(null); + replay(mock); + return mock; + } +} diff --git a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineToNodeMetadataTest.java b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineToNodeMetadataTest.java index d29b655776..e4c0e2a909 100644 --- a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineToNodeMetadataTest.java +++ b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/functions/VirtualMachineToNodeMetadataTest.java @@ -33,7 +33,7 @@ import org.jclouds.abiquo.domain.cloud.VirtualAppliance; import org.jclouds.abiquo.domain.cloud.VirtualDatacenter; import org.jclouds.abiquo.domain.cloud.VirtualMachine; import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate; -import org.jclouds.abiquo.domain.infrastructure.Datacenter; +import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplateWithZone; import org.jclouds.abiquo.domain.network.ExternalIp; import org.jclouds.abiquo.domain.network.Ip; import org.jclouds.abiquo.domain.network.PrivateIp; @@ -111,7 +111,7 @@ public class VirtualMachineToNodeMetadataTest new VirtualMachineToNodeMetadata(templateToImage(), templateToHardware(), stateToNodeState(), - datacenterToLocation()); + virtualDatacenterToLocation()); } public void testVirtualMachineToNodeMetadata() @@ -131,8 +131,6 @@ public class VirtualMachineToNodeMetadataTest assertEquals(node.getLocation().getDescription(), "Mock Location"); assertEquals(node.getImageId(), "1"); assertEquals(node.getHardware().getId(), "1"); - assertEquals(node.getHardware().getHypervisor(), HypervisorType.VMX_04.name()); - assertEquals(node.getHardware().getId(), "1"); assertEquals(node.getHardware().getRam(), vm.getRam()); assertEquals(node.getHardware().getProcessors().get(0).getCores(), (double) vm.getCpu()); assertEquals(node.getLoginPort(), vm.getVdrpPort()); @@ -159,12 +157,13 @@ public class VirtualMachineToNodeMetadataTest return templateToImage; } - private VirtualMachineTemplateToHardware templateToHardware() + private VirtualMachineTemplateWithZoneToHardware templateToHardware() { - VirtualMachineTemplateToHardware virtualMachineTemplateToHardware = - EasyMock.createMock(VirtualMachineTemplateToHardware.class); + VirtualMachineTemplateWithZoneToHardware virtualMachineTemplateToHardware = + EasyMock.createMock(VirtualMachineTemplateWithZoneToHardware.class); - expect(virtualMachineTemplateToHardware.apply(anyObject(VirtualMachineTemplate.class))) + expect( + virtualMachineTemplateToHardware.apply(anyObject(VirtualMachineTemplateWithZone.class))) .andReturn(hardware); replay(virtualMachineTemplateToHardware); @@ -172,15 +171,16 @@ public class VirtualMachineToNodeMetadataTest return virtualMachineTemplateToHardware; } - private DatacenterToLocation datacenterToLocation() + private VirtualDatacenterToLocation virtualDatacenterToLocation() { - DatacenterToLocation datacenterToLocation = EasyMock.createMock(DatacenterToLocation.class); + VirtualDatacenterToLocation datacenterToLocation = + EasyMock.createMock(VirtualDatacenterToLocation.class); Location location = EasyMock.createMock(Location.class); expect(location.getId()).andReturn("1"); expect(location.getDescription()).andReturn("Mock Location"); - expect(datacenterToLocation.apply(anyObject(Datacenter.class))).andReturn(location); + expect(datacenterToLocation.apply(anyObject(VirtualDatacenter.class))).andReturn(location); replay(location); replay(datacenterToLocation); diff --git a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/options/AbiquoTemplateOptionsTest.java b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/options/AbiquoTemplateOptionsTest.java index 7e8496f1f6..1f0937a2b5 100644 --- a/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/options/AbiquoTemplateOptionsTest.java +++ b/labs/abiquo/src/test/java/org/jclouds/abiquo/compute/options/AbiquoTemplateOptionsTest.java @@ -19,25 +19,11 @@ package org.jclouds.abiquo.compute.options; -import static org.jclouds.abiquo.domain.DomainWrapper.wrap; import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; -import org.easymock.EasyMock; -import org.jclouds.abiquo.AbiquoApi; -import org.jclouds.abiquo.AbiquoAsyncApi; -import org.jclouds.abiquo.domain.network.Ip; -import org.jclouds.abiquo.domain.network.PrivateIp; -import org.jclouds.abiquo.domain.network.PrivateNetwork; -import org.jclouds.abiquo.domain.network.UnmanagedNetwork; import org.jclouds.compute.options.TemplateOptions; -import org.jclouds.rest.RestContext; import org.testng.annotations.Test; -import com.abiquo.model.enumerator.NetworkType; -import com.abiquo.server.core.infrastructure.network.PrivateIpDto; -import com.abiquo.server.core.infrastructure.network.VLANNetworkDto; - /** * Unit tests for the {@link AbiquoTemplateOptions} class. * @@ -71,75 +57,4 @@ public class AbiquoTemplateOptionsTest assertEquals(options.as(AbiquoTemplateOptions.class).getVncPassword(), "foo"); } - public void testVirtualDatacenter() - { - TemplateOptions options = new AbiquoTemplateOptions().virtualDatacenter("foo"); - assertEquals(options.as(AbiquoTemplateOptions.class).getVirtualDatacenter(), "foo"); - } - - @SuppressWarnings("unchecked") - public void testIps() - { - RestContext context = EasyMock.createMock(RestContext.class); - - PrivateIpDto dto1 = new PrivateIpDto(); - dto1.setIp("10.60.0.1"); - PrivateIpDto dto2 = new PrivateIpDto(); - dto2.setIp("10.60.0.2"); - - PrivateIp ip1 = wrap(context, PrivateIp.class, dto1); - PrivateIp ip2 = wrap(context, PrivateIp.class, dto2); - - TemplateOptions options = new AbiquoTemplateOptions().ips(ip1, ip2); - - Ip< ? , ? >[] ips = options.as(AbiquoTemplateOptions.class).getIps(); - assertNotNull(ips); - assertEquals(ips[0].getIp(), "10.60.0.1"); - assertEquals(ips[1].getIp(), "10.60.0.2"); - } - - @SuppressWarnings("unchecked") - public void testGatewayNetwork() - { - RestContext context = EasyMock.createMock(RestContext.class); - - VLANNetworkDto dto = new VLANNetworkDto(); - dto.setAddress("10.0.0.0"); - dto.setMask(24); - dto.setGateway("10.0.0.1"); - dto.setType(NetworkType.INTERNAL); - - PrivateNetwork gateway = wrap(context, PrivateNetwork.class, dto); - - TemplateOptions options = new AbiquoTemplateOptions().gatewayNetwork(gateway); - assertEquals(options.as(AbiquoTemplateOptions.class).getGatewayNetwork(), gateway); - } - - @SuppressWarnings("unchecked") - public void testUnmanagedIps() - { - RestContext context = EasyMock.createMock(RestContext.class); - - VLANNetworkDto dto1 = new VLANNetworkDto(); - dto1.setAddress("10.0.0.0"); - dto1.setMask(24); - dto1.setGateway("10.0.0.1"); - dto1.setType(NetworkType.UNMANAGED); - - VLANNetworkDto dto2 = new VLANNetworkDto(); - dto2.setAddress("10.1.0.0"); - dto2.setMask(24); - dto2.setGateway("10.1.0.1"); - dto2.setType(NetworkType.UNMANAGED); - - UnmanagedNetwork net1 = wrap(context, UnmanagedNetwork.class, dto1); - UnmanagedNetwork net2 = wrap(context, UnmanagedNetwork.class, dto2); - - TemplateOptions options = new AbiquoTemplateOptions().unmanagedIps(net1, net2); - - UnmanagedNetwork[] nets = options.as(AbiquoTemplateOptions.class).getUnmanagedIps(); - assertNotNull(nets); - assertEquals(nets[0].getAddress(), "10.0.0.0"); - assertEquals(nets[1].getAddress(), "10.1.0.0"); - } }