diff --git a/providers/profitbricks/README.md b/providers/profitbricks/README.md index 09c367a3ec..67db8dd521 100644 --- a/providers/profitbricks/README.md +++ b/providers/profitbricks/README.md @@ -53,11 +53,9 @@ Template template = compute.templateBuilder() compute.createNodesInGroup( "cluster1", 1, template ); ``` -> If no `locationId` is specified in the template, jclouds will look for a `DataCenter` that is of same scope as the `Image`. - ## Limitations - There's no direct way of specifying arbitrary number of cores, RAM size, and storage size via the compute interface, at least until after [JCLOUDS-482](https://issues.apache.org/jira/browse/JCLOUDS-482) is resolved. The adapter uses a predefined list hardware profiles instead. -> Take note that these features are still accessible by *unwraping* the ProfitBricks API, but this'll reduce portability of your code. See [Concepts](https://jclouds.apache.org/start/concepts/). \ No newline at end of file +> Take note that these features are still accessible by *unwraping* the ProfitBricks API, but this'll reduce portability of your code. See [Concepts](https://jclouds.apache.org/start/concepts/). diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksProviderMetadata.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksProviderMetadata.java index ec7fc9ae3a..ba8b9d48a2 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksProviderMetadata.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksProviderMetadata.java @@ -20,18 +20,23 @@ import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; +import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONE; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONES; import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_INITIAL_PERIOD; import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_MAX_PERIOD; import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.TIMEOUT_DATACENTER_AVAILABLE; -import com.google.auto.service.AutoService; - import java.net.URI; import java.util.Properties; import org.jclouds.providers.ProviderMetadata; import org.jclouds.providers.internal.BaseProviderMetadata; +import com.google.auto.service.AutoService; + @AutoService(ProviderMetadata.class) public class ProfitBricksProviderMetadata extends BaseProviderMetadata { @@ -54,6 +59,16 @@ public class ProfitBricksProviderMetadata extends BaseProviderMetadata { public static Properties defaultProperties() { Properties properties = ProfitBricksApiMetadata.defaultProperties(); + + properties.setProperty(PROPERTY_REGIONS, "de,us"); + properties.setProperty(PROPERTY_REGION + ".de.zones", "de/fkb,de/fra"); + properties.setProperty(PROPERTY_REGION + ".us.zones", "us/las,us/lasdev"); + properties.setProperty(PROPERTY_ZONES, "de/fkb,de/fra,us/las,us/lasdev"); + properties.setProperty(PROPERTY_ZONE + ".de/fkb." + ISO3166_CODES, "DE-BW"); + properties.setProperty(PROPERTY_ZONE + ".de/fra." + ISO3166_CODES, "DE-HE"); + properties.setProperty(PROPERTY_ZONE + ".us/las." + ISO3166_CODES, "US-NV"); + properties.setProperty(PROPERTY_ZONE + ".us/lasdebv." + ISO3166_CODES, "US-NV"); + properties.put(TIMEOUT_DATACENTER_AVAILABLE, 30L * 60L); // 30 minutes properties.put(POLL_INITIAL_PERIOD, 5L); properties.put(POLL_MAX_PERIOD, 60L); @@ -79,6 +94,7 @@ public class ProfitBricksProviderMetadata extends BaseProviderMetadata { .name("ProfitBricks Cloud Compute 2.0") .homepage(URI.create("http://www.profitbricks.com")) .console(URI.create("https://my.profitbricks.com/dashboard/dcdr2/")) + .iso3166Codes("DE-BW", "DE-HE", "US-NV") .linkedServices("profitbricks") .apiMetadata(new ProfitBricksApiMetadata()) .defaultProperties(ProfitBricksProviderMetadata.defaultProperties()); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapter.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapter.java index 68a7097af1..fe02c41589 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapter.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapter.java @@ -47,18 +47,18 @@ import org.jclouds.domain.LocationScope; import org.jclouds.domain.LoginCredentials; import org.jclouds.logging.Logger; import org.jclouds.profitbricks.ProfitBricksApi; -import org.jclouds.profitbricks.domain.AvailabilityZone; -import org.jclouds.profitbricks.domain.DataCenter; -import org.jclouds.profitbricks.domain.Image; -import org.jclouds.profitbricks.domain.Server; -import org.jclouds.profitbricks.domain.Storage; -import org.jclouds.profitbricks.features.DataCenterApi; -import org.jclouds.profitbricks.features.ServerApi; import org.jclouds.profitbricks.compute.concurrent.ProvisioningJob; import org.jclouds.profitbricks.compute.concurrent.ProvisioningManager; import org.jclouds.profitbricks.compute.function.ProvisionableToImage; -import org.jclouds.profitbricks.domain.Snapshot; +import org.jclouds.profitbricks.compute.strategy.TemplateWithDataCenter; +import org.jclouds.profitbricks.domain.AvailabilityZone; +import org.jclouds.profitbricks.domain.DataCenter; +import org.jclouds.profitbricks.domain.Image; import org.jclouds.profitbricks.domain.Provisionable; +import org.jclouds.profitbricks.domain.Server; +import org.jclouds.profitbricks.domain.Snapshot; +import org.jclouds.profitbricks.domain.Storage; +import org.jclouds.profitbricks.features.ServerApi; import org.jclouds.profitbricks.util.Passwords; import org.jclouds.rest.ResourceNotFoundException; @@ -74,7 +74,7 @@ import com.google.common.util.concurrent.ListeningExecutorService; import com.google.inject.Inject; @Singleton -public class ProfitBricksComputeServiceAdapter implements ComputeServiceAdapter { +public class ProfitBricksComputeServiceAdapter implements ComputeServiceAdapter { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) @@ -100,12 +100,16 @@ public class ProfitBricksComputeServiceAdapter implements ComputeServiceAdapter< this.jobFactory = jobFactory; this.provisioningManager = provisioningManager; } - + @Override public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template) { - Location location = template.getLocation(); - checkArgument(location.getScope() == LocationScope.ZONE, "Template must use a ZONE-scoped location"); - final String dataCenterId = location.getId(); + checkArgument(template instanceof TemplateWithDataCenter, "This implementation requires a TemplateWithDataCenter"); + return createNodeWithGroupEncodedIntoName(group, name, TemplateWithDataCenter.class.cast(template)); + } + + protected NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, TemplateWithDataCenter template) { + checkArgument(template.getLocation().getScope() == LocationScope.ZONE, "Template must use a ZONE-scoped location"); + final String dataCenterId = template.getDataCenter().id(); Hardware hardware = template.getHardware(); @@ -314,29 +318,9 @@ public class ProfitBricksComputeServiceAdapter implements ComputeServiceAdapter< } @Override - public Iterable listLocations() { - logger.trace("<< fetching datacenters.."); - final DataCenterApi dcApi = api.dataCenterApi(); - - // Fetch all datacenters - ListenableFuture> futures = allAsList(transform(dcApi.getAllDataCenters(), - new Function>() { - - @Override - public ListenableFuture apply(final DataCenter input) { - // Fetch more details in parallel - return executorService.submit(new Callable() { - @Override - public DataCenter call() throws Exception { - logger.trace("<< fetching datacenter with id [%s]", input.id()); - return dcApi.getDataCenter(input.id()); - } - - }); - } - })); - - return getUnchecked(futures); + public Iterable listLocations() { + // Will never be called + throw new UnsupportedOperationException("Locations are configured in jclouds properties"); } @Override diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/ProfitBricksTemplateBuilderImpl.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/ProfitBricksTemplateBuilderImpl.java deleted file mode 100644 index a1967f8c85..0000000000 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/ProfitBricksTemplateBuilderImpl.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.profitbricks.compute; - -import static com.google.common.collect.Iterables.find; -import static java.lang.String.format; -import static org.jclouds.domain.LocationScope.ZONE; - -import java.util.NoSuchElementException; -import java.util.Set; - -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Provider; - -import org.jclouds.collect.Memoized; -import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.domain.TemplateBuilder; -import org.jclouds.compute.domain.internal.TemplateBuilderImpl; -import org.jclouds.compute.options.TemplateOptions; -import org.jclouds.domain.Location; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; - -import org.jclouds.compute.domain.Image; - -public class ProfitBricksTemplateBuilderImpl extends TemplateBuilderImpl { - - private final Function fnLocation; - - @Inject - ProfitBricksTemplateBuilderImpl(@Memoized Supplier> locations, - @Memoized Supplier> images, @Memoized Supplier> hardwares, - Supplier defaultLocation, @Named("DEFAULT") Provider optionsProvider, - @Named("DEFAULT") Provider defaultTemplateProvider, - Function fnLocation) { - super(locations, images, hardwares, defaultLocation, optionsProvider, defaultTemplateProvider); - this.fnLocation = fnLocation; - } - - @Override - public TemplateBuilder locationId(final String locationId) { - org.jclouds.profitbricks.domain.Location nativeLocation - = org.jclouds.profitbricks.domain.Location.fromId(locationId); - - Set dataCenters = this.locations.get(); - if (nativeLocation != org.jclouds.profitbricks.domain.Location.UNRECOGNIZED) - try { - // look for a child location instead if provided id is a Region - final Location parentLocation = fnLocation.apply(nativeLocation); - this.location = find(dataCenters, new Predicate() { - - @Override - public boolean apply(Location input) { - return parentLocation.equals(input.getParent()); - } - - @Override - public String toString() { - return "first datacenter in locationId(" + locationId + ")"; - } - - }); - } catch (NoSuchElementException ex) { - throw new NoSuchElementException( - format("no child location found for location id %s in: %s", locationId, locations)); - } - else - super.locationId(locationId); - return this; - } - - @Override - public Template build() { - Template template = super.build(); - - Location loc = template.getLocation(); - if (loc != null && loc.getScope() != ZONE) - return fromTemplate(template).locationId(loc.getId()).build(); - - return template; - } - -} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/config/ProfitBricksComputeServiceContextModule.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/config/ProfitBricksComputeServiceContextModule.java index 629fadc79c..abc732dd0b 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/config/ProfitBricksComputeServiceContextModule.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/config/ProfitBricksComputeServiceContextModule.java @@ -36,8 +36,8 @@ import org.jclouds.compute.config.ComputeServiceAdapterContextModule; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.Volume; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.domain.Location; import org.jclouds.functions.IdentityFunction; import org.jclouds.lifecycle.Closer; @@ -47,51 +47,41 @@ import org.jclouds.profitbricks.ProfitBricksApi; import org.jclouds.profitbricks.compute.ProfitBricksComputeServiceAdapter; import org.jclouds.profitbricks.compute.concurrent.ProvisioningJob; import org.jclouds.profitbricks.compute.concurrent.ProvisioningManager; -import org.jclouds.profitbricks.domain.DataCenter; -import org.jclouds.profitbricks.domain.Server; -import org.jclouds.profitbricks.domain.Storage; -import org.jclouds.profitbricks.compute.ProfitBricksTemplateBuilderImpl; -import org.jclouds.profitbricks.compute.function.DataCenterToLocation; -import org.jclouds.profitbricks.compute.function.LocationToLocation; import org.jclouds.profitbricks.compute.function.ProvisionableToImage; import org.jclouds.profitbricks.compute.function.ServerToNodeMetadata; import org.jclouds.profitbricks.compute.function.StorageToVolume; -import org.jclouds.profitbricks.domain.ProvisioningState; +import org.jclouds.profitbricks.compute.strategy.AssignDataCenterToTemplate; import org.jclouds.profitbricks.domain.Provisionable; +import org.jclouds.profitbricks.domain.ProvisioningState; +import org.jclouds.profitbricks.domain.Server; +import org.jclouds.profitbricks.domain.Storage; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.inject.Inject; import com.google.inject.Provides; +import com.google.inject.Scopes; import com.google.inject.TypeLiteral; import com.google.inject.assistedinject.FactoryModuleBuilder; public class ProfitBricksComputeServiceContextModule extends - ComputeServiceAdapterContextModule { + ComputeServiceAdapterContextModule { + @SuppressWarnings("unchecked") @Override protected void configure() { super.configure(); - install(new LocationsFromComputeServiceAdapterModule() { - }); - install(new FactoryModuleBuilder().build(ProvisioningJob.Factory.class)); - bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Singleton.class); + bind(ImplicitLocationSupplier.class).to(OnlyLocationOrFirstZone.class).in(Scopes.SINGLETON); - bind(new TypeLiteral(){}).to(ProfitBricksTemplateBuilderImpl.class); - - bind(new TypeLiteral>() { + bind(CreateNodesInGroupThenAddToSet.class).to(AssignDataCenterToTemplate.class).in(Scopes.SINGLETON); + + bind(new TypeLiteral>() { }).to(ProfitBricksComputeServiceAdapter.class); - bind(new TypeLiteral>() { - }).to(LocationToLocation.class); - - bind(new TypeLiteral>() { - }).to(DataCenterToLocation.class); - bind(new TypeLiteral>() { }).to(ServerToNodeMetadata.class); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/DataCenterToLocation.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/DataCenterToLocation.java deleted file mode 100644 index 93fb3a07cd..0000000000 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/DataCenterToLocation.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.profitbricks.compute.function; - -import static com.google.common.base.Preconditions.checkNotNull; - -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationBuilder; -import org.jclouds.domain.LocationScope; -import org.jclouds.profitbricks.domain.DataCenter; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableMap; -import com.google.inject.Inject; - -public class DataCenterToLocation implements Function { - - private final Function fnRegion; - - @Inject - DataCenterToLocation(Function fnRegion) { - this.fnRegion = fnRegion; - } - - @Override - public Location apply(DataCenter dataCenter) { - checkNotNull(dataCenter, "Null dataCenter"); - - LocationBuilder builder = new LocationBuilder() - .id(dataCenter.id()) - .description(dataCenter.name()) - .scope(LocationScope.ZONE) - .metadata(ImmutableMap.of( - "version", dataCenter.version(), - "state", dataCenter.state())); - if (dataCenter.location() != null) - builder.parent(fnRegion.apply(dataCenter.location())); - return builder.build(); - } -} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/LocationToLocation.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/LocationToLocation.java deleted file mode 100644 index 999069b726..0000000000 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/LocationToLocation.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.profitbricks.compute.function; - -import org.jclouds.domain.LocationBuilder; -import org.jclouds.domain.LocationScope; -import org.jclouds.location.suppliers.all.JustProvider; -import org.jclouds.profitbricks.domain.Location; - -import com.google.common.base.Function; -import com.google.common.collect.Iterables; -import com.google.inject.Inject; - -public class LocationToLocation implements Function { - - private final JustProvider justProvider; - - @Inject - LocationToLocation(JustProvider justProvider) { - this.justProvider = justProvider; - } - - @Override - public org.jclouds.domain.Location apply(Location in) { - return new LocationBuilder() - .id(in.getId()) - .description(in.getDescription()) - .scope(LocationScope.REGION) - .parent(Iterables.getOnlyElement(justProvider.get())) - .build(); - } - -} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ProvisionableToImage.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ProvisionableToImage.java index 4d0f511369..5b27370cba 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ProvisionableToImage.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ProvisionableToImage.java @@ -18,9 +18,13 @@ package org.jclouds.profitbricks.compute.function; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.find; +import static org.jclouds.location.predicates.LocationPredicates.idEquals; +import java.util.Set; import java.util.regex.Pattern; +import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.OperatingSystem; @@ -33,6 +37,7 @@ import org.jclouds.profitbricks.domain.Provisionable; import com.google.common.base.Function; import com.google.common.base.Strings; +import com.google.common.base.Supplier; import com.google.common.collect.ImmutableMap; import com.google.inject.Inject; @@ -44,9 +49,9 @@ public class ProvisionableToImage implements Function { private final SnapshotToImage fnSnapshotToImage; @Inject - ProvisionableToImage(Function fnRegion) { - this.fnImageToImage = new ImageToImage(fnRegion); - this.fnSnapshotToImage = new SnapshotToImage(fnRegion); + ProvisionableToImage(@Memoized Supplier> locations) { + this.fnImageToImage = new ImageToImage(locations); + this.fnSnapshotToImage = new SnapshotToImage(locations); } @Override @@ -83,16 +88,17 @@ public class ProvisionableToImage implements Function { private static final Pattern HAS_NUMBERS = Pattern.compile(".*\\d+.*"); - private final Function fnRegion; + private final Supplier> locations; - ImageToImage(Function fnRegion) { - this.fnRegion = fnRegion; + ImageToImage(Supplier> locations) { + this.locations = locations; } @Override public Image apply(org.jclouds.profitbricks.domain.Image from) { String desc = from.name(); OsFamily osFamily = parseOsFamily(desc, from.osType()); + Location location = find(locations.get(), idEquals(from.location().getId())); OperatingSystem os = OperatingSystem.builder() .description(osFamily.value()) @@ -104,7 +110,7 @@ public class ProvisionableToImage implements Function { return addTypeMetadata(new ImageBuilder() .ids(from.id()) .name(desc) - .location(fnRegion.apply(from.location())) + .location(location) .status(Image.Status.AVAILABLE) .operatingSystem(os)) .build(); @@ -159,16 +165,17 @@ public class ProvisionableToImage implements Function { private static class SnapshotToImage implements ImageFunction { - private final Function fnRegion; + private final Supplier> locations; - SnapshotToImage(Function fnRegion) { - this.fnRegion = fnRegion; + SnapshotToImage(Supplier> locations) { + this.locations = locations; } @Override public Image apply(Snapshot from) { String textToParse = from.name() + from.description(); OsFamily osFamily = parseOsFamily(textToParse, from.osType()); + Location location = find(locations.get(), idEquals(from.location().getId())); OperatingSystem os = OperatingSystem.builder() .description(osFamily.value()) @@ -181,7 +188,7 @@ public class ProvisionableToImage implements Function { .ids(from.id()) .name(from.name()) .description(from.description()) - .location(fnRegion.apply(from.location())) + .location(location) .status(mapStatus(from.state())) .operatingSystem(os)) .build(); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadata.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadata.java index 9a8d551ffd..9831c6f891 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadata.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadata.java @@ -18,18 +18,13 @@ package org.jclouds.profitbricks.compute.function; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Predicates.not; -import static org.jclouds.profitbricks.domain.OsType.LINUX; -import static org.jclouds.profitbricks.domain.OsType.WINDOWS; -import static org.jclouds.profitbricks.domain.Server.Status.BLOCKED; -import static org.jclouds.profitbricks.domain.Server.Status.CRASHED; -import static org.jclouds.profitbricks.domain.Server.Status.PAUSED; -import static org.jclouds.profitbricks.domain.Server.Status.RUNNING; -import static org.jclouds.profitbricks.domain.Server.Status.SHUTDOWN; -import static org.jclouds.profitbricks.domain.Server.Status.SHUTOFF; +import static com.google.common.collect.Iterables.find; +import static org.jclouds.location.predicates.LocationPredicates.idEquals; import java.util.List; import java.util.Set; +import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.HardwareBuilder; import org.jclouds.compute.domain.NodeMetadata; @@ -38,7 +33,10 @@ import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Processor; import org.jclouds.compute.domain.Volume; +import org.jclouds.compute.functions.GroupNamingConvention; import org.jclouds.domain.Location; +import org.jclouds.profitbricks.ProfitBricksApi; +import org.jclouds.profitbricks.domain.DataCenter; import org.jclouds.profitbricks.domain.Nic; import org.jclouds.profitbricks.domain.OsType; import org.jclouds.profitbricks.domain.Server; @@ -46,32 +44,30 @@ import org.jclouds.profitbricks.domain.Storage; import org.jclouds.util.InetAddresses2.IsPrivateIPAddress; import com.google.common.base.Function; -import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.inject.Inject; -import org.jclouds.collect.Memoized; -import org.jclouds.compute.functions.GroupNamingConvention; - public class ServerToNodeMetadata implements Function { private final Function fnVolume; - private final Supplier> locationSupply; + private final Supplier> locations; private final Function, List> fnCollectIps; + private final ProfitBricksApi api; private final GroupNamingConvention groupNamingConvention; @Inject ServerToNodeMetadata(Function fnVolume, - @Memoized Supplier> locationsSupply, + @Memoized Supplier> locations, + ProfitBricksApi api, GroupNamingConvention.Factory groupNamingConvention) { this.fnVolume = fnVolume; - this.locationSupply = locationsSupply; + this.locations = locations; + this.api = api; this.groupNamingConvention = groupNamingConvention.createWithoutPrefix(); this.fnCollectIps = new Function, List>() { - @Override public List apply(List in) { List ips = Lists.newArrayListWithExpectedSize(in.size()); @@ -85,17 +81,9 @@ public class ServerToNodeMetadata implements Function { @Override public NodeMetadata apply(final Server server) { checkNotNull(server, "Null server"); - - // Map fetched dataCenterId with actual populated object - Location location = null; - if (server.dataCenter() != null) - location = Iterables.find(locationSupply.get(), new Predicate() { - - @Override - public boolean apply(Location t) { - return t.getId().equals(server.dataCenter().id()); - } - }); + // Location is not populated in the datacenter on a server response + DataCenter dataCenter = api.dataCenterApi().getDataCenter(server.dataCenter().id()); + Location location = find(locations.get(), idEquals(dataCenter.location().getId())); float size = 0f; List volumes = Lists.newArrayList(); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/strategy/AssignDataCenterToTemplate.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/strategy/AssignDataCenterToTemplate.java new file mode 100644 index 0000000000..f7db219005 --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/strategy/AssignDataCenterToTemplate.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.profitbricks.compute.strategy; + +import static com.google.common.collect.Iterables.find; +import static org.jclouds.Constants.PROPERTY_USER_THREADS; +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_PREDICATE_DATACENTER; + +import java.util.Map; +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.compute.config.CustomizationResponse; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.functions.GroupNamingConvention; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; +import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap; +import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet; +import org.jclouds.logging.Logger; +import org.jclouds.profitbricks.ProfitBricksApi; +import org.jclouds.profitbricks.domain.DataCenter; +import org.jclouds.profitbricks.domain.Location; + +import com.google.common.annotations.Beta; +import com.google.common.base.Predicate; +import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; + +/** + * Attempts to find a valid datacenter in the configured location where the + * servers will be deployed. If no datacenter is found, one will be created. + */ +@Beta +@Singleton +public class AssignDataCenterToTemplate extends CreateNodesWithGroupEncodedIntoNameThenAddToSet { + + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + private final ProfitBricksApi api; + private final Predicate waitDcUntilAvailable; + + @Inject + protected AssignDataCenterToTemplate( + CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy, + ListNodesStrategy listNodesStrategy, + GroupNamingConvention.Factory namingConvention, + @Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, + CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory, + ProfitBricksApi api, @Named(POLL_PREDICATE_DATACENTER) Predicate waitDcUntilAvailable) { + super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor, + customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory); + this.api = api; + this.waitDcUntilAvailable = waitDcUntilAvailable; + } + + @Override + public Map> execute(String group, int count, final Template template, + Set goodNodes, Map badNodes, + Multimap customizationResponses) { + + logger.info(">> looking for a datacenter in %s", template.getLocation().getId()); + + // Try to find an existing datacenter in the selected location + DataCenter dataCenter = find(api.dataCenterApi().getAllDataCenters(), new Predicate() { + @Override + public boolean apply(DataCenter input) { + // The location field is not populated when getting the list of datacenters + DataCenter details = api.dataCenterApi().getDataCenter(input.id()); + return details != null && template.getLocation().getId().equals(details.location().getId()); + } + }, null); + + if (dataCenter == null) { + String name = namingConvention.create().sharedNameForGroup(group); + logger.info(">> no datacenter was found. Creating a new one named %s in %s...", name, template.getLocation() + .getId()); + dataCenter = api.dataCenterApi().createDataCenter( + DataCenter.Request.creatingPayload(name, Location.fromId(template.getLocation().getId()))); + waitDcUntilAvailable.apply(dataCenter.id()); + } + + return super.execute(group, count, new TemplateWithDataCenter(template, dataCenter), goodNodes, badNodes, + customizationResponses); + } + +} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/strategy/TemplateWithDataCenter.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/strategy/TemplateWithDataCenter.java new file mode 100644 index 0000000000..dd689d54ed --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/strategy/TemplateWithDataCenter.java @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.profitbricks.compute.strategy; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Location; +import org.jclouds.profitbricks.domain.DataCenter; + +import com.google.common.annotations.Beta; + +/** + * Extends the default {@link Template} object to provide the {@link DataCenter} + * where the nodes must be created. + */ +@Beta +public class TemplateWithDataCenter implements Template { + + private final Template delegate; + + private final DataCenter dataCenter; + + // For internal use only + TemplateWithDataCenter(Template delegate, DataCenter dataCenter) { + this.delegate = checkNotNull(delegate, "delegate cannot be null"); + this.dataCenter = checkNotNull(dataCenter, "dataCenter cannot be null"); + } + + public DataCenter getDataCenter() { + return dataCenter; + } + + public Template clone() { + return new TemplateWithDataCenter(delegate.clone(), dataCenter); + } + + public Hardware getHardware() { + return delegate.getHardware(); + } + + public Image getImage() { + return delegate.getImage(); + } + + public Location getLocation() { + return delegate.getLocation(); + } + + public TemplateOptions getOptions() { + return delegate.getOptions(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((dataCenter == null) ? 0 : dataCenter.hashCode()); + result = prime * result + ((delegate == null) ? 0 : delegate.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TemplateWithDataCenter other = (TemplateWithDataCenter) obj; + if (dataCenter == null) { + if (other.dataCenter != null) + return false; + } else if (!dataCenter.equals(other.dataCenter)) + return false; + if (delegate == null) { + if (other.delegate != null) + return false; + } else if (!delegate.equals(other.delegate)) + return false; + return true; + } + + @Override + public String toString() { + return delegate.toString(); + } + +} diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceLiveTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceLiveTest.java index dcb1edc9e3..0061090eec 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceLiveTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceLiveTest.java @@ -16,94 +16,25 @@ */ package org.jclouds.profitbricks.compute; -import static org.jclouds.profitbricks.BaseProfitBricksLiveTest.testLocation; -import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_PREDICATE_DATACENTER; - -import java.util.Objects; - -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; -import com.google.common.collect.FluentIterable; - +import org.jclouds.compute.domain.ExecResponse; import org.jclouds.compute.domain.NodeMetadata; -import org.testng.annotations.Test; - import org.jclouds.compute.internal.BaseComputeServiceLiveTest; +import org.jclouds.logging.config.LoggingModule; +import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; import org.jclouds.sshj.config.SshjSshClientModule; +import org.testng.annotations.Test; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.inject.Key; import com.google.inject.Module; -import com.google.inject.TypeLiteral; -import com.google.inject.name.Names; - -import org.jclouds.compute.domain.ExecResponse; -import org.jclouds.logging.config.LoggingModule; -import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; -import org.jclouds.profitbricks.ProfitBricksApi; -import org.jclouds.profitbricks.domain.DataCenter; -import org.jclouds.profitbricks.features.DataCenterApi; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; @Test(groups = "live", singleThreaded = true, testName = "ProfitBricksComputeServiceLiveTest") public class ProfitBricksComputeServiceLiveTest extends BaseComputeServiceLiveTest { - private static final String TEST_DC_NAME = "computeServiceLiveTest-" + System.currentTimeMillis(); - - private DataCenter dataCenter; - public ProfitBricksComputeServiceLiveTest() { provider = "profitbricks"; } - @BeforeClass - @Override - public void setupContext() { - super.setupContext(); - - final DataCenterApi api = getDataCenterApi(); - final Predicate predicate = getDataCenterPredicate(); - dataCenter = FluentIterable.from(api.getAllDataCenters()).firstMatch(new Predicate() { - - @Override - public boolean apply(DataCenter input) { - boolean match = Objects.equals(input.name(), TEST_DC_NAME); - if (match && input.location() == testLocation) - return predicate.apply(input.id()); - return match; - } - }).or(new Supplier() { - - @Override - public DataCenter get() { - DataCenter dataCenter = api.createDataCenter( - DataCenter.Request.creatingPayload(TEST_DC_NAME, testLocation)); - predicate.apply(dataCenter.id()); - - return api.getDataCenter(dataCenter.id()); - } - }); - } - - @AfterClass(groups = {"integration", "live"}, alwaysRun = true) - @Override - protected void tearDownContext() { - super.tearDownContext(); - if (dataCenter != null) - getDataCenterApi().deleteDataCenter(dataCenter.id()); - } - - private Predicate getDataCenterPredicate() { - return client.getContext().utils().injector().getInstance(Key.get(new TypeLiteral>() { - }, Names.named(POLL_PREDICATE_DATACENTER))); - } - - private DataCenterApi getDataCenterApi() { - return client.getContext().unwrapApi(ProfitBricksApi.class).dataCenterApi(); - } - @Override protected Module getSshModule() { return new SshjSshClientModule(); diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/DataCenterToLocationTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/DataCenterToLocationTest.java deleted file mode 100644 index 7dcf69cdc5..0000000000 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/DataCenterToLocationTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.profitbricks.compute.function; - -import static org.testng.Assert.assertEquals; - -import java.net.URI; - -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationBuilder; -import org.jclouds.domain.LocationScope; -import org.jclouds.location.suppliers.all.JustProvider; -import org.jclouds.profitbricks.ProfitBricksProviderMetadata; -import org.jclouds.profitbricks.domain.DataCenter; -import org.jclouds.profitbricks.domain.ProvisioningState; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - -import com.google.common.base.Suppliers; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; - -@Test(groups = "unit", testName = "DataCenterToLocationTest") -public class DataCenterToLocationTest { - - private DataCenterToLocation fnLocation; - private LocationToLocation fnRegion; - - @BeforeTest - public void setup() { - ProfitBricksProviderMetadata metadata = new ProfitBricksProviderMetadata(); - JustProvider justProvider = new JustProvider(metadata.getId(), Suppliers.ofInstance( - URI.create(metadata.getEndpoint())), ImmutableSet.of()); - this.fnRegion = new LocationToLocation(justProvider); - this.fnLocation = new DataCenterToLocation(fnRegion); - } - - @Test - public void testDataCenterToLocation() { - DataCenter dataCenter = DataCenter.builder() - .id("12345678-abcd-efgh-ijkl-987654321000") - .version(10) - .name("JClouds-DC") - .state(ProvisioningState.AVAILABLE) - .location(org.jclouds.profitbricks.domain.Location.DE_FRA) - .build(); - - Location actual = fnLocation.apply(dataCenter); - - Location expected = new LocationBuilder() - .id(dataCenter.id()) - .description(dataCenter.name()) - .scope(LocationScope.ZONE) - .metadata(ImmutableMap.of( - "version", dataCenter.version(), - "state", dataCenter.state())) - .parent(fnRegion.apply(org.jclouds.profitbricks.domain.Location.DE_FRA)) - .build(); - - assertEquals(actual, expected); - } - -} diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/LocationToLocationTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/LocationToLocationTest.java deleted file mode 100644 index 3967cf580e..0000000000 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/LocationToLocationTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jclouds.profitbricks.compute.function; - -import static org.testng.Assert.assertEquals; - -import java.net.URI; - -import org.jclouds.domain.LocationBuilder; -import org.jclouds.domain.LocationScope; -import org.jclouds.location.suppliers.all.JustProvider; -import org.jclouds.profitbricks.ProfitBricksProviderMetadata; -import org.jclouds.profitbricks.domain.Location; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - -import com.google.common.base.Suppliers; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; - -@Test(groups = "unit", testName = "LocationToLocationTest") -public class LocationToLocationTest { - - private LocationToLocation fnRegion; - private JustProvider justProvider; - - @BeforeTest - public void setup() { - ProfitBricksProviderMetadata metadata = new ProfitBricksProviderMetadata(); - this.justProvider = new JustProvider(metadata.getId(), Suppliers.ofInstance( - URI.create(metadata.getEndpoint())), ImmutableSet.of()); - this.fnRegion = new LocationToLocation(justProvider); - } - - @Test - public void testLocationToLocation() { - Location[] locations = Location.values(); - for (Location loc : locations) { - org.jclouds.domain.Location actual = fnRegion.apply(loc); - org.jclouds.domain.Location expected = new LocationBuilder() - .id(loc.getId()).description(loc.getDescription()).scope(LocationScope.REGION) - .parent(Iterables.getOnlyElement(justProvider.get())).build(); - - assertEquals(actual, expected); - } - - } -} diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ProvisionableToImageTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ProvisionableToImageTest.java index f27b302dad..ddecc8325b 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ProvisionableToImageTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ProvisionableToImageTest.java @@ -16,18 +16,20 @@ */ package org.jclouds.profitbricks.compute.function; +import static org.jclouds.profitbricks.domain.Location.US_LAS; import static org.testng.Assert.assertEquals; -import java.net.URI; +import java.util.Calendar; import java.util.Date; +import java.util.Set; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily; -import org.jclouds.location.suppliers.all.JustProvider; -import org.jclouds.profitbricks.ProfitBricksProviderMetadata; -import org.jclouds.profitbricks.domain.Location; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; import org.jclouds.profitbricks.domain.OsType; import org.jclouds.profitbricks.domain.ProvisioningState; import org.jclouds.profitbricks.domain.Snapshot; @@ -42,15 +44,13 @@ import com.google.common.collect.ImmutableSet; public class ProvisionableToImageTest { private ProvisionableToImage fnImage; - private LocationToLocation fnRegion; + + private final Location location = new LocationBuilder().id("us/las").description("us/las").scope(LocationScope.ZONE) + .parent(new LocationBuilder().id("us").description("us").scope(LocationScope.REGION).build()).build(); @BeforeTest public void setup() { - ProfitBricksProviderMetadata metadata = new ProfitBricksProviderMetadata(); - JustProvider justProvider = new JustProvider(metadata.getId(), Suppliers.ofInstance( - URI.create(metadata.getEndpoint())), ImmutableSet.of()); - this.fnRegion = new LocationToLocation(justProvider); - this.fnImage = new ProvisionableToImage(fnRegion); + this.fnImage = new ProvisionableToImage(Suppliers.> ofInstance(ImmutableSet.of(location))); } @Test @@ -66,7 +66,7 @@ public class ProvisionableToImageTest { .name("Ubuntu-14.04-LTS-server-2015-01-01") .size(2048f) .type(org.jclouds.profitbricks.domain.Image.Type.HDD) - .location(Location.US_LAS) + .location(US_LAS) .isNicHotPlug(true) .isNicHotUnPlug(true) .osType(OsType.LINUX) @@ -81,7 +81,7 @@ public class ProvisionableToImageTest { Image expected = new ImageBuilder() .ids(image.id()) .name(image.name()) - .location(fnRegion.apply(Location.US_LAS)) + .location(location) .status(Image.Status.AVAILABLE) .operatingSystem(OperatingSystem.builder() .description("UBUNTU") @@ -103,7 +103,7 @@ public class ProvisionableToImageTest { .name("Fedora-19-server-2015-01-01") .size(2048f) .type(org.jclouds.profitbricks.domain.Image.Type.HDD) - .location(Location.DE_FRA) + .location(US_LAS) .osType(OsType.LINUX) .build(); @@ -112,7 +112,7 @@ public class ProvisionableToImageTest { Image expected1 = new ImageBuilder() .ids(image1.id()) .name(image1.name()) - .location(fnRegion.apply(image1.location())) + .location(location) .status(Image.Status.AVAILABLE) .operatingSystem(OperatingSystem.builder() .description("FEDORA") @@ -131,7 +131,7 @@ public class ProvisionableToImageTest { .name("clearos-community-6.5.0-x86_64.iso") .size(2048f) .type(org.jclouds.profitbricks.domain.Image.Type.CDROM) - .location(Location.DE_FKB) + .location(US_LAS) .osType(OsType.LINUX) .build(); @@ -140,7 +140,7 @@ public class ProvisionableToImageTest { Image expected2 = new ImageBuilder() .ids(image2.id()) .name(image2.name()) - .location(fnRegion.apply(image2.location())) + .location(location) .status(Image.Status.AVAILABLE) .operatingSystem(OperatingSystem.builder() .description("UNRECOGNIZED") @@ -159,7 +159,7 @@ public class ProvisionableToImageTest { .name("windows-2008-r2-server-setup.iso") .size(2048f) .type(org.jclouds.profitbricks.domain.Image.Type.CDROM) - .location(Location.US_LASDEV) + .location(US_LAS) .osType(OsType.WINDOWS) .build(); @@ -168,7 +168,7 @@ public class ProvisionableToImageTest { Image expected3 = new ImageBuilder() .ids(image3.id()) .name(image3.name()) - .location(fnRegion.apply(image3.location())) + .location(location) .status(Image.Status.AVAILABLE) .operatingSystem(OperatingSystem.builder() .description("WINDOWS") @@ -185,6 +185,10 @@ public class ProvisionableToImageTest { @Test public void testSnapshotToImage() { + Calendar calendar = Calendar.getInstance(); + calendar.set(2015, 4, 13); + Date date = calendar.getTime(); + Snapshot snapshot1 = Snapshot.builder() .isBootable(true) .isCpuHotPlug(true) @@ -195,13 +199,13 @@ public class ProvisionableToImageTest { .name("placeholder-snapshot-04/13/2015") .description("Created from \"placeholder\" in Data Center \"sbx-computeservice\"") .size(2048f) - .location(Location.US_LAS) + .location(US_LAS) .isNicHotPlug(true) .isNicHotUnPlug(true) .osType(OsType.LINUX) .isRamHotPlug(true) .isRamHotUnPlug(false) - .creationTime(new Date(2015, 4, 13)) + .creationTime(date) .lastModificationTime(new Date()) .state(ProvisioningState.AVAILABLE) .build(); @@ -211,7 +215,7 @@ public class ProvisionableToImageTest { Image expected1 = new ImageBuilder() .ids(snapshot1.id()) .name(snapshot1.name()) - .location(fnRegion.apply(Location.US_LAS)) + .location(location) .status(Image.Status.AVAILABLE) .operatingSystem(OperatingSystem.builder() .description(snapshot1.description()) @@ -233,13 +237,13 @@ public class ProvisionableToImageTest { .name("jclouds-ubuntu14.10-template") .description("Created from \"jclouds-ubuntu14.10 Storage\" in Data Center \"jclouds-computeservice\"") .size(10240f) - .location(Location.DE_FKB) + .location(US_LAS) .isNicHotPlug(true) .isNicHotUnPlug(true) .osType(OsType.LINUX) .isRamHotPlug(true) .isRamHotUnPlug(false) - .creationTime(new Date(2015, 4, 13)) + .creationTime(date) .lastModificationTime(new Date()) .state(ProvisioningState.INPROCESS) .build(); @@ -249,7 +253,7 @@ public class ProvisionableToImageTest { Image expected2 = new ImageBuilder() .ids(snapshot2.id()) .name(snapshot2.name()) - .location(fnRegion.apply(Location.DE_FKB)) + .location(location) .status(Image.Status.PENDING) .operatingSystem(OperatingSystem.builder() .description("ubuntu") diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadataTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadataTest.java index 7f1da3989b..60f43ec2bf 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadataTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadataTest.java @@ -16,11 +16,16 @@ */ package org.jclouds.profitbricks.compute.function; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.jclouds.profitbricks.domain.Location.DE_FRA; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import java.util.Set; +import org.easymock.EasyMock; import org.jclouds.compute.domain.HardwareBuilder; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadataBuilder; @@ -33,6 +38,7 @@ import org.jclouds.compute.functions.GroupNamingConvention; import org.jclouds.domain.Location; import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; +import org.jclouds.profitbricks.ProfitBricksApi; import org.jclouds.profitbricks.ProfitBricksApiMetadata; import org.jclouds.profitbricks.domain.AvailabilityZone; import org.jclouds.profitbricks.domain.DataCenter; @@ -41,12 +47,13 @@ import org.jclouds.profitbricks.domain.OsType; import org.jclouds.profitbricks.domain.ProvisioningState; import org.jclouds.profitbricks.domain.Server; import org.jclouds.profitbricks.domain.Storage; -import org.testng.annotations.BeforeTest; +import org.jclouds.profitbricks.features.DataCenterApi; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import com.google.inject.Guice; @@ -56,25 +63,25 @@ import com.google.inject.name.Names; public class ServerToNodeMetadataTest { private ServerToNodeMetadata fnNodeMetadata; + + private ProfitBricksApi api; + + private DataCenterApi dataCenterApi; - @BeforeTest + @BeforeMethod public void setup() { Supplier> locationsSupply = new Supplier>() { - @Override public Set get() { return ImmutableSet.of( new LocationBuilder() - .id("12345678-abcd-efgh-ijkl-987654321000") - .description("JClouds-DC") - .scope(LocationScope.REGION) - .metadata(ImmutableMap.of( - "version", "10", - "state", "AVAILABLE")) + .id("de/fra") + .description("de/fra") + .scope(LocationScope.ZONE) .parent(new LocationBuilder() - .id("de/fra") - .description("Germany, Frankfurt (M)") - .scope(LocationScope.PROVIDER) + .id("de") + .description("de") + .scope(LocationScope.REGION) .build()) .build()); } @@ -86,15 +93,31 @@ public class ServerToNodeMetadataTest { Names.bindProperties(binder(), new ProfitBricksApiMetadata().getDefaultProperties()); } }).getInstance(GroupNamingConvention.Factory.class); + + dataCenterApi = EasyMock.createMock(DataCenterApi.class); + api = EasyMock.createMock(ProfitBricksApi.class); - this.fnNodeMetadata = new ServerToNodeMetadata(new StorageToVolume(), locationsSupply, namingConvention); + expect(dataCenterApi.getDataCenter("mock")).andReturn( + DataCenter.builder().id("mock").version(10).location(DE_FRA).build()); + expect(api.dataCenterApi()).andReturn(dataCenterApi); + + replay(dataCenterApi, api); + + this.fnNodeMetadata = new ServerToNodeMetadata(new StorageToVolume(), locationsSupply, api, namingConvention); + } + + @AfterMethod + public void tearDown() { + verify(api, dataCenterApi); } @Test public void testServerToNodeMetadata() { Server server = Server.builder() .dataCenter(DataCenter.builder() - .id("12345678-abcd-efgh-ijkl-987654321000").version(10) + .id("mock") + .version(10) + .location(org.jclouds.profitbricks.domain.Location.DE_FRA) .build()) .id("qwertyui-qwer-qwer-qwer-qwertyyuiiop") .name("mock-facebook-node") @@ -164,16 +187,13 @@ public class ServerToNodeMetadataTest { .family(OsFamily.LINUX) .build()) .location(new LocationBuilder() - .id("12345678-abcd-efgh-ijkl-987654321000") - .description("JClouds-DC") - .scope(LocationScope.REGION) - .metadata(ImmutableMap.of( - "version", "10", - "state", "AVAILABLE")) + .id("de/fra") + .description("de/fra") + .scope(LocationScope.ZONE) .parent(new LocationBuilder() - .id("de/fra") - .description("Germany, Frankfurt (M)") - .scope(LocationScope.PROVIDER) + .id("de") + .description("de") + .scope(LocationScope.REGION) .build()) .build()) .publicAddresses(ImmutableList.of("173.252.120.6"))