Merge pull request #890 from abiquo/simplify-compute

Improved Abiquo ComputeService
This commit is contained in:
Adrian Cole 2012-10-21 16:20:22 -07:00
commit 77d772d4b4
27 changed files with 1016 additions and 859 deletions

View File

@ -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.

View File

@ -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.VirtualMachineTemplateInVirtualDatacenterToHardware;
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.VirtualMachineTemplateInVirtualDatacenter;
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<VirtualMachine, VirtualMachineTemplate, VirtualMachineTemplate, Datacenter>
ComputeServiceAdapterContextModule<VirtualMachine, VirtualMachineTemplateInVirtualDatacenter, VirtualMachineTemplate, VirtualDatacenter>
{
@Override
@ -57,7 +60,7 @@ public class AbiquoComputeServiceContextModule
{
super.configure();
bind(
new TypeLiteral<ComputeServiceAdapter<VirtualMachine, VirtualMachineTemplate, VirtualMachineTemplate, Datacenter>>()
new TypeLiteral<ComputeServiceAdapter<VirtualMachine, VirtualMachineTemplateInVirtualDatacenter, VirtualMachineTemplate, VirtualDatacenter>>()
{
}).to(AbiquoComputeServiceAdapter.class);
bind(new TypeLiteral<Function<VirtualMachine, NodeMetadata>>()
@ -66,15 +69,18 @@ public class AbiquoComputeServiceContextModule
bind(new TypeLiteral<Function<VirtualMachineTemplate, Image>>()
{
}).to(VirtualMachineTemplateToImage.class);
bind(new TypeLiteral<Function<VirtualMachineTemplate, Hardware>>()
bind(new TypeLiteral<Function<VirtualMachineTemplateInVirtualDatacenter, Hardware>>()
{
}).to(VirtualMachineTemplateToHardware.class);
}).to(VirtualMachineTemplateInVirtualDatacenterToHardware.class);
bind(new TypeLiteral<Function<Datacenter, Location>>()
{
}).to(DatacenterToLocation.class);
bind(new TypeLiteral<Function<VirtualDatacenter, Location>>()
{
}).to(VirtualDatacenterToLocation.class);
bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON);
bind(TemplateOptions.class).to(AbiquoTemplateOptions.class);
install(new LocationsFromComputeServiceAdapterModule<VirtualMachine, VirtualMachineTemplate, VirtualMachineTemplate, Datacenter>()
install(new LocationsFromComputeServiceAdapterModule<VirtualMachine, VirtualMachineTemplateInVirtualDatacenter, VirtualMachineTemplate, VirtualDatacenter>()
{
});
}

View File

@ -32,6 +32,8 @@ import com.google.common.collect.ImmutableSet;
/**
* Converts a {@link Datacenter} to a {@link Location} one.
* <p>
* Physical datacenters will be considered regions.
*
* @author Ignasi Barrera
*/
@ -46,8 +48,7 @@ public class DatacenterToLocation implements Function<Datacenter, Location>
builder.id(datacenter.getId().toString());
builder.description(datacenter.getName() + " [" + datacenter.getLocation() + "]");
builder.metadata(ImmutableMap.<String, Object> of());
builder.scope(LocationScope.ZONE);
// TODO: Convert to ISO3166 code?
builder.scope(LocationScope.REGION);
builder.iso3166Codes(ImmutableSet.<String> of());
builder.parent(new LocationBuilder().scope(LocationScope.PROVIDER).id("abiquo")

View File

@ -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.
* <p>
* 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<VirtualDatacenter, Location>
{
private final Function<Datacenter, Location> datacenterToLocation;
private final Supplier<Map<Integer, Datacenter>> regionMap;
@Inject
public VirtualDatacenterToLocation(final Function<Datacenter, Location> datacenterToLocation,
@Memoized final Supplier<Map<Integer, Datacenter>> 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.<String, Object> of());
builder.scope(LocationScope.ZONE);
builder.iso3166Codes(ImmutableSet.<String> of());
Datacenter parent =
regionMap.get().get(vdc.unwrap().getIdFromLink(ParentLinkName.DATACENTER));
builder.parent(datacenterToLocation.apply(parent));
return builder.build();
}
}

View File

@ -43,15 +43,13 @@ public class VirtualMachineStateToNodeState implements Function<VirtualMachineSt
case ALLOCATED:
case LOCKED:
case CONFIGURED:
case NOT_ALLOCATED:
return Status.PENDING;
case ON:
return Status.RUNNING;
case OFF:
case PAUSED:
return Status.SUSPENDED;
case NOT_ALLOCATED:
// TODO: What about nodes created but still not deployed?
return Status.TERMINATED;
case UNKNOWN:
default:
return Status.UNRECOGNIZED;

View File

@ -19,41 +19,69 @@
package org.jclouds.abiquo.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.abiquo.domain.cloud.VirtualDatacenter;
import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate;
import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplateInVirtualDatacenter;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.VolumeBuilder;
import org.jclouds.compute.predicates.ImagePredicates;
import org.jclouds.domain.Location;
import com.google.common.base.Function;
/**
* Transforms a {@link VirtualMachineTemplate} into an {@link Hardware}.
* <p>
* 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<VirtualMachineTemplate, Hardware>
public class VirtualMachineTemplateInVirtualDatacenterToHardware implements
Function<VirtualMachineTemplateInVirtualDatacenter, Hardware>
{
/** 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<VirtualDatacenter, Location> virtualDatacenterToLocation;
@Inject
public VirtualMachineTemplateInVirtualDatacenterToHardware(
final Function<VirtualDatacenter, Location> virtualDatacenterToLocation)
{
this.virtualDatacenterToLocation =
checkNotNull(virtualDatacenterToLocation, "virtualDatacenterToLocation");
}
@Override
public Hardware apply(
final VirtualMachineTemplateInVirtualDatacenter templateInVirtualDatacenter)
{
VirtualMachineTemplate template = templateInVirtualDatacenter.getTemplate();
VirtualDatacenter virtualDatacenter = templateInVirtualDatacenter.getZone();
HardwareBuilder builder = new HardwareBuilder();
builder.ids(template.getId().toString());
builder.providerId(template.getId().toString());
builder.id(template.getId().toString() + "/" + virtualDatacenter.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(virtualDatacenter));
builder.hypervisor(virtualDatacenter.getHypervisorType().name());
builder.supportsImage(ImagePredicates.idEquals(template.getId().toString()));
VolumeBuilder volumeBuilder = new VolumeBuilder();

View File

@ -19,27 +19,49 @@
package org.jclouds.abiquo.compute.functions;
import java.net.URI;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.abiquo.domain.cloud.VirtualMachineTemplate;
import org.jclouds.abiquo.domain.infrastructure.Datacenter;
import org.jclouds.abiquo.reference.rest.ParentLinkName;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Image.Status;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.domain.Location;
import com.abiquo.model.rest.RESTLink;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
/**
* Transforms a {@link VirtualMachineTemplate} into an {@link Image}.
* <p>
* Images are scoped to a region (physical datacenter).
*
* @author Ignasi Barrera
*/
@Singleton
public class VirtualMachineTemplateToImage implements Function<VirtualMachineTemplate, Image>
{
private final Function<Datacenter, Location> datacenterToLocation;
private final Supplier<Map<Integer, Datacenter>> regionMap;
@Inject
public VirtualMachineTemplateToImage(final Function<Datacenter, Location> datacenterToLocation,
@Memoized final Supplier<Map<Integer, Datacenter>> 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<VirtualMachineTem
builder.name(template.getName());
builder.description(template.getDescription());
// Location information
Datacenter region =
regionMap.get().get(template.unwrap().getIdFromLink(ParentLinkName.DATACENTER));
builder.location(datacenterToLocation.apply(region));
// Only conversions have a status
builder.status(Status.AVAILABLE);
builder.backendStatus(Status.AVAILABLE.name()); // Abiquo images do not have a status
@ -57,9 +84,10 @@ public class VirtualMachineTemplateToImage implements Function<VirtualMachineTem
builder.uri(downloadLink == null ? null : URI.create(downloadLink.getHref()));
// TODO: Operating system not implemented in Abiquo Templates
// TODO: Image credentials still not present in Abiquo template metadata
// Will be added in Abiquo 2.4: http://jira.abiquo.com/browse/ABICLOUDPREMIUM-3647
builder.operatingSystem(OperatingSystem.builder().description(template.getName()).build());
// TODO: image credentials
return builder.build();
}
}

View File

@ -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.VirtualMachineTemplateInVirtualDatacenter;
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<VirtualMachine, No
private final VirtualMachineTemplateToImage virtualMachineTemplateToImage;
private final VirtualMachineTemplateToHardware virtualMachineTemplateToHardware;
private final VirtualMachineTemplateInVirtualDatacenterToHardware virtualMachineTemplateToHardware;
private final VirtualMachineStateToNodeState virtualMachineStateToNodeState;
private final DatacenterToLocation datacenterToLocation;
private final Function<VirtualDatacenter, Location> virtualDatacenterToLocation;
@Inject
public VirtualMachineToNodeMetadata(
final VirtualMachineTemplateToImage virtualMachineTemplateToImage,
final VirtualMachineTemplateToHardware virtualMachineTemplateToHardware,
final VirtualMachineTemplateInVirtualDatacenterToHardware virtualMachineTemplateToHardware,
final VirtualMachineStateToNodeState virtualMachineStateToNodeState,
final DatacenterToLocation datacenterToLocation)
final Function<VirtualDatacenter, Location> virtualDatacenterToLocation)
{
this.virtualMachineTemplateToImage =
checkNotNull(virtualMachineTemplateToImage, "virtualMachineTemplateToImage");
@ -80,7 +81,8 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
checkNotNull(virtualMachineTemplateToHardware, "virtualMachineTemplateToHardware");
this.virtualMachineStateToNodeState =
checkNotNull(virtualMachineStateToNodeState, "virtualMachineStateToNodeState");
this.datacenterToLocation = checkNotNull(datacenterToLocation, "datacenterToLocation");
this.virtualDatacenterToLocation =
checkNotNull(virtualDatacenterToLocation, "virtualDatacenterToLocation");
}
@Override
@ -92,19 +94,12 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
builder.name(vm.getNameLabel());
builder.group(vm.getVirtualAppliance().getName());
// TODO: builder.credentials() (http://jira.abiquo.com/browse/ABICLOUDPREMIUM-3647)
VirtualDatacenter vdc = vm.getVirtualDatacenter();
// TODO: Node credentials still not present in Abiquo template metadata
// Will be added in Abiquo 2.4: http://jira.abiquo.com/browse/ABICLOUDPREMIUM-3647
// Location details
try
{
Datacenter datacenter = vdc.getDatacenter();
builder.location(datacenterToLocation.apply(datacenter));
}
catch (AuthorizationException ex)
{
logger.debug("User does not have permissions to see the location of the node");
}
VirtualDatacenter vdc = vm.getVirtualDatacenter();
builder.location(virtualDatacenterToLocation.apply(vdc));
// Image details
VirtualMachineTemplate template = vm.getTemplate();
@ -113,18 +108,19 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
builder.operatingSystem(image.getOperatingSystem());
// Hardware details
Hardware defaultHardware = virtualMachineTemplateToHardware.apply(template);
Hardware defaultHardware =
virtualMachineTemplateToHardware
.apply(new VirtualMachineTemplateInVirtualDatacenter(template, vdc));
Hardware hardware =
new HardwareBuilder() //
.ids(defaultHardware.getId()) //
.uri(defaultHardware.getUri()) //
.name(defaultHardware.getName()) //
.supportsImage(defaultHardware.supportsImage()) //
.ram(vm.getRam()) //
.hypervisor(vdc.getHypervisorType().name()) //
.processor(
new Processor(vm.getCpu(), VirtualMachineTemplateToHardware.DEFAULT_CORE_SPEED)) //
HardwareBuilder
.fromHardware(defaultHardware)
.ram(vm.getRam())
.processors(
Lists.newArrayList(new Processor(vm.getCpu(),
VirtualMachineTemplateInVirtualDatacenterToHardware.DEFAULT_CORE_SPEED))) //
.build();
builder.hardware(hardware);
// Networking configuration

View File

@ -19,9 +19,6 @@
package org.jclouds.abiquo.compute.options;
import org.jclouds.abiquo.domain.network.Ip;
import org.jclouds.abiquo.domain.network.Network;
import org.jclouds.abiquo.domain.network.UnmanagedNetwork;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.options.TemplateOptions;
@ -43,14 +40,6 @@ public class AbiquoTemplateOptions extends TemplateOptions implements Cloneable
private String vncPassword;
private String virtualDatacenter;
private Ip< ? , ? >[] 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);
}
}
}

View File

@ -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.VirtualMachineTemplateInVirtualDatacenter;
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<VirtualMachine, VirtualMachineTemplate, VirtualMachineTemplate, Datacenter>
ComputeServiceAdapter<VirtualMachine, VirtualMachineTemplateInVirtualDatacenter, VirtualMachineTemplate, VirtualDatacenter>
{
@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<Map<Integer, Datacenter>> regionMap;
@Inject
public AbiquoComputeServiceAdapter(final RestContext<AbiquoApi, AbiquoAsyncApi> context,
final AdministrationService adminService, final CloudService cloudService,
final MonitoringService monitoringService, final AbiquoComputeServiceHelper helper)
final MonitoringService monitoringService,
final FindCompatibleVirtualDatacenters compatibleVirtualDatacenters,
@Memoized final Supplier<Map<Integer, Datacenter>> 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.<PublicIp> notUsed());
if (publicIp != null)
{
List<PublicIp> 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<VirtualMachine>(vm, vm.getId().toString(), template
.getImage().getDefaultCredentials());
return new NodeAndInitialCredentials<VirtualMachine>(vm, vm.getId().toString(), null);
}
@Override
public Iterable<VirtualMachineTemplate> listHardwareProfiles()
public Iterable<VirtualMachineTemplateInVirtualDatacenter> 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<VirtualMachineTemplate, Iterable<VirtualMachineTemplateInVirtualDatacenter>>()
{
@Override
public Iterable<VirtualMachineTemplateInVirtualDatacenter> apply(
final VirtualMachineTemplate template)
{
Iterable<VirtualDatacenter> compatibleZones =
compatibleVirtualDatacenters.execute(template);
return transform(compatibleZones,
new Function<VirtualDatacenter, VirtualMachineTemplateInVirtualDatacenter>()
{
@Override
public VirtualMachineTemplateInVirtualDatacenter apply(final VirtualDatacenter vdc)
{
return new VirtualMachineTemplateInVirtualDatacenter(template, vdc);
}
});
}
}));
}
@Override
@ -172,17 +212,14 @@ public class AbiquoComputeServiceAdapter
}
@Override
public Iterable<Datacenter> listLocations()
public Iterable<VirtualDatacenter> 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));
}

View File

@ -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<AbiquoApi, AbiquoAsyncApi> context;
private CloudService cloudService;
@Inject
public AbiquoComputeServiceHelper(final RestContext<AbiquoApi, AbiquoAsyncApi> 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.
* <p>
* 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 <code>null</code> 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<VirtualDatacenter> 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<VirtualDatacenter> findCompatibleVirtualDatacenters(
final Datacenter datacenter, final VirtualMachineTemplate template)
{
Iterable<VirtualDatacenter> vdcs =
cloudService.listVirtualDatacenters(VirtualDatacenterPredicates.datacenter(datacenter));
return filter(vdcs, new Predicate<VirtualDatacenter>()
{
@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<Ip< ? , ? extends Network< ? >>> ips,
@Nullable final List<UnmanagedNetwork> 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<Conversion> compatibleConversions =
template.listConversions(type, ConversionState.FINISHED);
compatible = compatibleConversions != null && !compatibleConversions.isEmpty();
}
return compatible;
}
}

View File

@ -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<VirtualDatacenter> execute(VirtualMachineTemplate template);
}

View File

@ -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.
* <p>
* 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<AbiquoApi, AbiquoAsyncApi> context;
private final CloudService cloudService;
@Inject
public FindCompatibleVirtualDatacentersForImageAndConversions(
final RestContext<AbiquoApi, AbiquoAsyncApi> context, final CloudService cloudService)
{
this.context = checkNotNull(context, "context");
this.cloudService = checkNotNull(cloudService, "cloudService");
}
@Override
public Iterable<VirtualDatacenter> 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<VirtualDatacenter> vdcs =
cloudService.listVirtualDatacenters(VirtualDatacenterPredicates.datacenter(datacenter));
return filter(vdcs, compatibleWithTemplateOrConversions(template));
}
}

View File

@ -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.
* <p>
* 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.
* <p>
* This strategy will only consider the base disk format of the image.
*
* @author Ignasi Barrera
*/
@Singleton
public class FindCompatibleVirtualDatacentersForImageBaseFormat implements
FindCompatibleVirtualDatacenters
{
private final RestContext<AbiquoApi, AbiquoAsyncApi> context;
private final CloudService cloudService;
@Inject
public FindCompatibleVirtualDatacentersForImageBaseFormat(
final RestContext<AbiquoApi, AbiquoAsyncApi> context, final CloudService cloudService)
{
this.context = checkNotNull(context, "context");
this.cloudService = checkNotNull(cloudService, "cloudService");
}
@Override
public Iterable<VirtualDatacenter> 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<VirtualDatacenter> vdcs =
cloudService.listVirtualDatacenters(VirtualDatacenterPredicates.datacenter(datacenter));
return filter(vdcs, new Predicate<VirtualDatacenter>()
{
@Override
public boolean apply(final VirtualDatacenter vdc)
{
HypervisorType type = vdc.getHypervisorType();
return type.isCompatible(template.getDiskFormatType());
}
});
}
}

View File

@ -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<AbiquoApi, AbiquoAs
@Memoized
public Supplier<User> getCurrentUser(
final AtomicReference<AuthorizationException> authException,
@Named(PROPERTY_SESSION_INTERVAL) final long seconds, final GetCurrentUser getCurrentUser)
@Named(PROPERTY_SESSION_INTERVAL) final long seconds,
final RestContext<AbiquoApi, AbiquoAsyncApi> context)
{
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
getCurrentUser, seconds, TimeUnit.SECONDS);
new Supplier<User>()
{
@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<AbiquoApi, AbiquoAs
public Supplier<Enterprise> getCurrentEnterprise(
final AtomicReference<AuthorizationException> authException,
@Named(PROPERTY_SESSION_INTERVAL) final long seconds,
final GetCurrentEnterprise getCurrentEnterprise)
final @Memoized Supplier<User> currentUser)
{
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
getCurrentEnterprise, seconds, TimeUnit.SECONDS);
new Supplier<Enterprise>()
{
@Override
public Enterprise get()
{
return currentUser.get().getEnterprise();
}
}, seconds, TimeUnit.SECONDS);
}
@Provides
@Singleton
@Memoized
public Supplier<Map<Integer, Datacenter>> getAvailableRegionsIndexedById(
final AtomicReference<AuthorizationException> authException,
@Named(PROPERTY_SESSION_INTERVAL) final long seconds,
@Memoized final Supplier<Enterprise> currentEnterprise)
{
Supplier<Map<Integer, Datacenter>> availableRegionsMapSupplier =
Suppliers2.compose(new Function<List<Datacenter>, Map<Integer, Datacenter>>()
{
@Override
public Map<Integer, Datacenter> apply(final List<Datacenter> datacenters)
{
// Index available regions by id
return Maps.uniqueIndex(datacenters, new Function<Datacenter, Integer>()
{
@Override
public Integer apply(final Datacenter input)
{
return input.getId();
}
});
}
}, new Supplier<List<Datacenter>>()
{
@Override
public List<Datacenter> get()
{
// Get the list of regions available for the user's tenant
return currentEnterprise.get().listAllowedDatacenters();
}
});
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
availableRegionsMapSupplier, seconds, TimeUnit.SECONDS);
}
}

View File

@ -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<VirtualMachineWithNod
return setVolumes(true, volumes);
}
public AsyncTask setNics(final List<Ip< ? , ? >> 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<Ip< ? , ? >> ips,
public AsyncTask setNics(final List< ? extends Ip< ? , ? >> ips,
final List<UnmanagedNetwork> unmanagetNetworks)
{
// By default the network of the first ip will be used as a gateway
@ -515,18 +519,15 @@ public class VirtualMachine extends DomainWithTasksWrapper<VirtualMachineWithNod
return setNics(gateway, ips, unmanagetNetworks);
}
public AsyncTask setNics(final Network< ? > gatewayNetwork, final List<Ip< ? , ? >> 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<Ip< ? , ? >> ips,
final List<UnmanagedNetwork> unmanagetNetworks)
public AsyncTask setNics(final Network< ? > gatewayNetwork,
final List< ? extends Ip< ? , ? >> ips, final List<UnmanagedNetwork> 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<VirtualMachineWithNod
}
}
// Set the new network configuration
if (gatewayNetwork != null)
AsyncTask task = update(true);
if (gatewayNetwork == null)
{
target.addLink(new RESTLink(ParentLinkName.NETWORK_GATEWAY, configLink.getHref() + "/"
+ gatewayNetwork.getId()));
return task;
}
// If there is a gateway network, we have to wait until the network configuration links are
// available
if (task != null)
{
VirtualMachineState originalState = target.getState();
VirtualMachineMonitor monitor =
context.getUtils().getInjector().getInstance(MonitoringService.class)
.getVirtualMachineMonitor();
monitor.awaitState(originalState, this);
}
// Set the new network configuration
// Refresh virtual machine, to get the new configuration links
refresh();
VMNetworkConfigurationsDto configs =
context.getApi().getCloudApi().listNetworkConfigurations(target);
Iterables.removeIf(target.getLinks(), LinkPredicates.rel(ParentLinkName.NETWORK_GATEWAY));
for (VMNetworkConfigurationDto config : configs.getCollection())
{
if (config.getGateway().equalsIgnoreCase(gatewayNetwork.getGateway()))
{
target.addLink(new RESTLink(ParentLinkName.NETWORK_GATEWAY, config.getEditLink()
.getHref()));
break;
}
}
return update(true);

View File

@ -16,35 +16,38 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.abiquo.suppliers;
package org.jclouds.abiquo.domain.cloud;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import org.jclouds.abiquo.domain.enterprise.Enterprise;
import com.google.common.base.Supplier;
/**
* Gets the current enterprise.
* Wrapper to hold the information of a virtual machine template scoped to a concrete hypervisor
* type.
*
* @author Ignasi Barrera
*/
public class GetCurrentEnterprise implements Supplier<Enterprise>
public class VirtualMachineTemplateInVirtualDatacenter
{
private final GetCurrentUser currentUserSupplier;
private VirtualMachineTemplate template;
@Inject
public GetCurrentEnterprise(final GetCurrentUser currentUserSupplier)
private VirtualDatacenter zone;
public VirtualMachineTemplateInVirtualDatacenter(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;
}
}

View File

@ -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<VirtualDatacenter> compatibleWithTemplateOrConversions(
final VirtualMachineTemplate template)
{
return new Predicate<VirtualDatacenter>()
{
@Override
public boolean apply(final VirtualDatacenter vdc)
{
HypervisorType type = vdc.getHypervisorType();
boolean compatible = type.isCompatible(template.getDiskFormatType());
if (!compatible)
{
List<Conversion> compatibleConversions =
template.listConversions(type, ConversionState.FINISHED);
compatible = compatibleConversions != null && !compatibleConversions.isEmpty();
}
return compatible;
}
};
}
}

View File

@ -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<User>
{
private RestContext<AbiquoApi, AbiquoAsyncApi> context;
@Inject
public GetCurrentUser(final RestContext<AbiquoApi, AbiquoAsyncApi> context)
{
this.context = checkNotNull(context, "context");
}
@Override
public User get()
{
UserDto user = context.getApi().getAdminApi().getCurrentUser();
return wrap(context, User.class, user);
}
}

View File

@ -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);
}
}

View File

@ -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<Datacenter, Location> dcToLocation = mockDatacenterToLocation();
Supplier<Map<Integer, Datacenter>> 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<AbiquoApi, AbiquoAsyncApi> 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<Datacenter, Location> mockDatacenterToLocation()
{
Function<Datacenter, Location> mock = EasyMock.createMock(Function.class);
expect(mock.apply(anyObject(Datacenter.class))).andReturn(null);
replay(mock);
return mock;
}
@SuppressWarnings("unchecked")
private static Supplier<Map<Integer, Datacenter>> mockRegionMap()
{
Supplier<Map<Integer, Datacenter>> mock = EasyMock.createMock(Supplier.class);
expect(mock.get()).andReturn(Collections.EMPTY_MAP);
replay(mock);
return mock;
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,248 @@
/**
* 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.VirtualMachineTemplateInVirtualDatacenter;
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 VirtualMachineTemplateInVirtualDatacenterToHardware} function.
*
* @author Ignasi Barrera
*/
@Test(groups = "unit", testName = "VirtualMachineTemplateInVirtualDatacenterToHardwareTest")
public class VirtualMachineTemplateInVirtualDatacenterToHardwareTest
{
@SuppressWarnings("unchecked")
public void testVirtualMachineTemplateToHardware()
{
RestContext<AbiquoApi, AbiquoAsyncApi> context = EasyMock.createMock(RestContext.class);
Function<VirtualDatacenter, Location> vdcToLocation = mockVirtualDatacenterToLocation();
VirtualMachineTemplateInVirtualDatacenterToHardware function =
new VirtualMachineTemplateInVirtualDatacenterToHardware(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 VirtualMachineTemplateInVirtualDatacenter(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(),
VirtualMachineTemplateInVirtualDatacenterToHardware.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<AbiquoApi, AbiquoAsyncApi> context = EasyMock.createMock(RestContext.class);
Function<VirtualDatacenter, Location> vdcToLocation = mockVirtualDatacenterToLocation();
VirtualMachineTemplateInVirtualDatacenterToHardware function =
new VirtualMachineTemplateInVirtualDatacenterToHardware(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 VirtualMachineTemplateInVirtualDatacenter(template, vdc));
verify(vdcToLocation);
assertNull(hardware.getUri());
}
@SuppressWarnings("unchecked")
@Test(expectedExceptions = NullPointerException.class)
public void testConvertWithoutId()
{
RestContext<AbiquoApi, AbiquoAsyncApi> context = EasyMock.createMock(RestContext.class);
Function<VirtualDatacenter, Location> vdcToLocation = mockVirtualDatacenterToLocation();
VirtualMachineTemplateInVirtualDatacenterToHardware function =
new VirtualMachineTemplateInVirtualDatacenterToHardware(vdcToLocation);
VirtualMachineTemplate template =
wrap(context, VirtualMachineTemplate.class, new VirtualMachineTemplateDto());
VirtualDatacenter vdc = wrap(context, VirtualDatacenter.class, new VirtualDatacenterDto());
function.apply(new VirtualMachineTemplateInVirtualDatacenter(template, vdc));
}
@SuppressWarnings("unchecked")
public void testConvertWithoutCpu()
{
RestContext<AbiquoApi, AbiquoAsyncApi> context = EasyMock.createMock(RestContext.class);
Function<VirtualDatacenter, Location> vdcToLocation = mockVirtualDatacenterToLocation();
VirtualMachineTemplateInVirtualDatacenterToHardware function =
new VirtualMachineTemplateInVirtualDatacenterToHardware(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 VirtualMachineTemplateInVirtualDatacenter(template, vdc));
verify(vdcToLocation);
assertEquals(hardware.getProcessors().size(), 1);
assertEquals(hardware.getProcessors().get(0).getCores(), 0D);
}
@SuppressWarnings("unchecked")
public void testConvertWithoutRam()
{
RestContext<AbiquoApi, AbiquoAsyncApi> context = EasyMock.createMock(RestContext.class);
Function<VirtualDatacenter, Location> vdcToLocation = mockVirtualDatacenterToLocation();
VirtualMachineTemplateInVirtualDatacenterToHardware function =
new VirtualMachineTemplateInVirtualDatacenterToHardware(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 VirtualMachineTemplateInVirtualDatacenter(template, vdc));
verify(vdcToLocation);
assertEquals(hardware.getRam(), 0);
}
@SuppressWarnings("unchecked")
public void testConvertWithoutHd()
{
RestContext<AbiquoApi, AbiquoAsyncApi> context = EasyMock.createMock(RestContext.class);
Function<VirtualDatacenter, Location> vdcToLocation = mockVirtualDatacenterToLocation();
VirtualMachineTemplateInVirtualDatacenterToHardware function =
new VirtualMachineTemplateInVirtualDatacenterToHardware(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 VirtualMachineTemplateInVirtualDatacenter(template, vdc));
verify(vdcToLocation);
assertEquals(hardware.getVolumes().size(), 1);
assertEquals(hardware.getVolumes().get(0).getSize(), 0F);
}
@SuppressWarnings("unchecked")
private static Function<VirtualDatacenter, Location> mockVirtualDatacenterToLocation()
{
Function<VirtualDatacenter, Location> mock = EasyMock.createMock(Function.class);
expect(mock.apply(anyObject(VirtualDatacenter.class))).andReturn(null);
replay(mock);
return mock;
}
}

View File

@ -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<AbiquoApi, AbiquoAsyncApi> 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<AbiquoApi, AbiquoAsyncApi> 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<AbiquoApi, AbiquoAsyncApi> 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<AbiquoApi, AbiquoAsyncApi> 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<AbiquoApi, AbiquoAsyncApi> 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<AbiquoApi, AbiquoAsyncApi> 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);
}
}

View File

@ -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<AbiquoApi, AbiquoAsyncApi> context = EasyMock.createMock(RestContext.class);
VirtualMachineTemplateToImage function = new VirtualMachineTemplateToImage();
Function<Datacenter, Location> dcToLocation = mockDatacenterToLocation();
Supplier<Map<Integer, Datacenter>> 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<AbiquoApi, AbiquoAsyncApi> context = EasyMock.createMock(RestContext.class);
VirtualMachineTemplateToImage function = new VirtualMachineTemplateToImage();
Function<Datacenter, Location> dcToLocation = mockDatacenterToLocation();
Supplier<Map<Integer, Datacenter>> 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<AbiquoApi, AbiquoAsyncApi> context = EasyMock.createMock(RestContext.class);
VirtualMachineTemplateToImage function = new VirtualMachineTemplateToImage();
Function<Datacenter, Location> dcToLocation = mockDatacenterToLocation();
Supplier<Map<Integer, Datacenter>> 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<Datacenter, Location> mockDatacenterToLocation()
{
Function<Datacenter, Location> mock = EasyMock.createMock(Function.class);
expect(mock.apply(anyObject(Datacenter.class))).andReturn(null);
replay(mock);
return mock;
}
@SuppressWarnings("unchecked")
private static Supplier<Map<Integer, Datacenter>> mockRegionMap()
{
Supplier<Map<Integer, Datacenter>> mock = EasyMock.createMock(Supplier.class);
expect(mock.get()).andReturn(Collections.EMPTY_MAP);
replay(mock);
return mock;
}
}

View File

@ -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.VirtualMachineTemplateInVirtualDatacenter;
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 VirtualMachineTemplateInVirtualDatacenterToHardware templateToHardware()
{
VirtualMachineTemplateToHardware virtualMachineTemplateToHardware =
EasyMock.createMock(VirtualMachineTemplateToHardware.class);
VirtualMachineTemplateInVirtualDatacenterToHardware virtualMachineTemplateToHardware =
EasyMock.createMock(VirtualMachineTemplateInVirtualDatacenterToHardware.class);
expect(virtualMachineTemplateToHardware.apply(anyObject(VirtualMachineTemplate.class)))
expect(
virtualMachineTemplateToHardware.apply(anyObject(VirtualMachineTemplateInVirtualDatacenter.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);

View File

@ -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<AbiquoApi, AbiquoAsyncApi> 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<AbiquoApi, AbiquoAsyncApi> 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<AbiquoApi, AbiquoAsyncApi> 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");
}
}