From ed247e7dea753daa94c8f0b228804f6947b694e7 Mon Sep 17 00:00:00 2001 From: Reijhanniel Jearl Campos Date: Mon, 29 Jun 2015 11:13:21 +0800 Subject: [PATCH] JCLOUDS-702: JClouds ProfitBricks provider - ComputeServiceAdapter --- providers/profitbricks/README.md | 63 +++ providers/profitbricks/pom.xml | 1 - .../profitbricks/ProfitBricksApiMetadata.java | 7 +- .../ProfitBricksProviderMetadata.java | 25 +- .../CreateDataCenterRequestBinder.java | 2 +- .../CreateLoadBalancerRequestBinder.java | 3 +- .../DeregisterLoadBalancerRequestBinder.java | 3 +- .../RegisterLoadBalancerRequestBinder.java | 3 +- .../snapshot/CreateSnapshotRequestBinder.java | 12 +- .../RollbackSnapshotRequestBinder.java | 30 +- .../snapshot/UpdateSnapshotRequestBinder.java | 32 +- .../ProfitBricksComputeServiceAdapter.java | 488 ++++++++++++++++++ .../compute/concurrent/ProvisioningJob.java | 62 +++ .../concurrent/ProvisioningManager.java | 88 ++++ ...ofitBricksComputeServiceContextModule.java | 147 ++++++ .../function/DataCenterToLocation.java | 54 ++ .../compute/function/LocationToLocation.java | 47 ++ .../function/ProvisionableToImage.java | 215 ++++++++ .../function/ServerToNodeMetadata.java | 180 +++++++ .../compute/function/StorageToVolume.java | 47 ++ .../ProvisioningStatusPollingPredicate.java | 32 +- .../config/ProfitBricksComputeProperties.java | 31 ++ .../jclouds/profitbricks/domain/Firewall.java | 6 +- .../jclouds/profitbricks/domain/Image.java | 129 +---- .../profitbricks/domain/LoadBalancer.java | 46 +- .../jclouds/profitbricks/domain/Location.java | 20 +- .../org/jclouds/profitbricks/domain/Nic.java | 8 +- .../jclouds/profitbricks/domain/Server.java | 114 ++-- .../jclouds/profitbricks/domain/Snapshot.java | 429 ++++++--------- .../jclouds/profitbricks/domain/Storage.java | 13 +- .../domain/internal/HotPluggable.java | 102 ++++ .../domain/internal/Provisionable.java | 67 +++ .../internal/ServerCommonProperties.java | 22 +- .../features/LoadBalancerApi.java | 2 +- .../firewall/FirewallListResponseHandler.java | 6 +- .../ipblock/IpBlockListResponseHandler.java | 6 +- .../BaseLoadBalancerResponseHandler.java | 33 +- .../LoadBalancerListResponseHandler.java | 25 +- .../LoadBalancerResponseHandler.java | 13 +- .../server/BaseServerResponseHandler.java | 38 +- .../server/ServerInfoResponseHandler.java | 7 +- .../server/ServerListResponseHandler.java | 24 +- .../snapshot/BaseSnapshotResponseHandler.java | 48 +- .../snapshot/SnapshotListResponseHandler.java | 12 +- .../snapshot/SnapshotResponseHandler.java | 11 +- .../storage/BaseStorageResponseHandler.java | 12 +- .../storage/StorageInfoResponseHandler.java | 7 +- .../storage/StorageListResponseHandler.java | 12 +- .../jclouds/profitbricks/util/Passwords.java | 64 +++ .../CreateSnapshotRequestBinderTest.java | 14 +- .../RollbackSnapshotRequestBinderTest.java | 16 +- ...itBricksComputeServiceAdapterLiveTest.java | 74 +++ .../ProfitBricksTemplateBuilderLiveTest.java | 37 ++ .../concurrent/ProvisioningManagerTest.java | 118 +++++ .../function/DataCenterToLocationTest.java | 77 +++ .../function/LocationToLocationTest.java | 62 +++ .../function/ProvisionableToImageTest.java | 260 ++++++++++ .../function/ServerToNodeMetadataTest.java | 184 +++++++ .../compute/function/StorageToVolumeTest.java | 61 +++ ...rovisioningStatusPollingPredicateTest.java | 6 +- .../features/DrivesApiLiveTest.java | 9 +- .../features/FirewallApiLiveTest.java | 2 +- .../features/IpBlockApiLiveTest.java | 2 +- .../features/IpBlockApiMockTest.java | 4 +- .../features/LoadbalancerApiLiveTest.java | 2 +- .../features/LoadbalancerApiMockTest.java | 2 +- .../features/SnapshotApiLiveTest.java | 32 +- .../features/SnapshotApiMockTest.java | 174 ++++--- .../DataCenterInfoResponseHandlerTest.java | 22 +- .../image/ImageListResponseHandlerTest.java | 6 +- .../LoadBalancerListResponseHandlerTest.java | 75 ++- .../LoadBalancerResponseHandlerTest.java | 28 +- .../server/ServerInfoResponseHandlerTest.java | 20 +- .../server/ServerListResponseHandlerTest.java | 32 +- .../SnapshotListResponseHandlerTest.java | 89 ++-- .../snapshot/SnapshotResponseHandlerTest.java | 49 +- .../StorageInfoResponseHandlerTest.java | 13 +- .../StorageListResponseHandlerTest.java | 17 +- .../profitbricks/util/PasswordsTest.java | 53 ++ .../datacenter/datacenter-deleted.xml | 14 +- .../datacenter/datacenter-not-found.xml | 28 +- .../datacenter/datacenter-state-inprocess.xml | 10 +- .../resources/datacenter/datacenter-state.xml | 10 +- .../src/test/resources/drives/drives-add.xml | 18 +- .../test/resources/drives/drives-remove.xml | 18 +- .../resources/firewall/firewall-activate.xml | 18 +- .../resources/firewall/firewall-addtonic.xml | 40 +- .../firewall/firewall-deactivate.xml | 18 +- .../resources/firewall/firewall-delete.xml | 18 +- .../resources/firewall/firewall-remove.xml | 18 +- .../src/test/resources/firewall/firewall.xml | 40 +- .../resources/ipblock/ipblock-addtonic.xml | 18 +- .../resources/ipblock/ipblock-release.xml | 14 +- .../ipblock/ipblock-removefromnic.xml | 18 +- .../resources/ipblock/ipblock-reserve.xml | 20 +- .../src/test/resources/ipblock/ipblock.xml | 30 +- .../loadbalancer/loadbalancer-create.xml | 4 +- .../loadbalancer/loadbalancer-delete.xml | 18 +- .../loadbalancer/loadbalancer-deregister.xml | 8 +- .../loadbalancer/loadbalancer-register.xml | 8 +- .../loadbalancer/loadbalancer-update.xml | 4 +- .../resources/loadbalancer/loadbalancer.xml | 2 +- .../resources/loadbalancer/loadbalancers.xml | 4 +- .../src/test/resources/server/server.xml | 4 +- .../src/test/resources/snapshot/snapshots.xml | 38 +- 105 files changed, 3641 insertions(+), 1187 deletions(-) create mode 100644 providers/profitbricks/README.md create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapter.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningJob.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningManager.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/config/ProfitBricksComputeServiceContextModule.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/DataCenterToLocation.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/LocationToLocation.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ProvisionableToImage.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadata.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/StorageToVolume.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/config/ProfitBricksComputeProperties.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/HotPluggable.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/Provisionable.java create mode 100644 providers/profitbricks/src/main/java/org/jclouds/profitbricks/util/Passwords.java create mode 100644 providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapterLiveTest.java create mode 100644 providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksTemplateBuilderLiveTest.java create mode 100644 providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningManagerTest.java create mode 100644 providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/DataCenterToLocationTest.java create mode 100644 providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/LocationToLocationTest.java create mode 100644 providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ProvisionableToImageTest.java create mode 100644 providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadataTest.java create mode 100644 providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/StorageToVolumeTest.java create mode 100644 providers/profitbricks/src/test/java/org/jclouds/profitbricks/util/PasswordsTest.java diff --git a/providers/profitbricks/README.md b/providers/profitbricks/README.md new file mode 100644 index 0000000000..09c367a3ec --- /dev/null +++ b/providers/profitbricks/README.md @@ -0,0 +1,63 @@ +# jclouds ProfitBricks + +## Terms +Like any cloud provider, ProfitBricks has its own set of terms in cloud computing. To abstract this into jclouds' Compute interface, these terms were associated: + +- Node - composite instance of `Server` and `Storage` +- Image - both *user-uploaded* and *provided* `Images`; and `Snapshots` +- Location - `DataCenters` and `Region` (Las Vegas, Frankfurt, etc.) +- Hardware - number of cores, RAM size and storage size + +## Getting Started + +Assuming that there's **atleast one** datacenter existing in your account, the provider needs only an *identity* (your ProfitBricks email), and *credentials* (password) to provision a `Node`, by using a ProfitBricks-provided ubuntu-12.04 image as a template. + +```java +ComputeService compute = ContextBuilder.newBuilder( "profitbricks" ) + .credentials( "profitbricks email", "password" ) + .buildView( ComputeServiceContext.class ) + .getComputeService(); +``` + + +This works well; however, we won't be able to use jclouds' ability to execute *scripts* on a remote node. This is because, ProfitBricks' default images require users to change passwords upon first log in. + +To enable jclouds to execute script, we need to use a custom image. The easiest way to do this is via ProfitBricks snapshot: + +- Go to your [DCD](https://my.profitbricks.com/dashboard/). +- Provision a server + storage, and connect it to the internet. Upon success, you will receive an email containing the credentials needed to login to your server. +- Login to your server, and change the password, as requested. + +``` +~ ssh root@ +... +Changing password for root. +(current) UNIX password: +Enter new UNIX password: +Retype new UNIX password: +~ root@ubuntu:~# exit + +``` + +- Go back to the DCD, and *make a snapshot* of the storage. Put a descriptive name. +- Configure jclouds to use this *snapshot*. + +```java +Template template = compute.templateBuilder() + .imageNameMatches( "" ) + .options( compute.templateOptions() + .overrideLoginUser( "root" ) // unless you changed the user + .overrideLoginPassword( "" )) + // more options, as you need + .build(); + +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 diff --git a/providers/profitbricks/pom.xml b/providers/profitbricks/pom.xml index 84f49b4ddf..9311e4823a 100644 --- a/providers/profitbricks/pom.xml +++ b/providers/profitbricks/pom.xml @@ -36,7 +36,6 @@ FIXME FIXME 1.3 - org.jclouds.profitbricks*;version="${project.version}" org.jclouds.labs*;version="${project.version}", diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksApiMetadata.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksApiMetadata.java index 205b246a82..2973f4a991 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksApiMetadata.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksApiMetadata.java @@ -19,8 +19,10 @@ package org.jclouds.profitbricks; import java.net.URI; import java.util.Properties; +import org.jclouds.profitbricks.compute.config.ProfitBricksComputeServiceContextModule; import org.jclouds.profitbricks.config.ProfitBricksHttpApiModule; import org.jclouds.apis.ApiMetadata; +import org.jclouds.compute.ComputeServiceContext; import org.jclouds.profitbricks.config.ProfitBricksHttpApiModule.ProfitBricksHttpCommandExecutorServiceModule; import org.jclouds.rest.internal.BaseHttpApiMetadata; @@ -60,11 +62,12 @@ public class ProfitBricksApiMetadata extends BaseHttpApiMetadata>of( ProfitBricksHttpApiModule.class, - ProfitBricksHttpCommandExecutorServiceModule.class + ProfitBricksHttpCommandExecutorServiceModule.class, + ProfitBricksComputeServiceContextModule.class )); } 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 9ecfbc1a0e..ed6c556ef5 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksProviderMetadata.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/ProfitBricksProviderMetadata.java @@ -16,8 +16,17 @@ */ package org.jclouds.profitbricks; +import static org.jclouds.Constants.PROPERTY_CONNECTION_TIMEOUT; +import static org.jclouds.Constants.PROPERTY_SO_TIMEOUT; +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_PERIOD; +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_MAX_PERIOD; +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_TIMEOUT; + 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; @@ -41,6 +50,19 @@ public class ProfitBricksProviderMetadata extends BaseProviderMetadata { return new Builder(); } + public static Properties defaultProperties() { + Properties properties = ProfitBricksApiMetadata.defaultProperties(); + long defaultTimeout = 60l * 60l; // 1 hour + properties.put(POLL_TIMEOUT, defaultTimeout); + properties.put(POLL_PERIOD, 2l); + properties.put(POLL_MAX_PERIOD, 2l * 10l); + + properties.put(PROPERTY_SO_TIMEOUT, 60000 * 5); + properties.put(PROPERTY_CONNECTION_TIMEOUT, 60000 * 5); + + return properties; + } + public static class Builder extends BaseProviderMetadata.Builder { protected Builder() { @@ -49,7 +71,8 @@ public class ProfitBricksProviderMetadata extends BaseProviderMetadata { .homepage(URI.create("http://www.profitbricks.com")) .console(URI.create("https://my.profitbricks.com/dashboard/dcdr2/")) .linkedServices("profitbricks") - .apiMetadata(new ProfitBricksApiMetadata()); + .apiMetadata(new ProfitBricksApiMetadata()) + .defaultProperties(ProfitBricksProviderMetadata.defaultProperties()); } @Override diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/datacenter/CreateDataCenterRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/datacenter/CreateDataCenterRequestBinder.java index 8a07b0aae7..1873f31f00 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/datacenter/CreateDataCenterRequestBinder.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/datacenter/CreateDataCenterRequestBinder.java @@ -35,7 +35,7 @@ public class CreateDataCenterRequestBinder extends BaseProfitBricksRequestBinder requestBuilder.append("") .append("") .append(format("%s", payload.name())) - .append(format("%s", payload.location().value())) + .append(format("%s", payload.location().getId())) .append("") .append(""); return requestBuilder.toString(); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/CreateLoadBalancerRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/CreateLoadBalancerRequestBinder.java index 23e121eb54..90eb93f603 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/CreateLoadBalancerRequestBinder.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/CreateLoadBalancerRequestBinder.java @@ -39,9 +39,8 @@ public class CreateLoadBalancerRequestBinder extends BaseProfitBricksRequestBind .append(format("%s", payload.loadBalancerAlgorithm())) .append(format("%s", payload.ip())) .append(format("%s", payload.lanId())); - for (String serverId : payload.serverIds()) { + for (String serverId : payload.serverIds()) requestBuilder.append(format("%s", serverId)); - } requestBuilder .append("") .append(""); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/DeregisterLoadBalancerRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/DeregisterLoadBalancerRequestBinder.java index 92f28681c5..ba237c40b5 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/DeregisterLoadBalancerRequestBinder.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/DeregisterLoadBalancerRequestBinder.java @@ -33,9 +33,8 @@ public class DeregisterLoadBalancerRequestBinder extends BaseProfitBricksRequest protected String createPayload(LoadBalancer.Request.DeregisterPayload payload) { requestBuilder.append("") .append(""); - for (String s : payload.serverIds()) { + for (String s : payload.serverIds()) requestBuilder.append(format("%s", s)); - } requestBuilder.append(format("%s", payload.id())) .append("") .append(""); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/RegisterLoadBalancerRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/RegisterLoadBalancerRequestBinder.java index 2e437f0e78..21f1d84907 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/RegisterLoadBalancerRequestBinder.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/loadbalancer/RegisterLoadBalancerRequestBinder.java @@ -35,9 +35,8 @@ public class RegisterLoadBalancerRequestBinder extends BaseProfitBricksRequestBi .append("").append("") .append(format("%s", payload.id())); - for (String s : payload.serverIds()) { + for (String s : payload.serverIds()) requestBuilder.append(format("%s", s)); - } requestBuilder .append("") .append(""); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinder.java index 213a3a8a58..5ec4644836 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinder.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinder.java @@ -33,12 +33,12 @@ public class CreateSnapshotRequestBinder extends BaseProfitBricksRequestBinder") - .append("") - .append(format("%s", payload.storageId())) - .append(formatIfNotEmpty("%s", payload.description())) - .append(formatIfNotEmpty("%s", payload.name())) - .append("") - .append(""); + .append("") + .append(format("%s", payload.storageId())) + .append(formatIfNotEmpty("%s", payload.description())) + .append(formatIfNotEmpty("%s", payload.name())) + .append("") + .append(""); return requestBuilder.toString(); } } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinder.java index a9997cb4b7..50993246a2 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinder.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinder.java @@ -23,21 +23,21 @@ import static java.lang.String.format; public class RollbackSnapshotRequestBinder extends BaseProfitBricksRequestBinder { - protected final StringBuilder requestBuilder; + protected final StringBuilder requestBuilder; - protected RollbackSnapshotRequestBinder() { - super("snapshot"); - this.requestBuilder = new StringBuilder(128); - } + protected RollbackSnapshotRequestBinder() { + super("snapshot"); + this.requestBuilder = new StringBuilder(128); + } - @Override - protected String createPayload(Snapshot.Request.RollbackPayload payload) { - requestBuilder.append("") - .append("") - .append(format("%s", payload.snapshotId())) - .append(format("%s", payload.storageId())) - .append("") - .append(""); - return requestBuilder.toString(); - } + @Override + protected String createPayload(Snapshot.Request.RollbackPayload payload) { + requestBuilder.append("") + .append("") + .append(format("%s", payload.snapshotId())) + .append(format("%s", payload.storageId())) + .append("") + .append(""); + return requestBuilder.toString(); + } } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinder.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinder.java index e3967150e8..df1b7cd07e 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinder.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/binder/snapshot/UpdateSnapshotRequestBinder.java @@ -32,22 +32,22 @@ public class UpdateSnapshotRequestBinder extends BaseProfitBricksRequestBinder") - .append("") - .append(format("%s", payload.snapshotId())) - .append(format("%s", payload.description())) - .append(format("%s", payload.name())) - .append(formatIfNotEmpty("%s", payload.bootable())) - .append(formatIfNotEmpty("%s", payload.osType())) - .append(formatIfNotEmpty("%s", payload.cpuHotplug())) - .append(formatIfNotEmpty("%s", payload.cpuHotunplug())) - .append(formatIfNotEmpty("%s", payload.ramHotplug())) - .append(formatIfNotEmpty("%s", payload.ramHotunplug())) - .append(formatIfNotEmpty("%s", payload.nicHotplug())) - .append(formatIfNotEmpty("%s", payload.nicHotunplug())) - .append(formatIfNotEmpty("%s", payload.discVirtioHotplug())) - .append(formatIfNotEmpty("%s", payload.discVirtioHotunplug())) - .append("") - .append(""); + .append("") + .append(format("%s", payload.snapshotId())) + .append(format("%s", payload.description())) + .append(format("%s", payload.name())) + .append(formatIfNotEmpty("%s", payload.bootable())) + .append(formatIfNotEmpty("%s", payload.osType())) + .append(formatIfNotEmpty("%s", payload.isCpuHotPlug())) + .append(formatIfNotEmpty("%s", payload.isCpuHotUnPlug())) + .append(formatIfNotEmpty("%s", payload.isRamHotPlug())) + .append(formatIfNotEmpty("%s", payload.isRamHotUnPlug())) + .append(formatIfNotEmpty("%s", payload.isNicHotPlug())) + .append(formatIfNotEmpty("%s", payload.isNicHotUnPlug())) + .append(formatIfNotEmpty("%s", payload.isDiscVirtioHotPlug())) + .append(formatIfNotEmpty("%s", payload.isDiscVirtioHotUnPlug())) + .append("") + .append(""); return requestBuilder.toString(); } } 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 new file mode 100644 index 0000000000..add3fb9f27 --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapter.java @@ -0,0 +1,488 @@ +/* + * 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.base.Strings.isNullOrEmpty; +import static com.google.common.collect.Iterables.transform; +import static com.google.common.util.concurrent.Futures.allAsList; +import static com.google.common.util.concurrent.Futures.getUnchecked; +import static java.lang.String.format; +import static org.jclouds.Constants.PROPERTY_USER_THREADS; +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_PREDICATE_DATACENTER; + +import java.util.List; +import java.util.concurrent.Callable; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.compute.ComputeServiceAdapter; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.Volume; +import org.jclouds.compute.domain.internal.VolumeImpl; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.compute.util.ComputeServiceUtils; +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.domain.Snapshot; +import org.jclouds.profitbricks.domain.internal.Provisionable; +import org.jclouds.profitbricks.util.Passwords; +import org.jclouds.rest.ResourceNotFoundException; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.Inject; + +@Singleton +public class ProfitBricksComputeServiceAdapter implements ComputeServiceAdapter { + + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + private final ProfitBricksApi api; + private final Predicate waitDcUntilAvailable; + private final ListeningExecutorService executorService; + private final ProvisioningJob.Factory jobFactory; + private final ProvisioningManager provisioningManager; + + private static final Integer DEFAULT_LAN_ID = 1; + + @Inject + ProfitBricksComputeServiceAdapter(ProfitBricksApi api, + @Named(POLL_PREDICATE_DATACENTER) Predicate waitDcUntilAvailable, + @Named(PROPERTY_USER_THREADS) ListeningExecutorService executorService, + ProvisioningJob.Factory jobFactory, + ProvisioningManager provisioningManager) { + this.api = api; + this.waitDcUntilAvailable = waitDcUntilAvailable; + this.executorService = executorService; + this.jobFactory = jobFactory; + this.provisioningManager = provisioningManager; + } + + @Override + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template) { + final String dataCenterId = template.getLocation().getId(); + Hardware hardware = template.getHardware(); + + TemplateOptions options = template.getOptions(); + final String loginUser = isNullOrEmpty(options.getLoginUser()) ? "root" : options.getLoginUser(); + final String password = options.hasLoginPassword() ? options.getLoginPassword() : Passwords.generate(); + + final org.jclouds.compute.domain.Image image = template.getImage(); + + // provision all storages based on hardware + List volumes = hardware.getVolumes(); + List storageIds = Lists.newArrayListWithExpectedSize(volumes.size()); + + int i = 1; + for (final Volume volume : volumes) + try { + logger.trace("<< provisioning storage '%s'", volume); + final Storage.Request.CreatePayload request = Storage.Request.creatingBuilder() + .dataCenterId(dataCenterId) + // put image to first storage + .mountImageId(i == 1 ? image.getId() : "") + .imagePassword(password) + .name(format("%s-disk-%d", name, i++)) + .size(volume.getSize()) + .build(); + + String storageId = (String) provisioningManager.provision(jobFactory.create(dataCenterId, new Supplier() { + + @Override + public Object get() { + return api.storageApi().createStorage(request); + } + })); + + storageIds.add(storageId); + logger.trace(">> provisioning complete for storage. returned id='%s'", storageId); + } catch (Exception ex) { + if (i - 1 == 1) // if first storage (one with image) provisioning fails; stop method + throw Throwables.propagate(ex); + logger.warn(ex, ">> failed to provision storage. skipping.."); + } + + int lanId = DEFAULT_LAN_ID; + if (options.getNetworks() != null) + try { + String networkId = Iterables.get(options.getNetworks(), 0); + lanId = Integer.valueOf(networkId); + } catch (Exception ex) { + logger.warn("no valid network id found from options. using default id='%d'", DEFAULT_LAN_ID); + } + + Double cores = ComputeServiceUtils.getCores(hardware); + + // provision server and connect boot storage (first provisioned) + String serverId = null; + try { + String storageBootDeviceId = Iterables.get(storageIds, 0); // must have atleast 1 + final Server.Request.CreatePayload serverRequest = Server.Request.creatingBuilder() + .dataCenterId(dataCenterId) + .name(name) + .bootFromStorageId(storageBootDeviceId) + .cores(cores.intValue()) + .ram(hardware.getRam()) + .availabilityZone(AvailabilityZone.AUTO) + .hasInternetAccess(true) + .lanId(lanId) + .build(); + logger.trace("<< provisioning server '%s'", serverRequest); + + serverId = (String) provisioningManager.provision(jobFactory.create(dataCenterId, new Supplier() { + + @Override + public Object get() { + return api.serverApi().createServer(serverRequest); + } + })); + logger.trace(">> provisioning complete for server. returned id='%s'", serverId); + + } catch (Exception ex) { + logger.error(ex, ">> failed to provision server. rollbacking.."); + destroyStorages(storageIds, dataCenterId); + throw Throwables.propagate(ex); + } + + // connect the rest of storages to server; delete if fails + final int storageCount = storageIds.size(); + for (int j = 1; j < storageCount; j++) { // skip first; already connected + String storageId = storageIds.get(j); + try { + logger.trace("<< connecting storage '%s' to server '%s'", storageId, serverId); + final Storage.Request.ConnectPayload request = Storage.Request.connectingBuilder() + .storageId(storageId) + .serverId(serverId) + .build(); + + provisioningManager.provision(jobFactory.create(group, new Supplier() { + + @Override + public Object get() { + return api.storageApi().connectStorageToServer(request); + } + })); + + logger.trace(">> storage connected."); + } catch (Exception ex) { + // delete unconnected storage + logger.warn(ex, ">> failed to connect storage '%s'. deleting..", storageId); + destroyStorage(storageId, dataCenterId); + } + } + + // Last paranoid check + waitDcUntilAvailable.apply(dataCenterId); + + LoginCredentials serverCredentials = LoginCredentials.builder() + .user(loginUser) + .password(password) + .build(); + + Server server = getNode(serverId); + + return new NodeAndInitialCredentials(server, serverId, serverCredentials); + } + + @Override + public Iterable listHardwareProfiles() { + // Max [cores=48] [disk size per storage=2048GB] [ram=200704 MB] + List hardwares = Lists.newArrayList(); + for (int core = 1; core <= 48; core++) + for (int ram : new int[]{1024, 2 * 1024, 4 * 1024, 8 * 1024, + 10 * 1024, 16 * 1024, 24 * 1024, 28 * 1024, 32 * 1024}) + for (float size : new float[]{10, 20, 30, 50, 80, 100, 150, 200, 250, 500}) { + String id = String.format("cpu=%d,ram=%s,disk=%f", core, ram, size); + hardwares.add(new HardwareBuilder() + .ids(id) + .ram(ram) + .hypervisor("kvm") + .name(id) + .processor(new Processor(core, 1d)) + .volume(new VolumeImpl(size, true, true)) + .build()); + } + return hardwares; + } + + @Override + public Iterable listImages() { + // fetch images.. + ListenableFuture> images = executorService.submit(new Callable>() { + + @Override + public List call() throws Exception { + logger.trace("<< fetching images.."); + // Filter HDD types only, since JClouds doesn't have a concept of "CD-ROM" anyway + Iterable filteredImages = Iterables.filter(api.imageApi().getAllImages(), new Predicate() { + + @Override + public boolean apply(Image image) { + return image.type() == Image.Type.HDD; + } + }); + logger.trace(">> images fetched."); + + return ImmutableList.copyOf(filteredImages); + } + + }); + // and snapshots at the same time + ListenableFuture> snapshots = executorService.submit(new Callable>() { + + @Override + public List call() throws Exception { + logger.trace("<< fetching snapshots"); + List remoteSnapshots = api.snapshotApi().getAllSnapshots(); + logger.trace(">> snapshots feched."); + + return remoteSnapshots; + } + + }); + + return Iterables.concat(getUnchecked(images), getUnchecked(snapshots)); + } + + @Override + public Provisionable getImage(String id) { + // try search images + logger.trace("<< searching for image with id=%s", id); + Image image = api.imageApi().getImage(id); + if (image != null) { + logger.trace(">> found image [%s].", image.name()); + return image; + } + // try search snapshots + logger.trace("<< not found from images. searching for snapshot with id=%s", id); + Snapshot snapshot = api.snapshotApi().getSnapshot(id); + if (snapshot != null) { + logger.trace(">> found snapshot [%s]", snapshot.name()); + return snapshot; + } + throw new ResourceNotFoundException("No image/snapshot with id '" + id + "' was found"); + } + + @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); + } + + @Override + public Server getNode(String id) { + logger.trace("<< searching for server with id=%s", id); + + Server server = api.serverApi().getServer(id); + if (server != null) + logger.trace(">> found server [%s]", server.name()); + return server; + } + + @Override + public void destroyNode(String nodeId) { + ServerApi serverApi = api.serverApi(); + Server server = serverApi.getServer(nodeId); + if (server != null) { + String dataCenterId = server.dataCenter().id(); + for (Storage storage : server.storages()) + destroyStorage(storage.id(), dataCenterId); + + try { + destroyServer(nodeId, dataCenterId); + } catch (Exception ex) { + logger.warn(ex, ">> failed to delete server with id=%s", nodeId); + } + } + } + + @Override + public void rebootNode(final String id) { + // Fail pre-emptively if not found + final Server node = getRequiredNode(id); + final DataCenter dataCenter = node.dataCenter(); + provisioningManager.provision(jobFactory.create(dataCenter.id(), new Supplier() { + + @Override + public Object get() { + api.serverApi().resetServer(id); + + return node; + } + })); + } + + @Override + public void resumeNode(final String id) { + final Server node = getRequiredNode(id); + if (node.status() == Server.Status.RUNNING) + return; + + final DataCenter dataCenter = node.dataCenter(); + provisioningManager.provision(jobFactory.create(dataCenter.id(), new Supplier() { + + @Override + public Object get() { + api.serverApi().startServer(id); + + return node; + } + })); + } + + @Override + public void suspendNode(final String id) { + final Server node = getRequiredNode(id); + // Intentionally didn't include SHUTDOWN (only achieved via UI; soft-shutdown). + // A SHUTOFF server is no longer billed, so we execute method for all other status + if (node.status() == Server.Status.SHUTOFF) + return; + + final DataCenter dataCenter = node.dataCenter(); + provisioningManager.provision(jobFactory.create(dataCenter.id(), new Supplier() { + + @Override + public Object get() { + api.serverApi().stopServer(id); + + return node; + } + })); + } + + @Override + public Iterable listNodes() { + logger.trace(">> fetching all servers.."); + List servers = api.serverApi().getAllServers(); + logger.trace(">> servers fetched."); + return servers; + } + + @Override + public Iterable listNodesByIds(final Iterable ids) { + // Only fetch the requested nodes. Do it in parallel. + ListenableFuture> futures = allAsList(transform(ids, + new Function>() { + + @Override + public ListenableFuture apply(final String input) { + return executorService.submit(new Callable() { + + @Override + public Server call() throws Exception { + return getNode(input); + } + }); + } + })); + + return getUnchecked(futures); + } + + private void destroyServer(final String serverId, final String dataCenterId) { + try { + logger.trace("<< deleting server with id=%s", serverId); + provisioningManager.provision(jobFactory.create(dataCenterId, new Supplier() { + + @Override + public Object get() { + api.serverApi().deleteServer(serverId); + + return serverId; + } + })); + logger.trace(">> server '%s' deleted.", serverId); + } catch (Exception ex) { + logger.warn(ex, ">> failed to delete server with id=%s", serverId); + } + } + + private void destroyStorages(List storageIds, String dataCenterId) { + for (String storageId : storageIds) + destroyStorage(storageId, dataCenterId); + } + + private void destroyStorage(final String storageId, final String dataCenterId) { + try { + logger.trace("<< deleting storage with id=%s", storageId); + provisioningManager.provision(jobFactory.create(dataCenterId, new Supplier() { + + @Override + public Object get() { + api.storageApi().deleteStorage(storageId); + + return storageId; + } + })); + logger.trace(">> storage '%s' deleted.", storageId); + } catch (Exception ex) { + logger.warn(ex, ">> failed to delete storage with id=%s", storageId); + } + } + + private Server getRequiredNode(String nodeId) { + Server node = getNode(nodeId); + if (node == null) + throw new ResourceNotFoundException("Node with id'" + nodeId + "' was not found."); + return node; + } +} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningJob.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningJob.java new file mode 100644 index 0000000000..7da7d3c04f --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningJob.java @@ -0,0 +1,62 @@ +/* + * 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.concurrent; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_PREDICATE_DATACENTER; + +import java.util.concurrent.Callable; + +import javax.inject.Named; + +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; + +public class ProvisioningJob implements Callable { + + public interface Factory { + + ProvisioningJob create(String group, Supplier operation); + } + + private final Predicate waitDataCenterUntilReady; + private final String group; + private final Supplier operation; + + @Inject + ProvisioningJob(@Named(POLL_PREDICATE_DATACENTER) Predicate waitDataCenterUntilReady, + @Assisted String group, @Assisted Supplier operation) { + this.waitDataCenterUntilReady = waitDataCenterUntilReady; + this.group = checkNotNull(group, "group cannot be null"); + this.operation = checkNotNull(operation, "operation cannot be null"); + } + + @Override + public Object call() throws Exception { + waitDataCenterUntilReady.apply(group); + Object obj = operation.get(); + waitDataCenterUntilReady.apply(group); + + return obj; + } + + public String getGroup() { + return group; + } +} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningManager.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningManager.java new file mode 100644 index 0000000000..820cafeb4e --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningManager.java @@ -0,0 +1,88 @@ +/* + * 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.concurrent; + +import static com.google.common.util.concurrent.Futures.getUnchecked; +import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.annotation.Resource; + +import org.jclouds.concurrent.config.WithSubmissionTrace; +import org.jclouds.logging.Logger; + +import com.google.common.util.concurrent.ListeningExecutorService; + +/** + * Delegates {@link Job} to single-threaded executor services based on it's group. + * + */ +public final class ProvisioningManager implements Closeable { + + @Resource + private Logger logger = Logger.NULL; + + private final Map workers + = new ConcurrentHashMap(1); + + private final AtomicBoolean terminated = new AtomicBoolean(false); + + public Object provision(ProvisioningJob job) { + if (terminated.get()) { + logger.warn("Job(%s) submitted but the provisioning manager is already closed", job); + return null; + } + + logger.debug("Job(%s) submitted to group '%s'", job, job.getGroup()); + ListeningExecutorService workerGroup = getWorkerGroup(job.getGroup()); + return getUnchecked(workerGroup.submit(job)); + } + + protected ListeningExecutorService newExecutorService() { + return WithSubmissionTrace.wrap(listeningDecorator(Executors.newSingleThreadExecutor())); + } + + private void newWorkerGroupIfAbsent(String name) { + if (!workers.containsKey(name)) + workers.put(name, newExecutorService()); + } + + private ListeningExecutorService getWorkerGroup(String name) { + newWorkerGroupIfAbsent(name); + return workers.get(name); + } + + @Override + public void close() throws IOException { + terminated.set(true); // Do not allow to enqueue more jobs + Collection executors = workers.values(); + for (ListeningExecutorService executor : executors) { + List runnables = executor.shutdownNow(); + if (!runnables.isEmpty()) + logger.warn("when shutting down executor %s, runnables outstanding: %s", executor, runnables); + } + } + +} 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 new file mode 100644 index 0000000000..d260caf8aa --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/config/ProfitBricksComputeServiceContextModule.java @@ -0,0 +1,147 @@ +/* + * 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.config; + +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_PERIOD; +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_MAX_PERIOD; +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_PREDICATE_DATACENTER; +import static org.jclouds.profitbricks.config.ProfitBricksComputeProperties.POLL_TIMEOUT; + +import java.util.concurrent.TimeUnit; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.compute.ComputeServiceAdapter; +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.Volume; +import org.jclouds.domain.Location; +import org.jclouds.functions.IdentityFunction; +import org.jclouds.lifecycle.Closer; +import org.jclouds.location.suppliers.ImplicitLocationSupplier; +import org.jclouds.location.suppliers.implicit.OnlyLocationOrFirstZone; +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.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.compute.internal.ProvisioningStatusAware; +import org.jclouds.profitbricks.compute.internal.ProvisioningStatusPollingPredicate; +import org.jclouds.profitbricks.domain.ProvisioningState; +import org.jclouds.profitbricks.domain.internal.Provisionable; +import org.jclouds.util.Predicates2; + +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.TypeLiteral; +import com.google.inject.assistedinject.FactoryModuleBuilder; + +public class ProfitBricksComputeServiceContextModule extends + ComputeServiceAdapterContextModule { + + @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(new TypeLiteral>() { + }).to(ProfitBricksComputeServiceAdapter.class); + + bind(new TypeLiteral>() { + }).to(LocationToLocation.class); + + bind(new TypeLiteral>() { + }).to(DataCenterToLocation.class); + + bind(new TypeLiteral>() { + }).to(ServerToNodeMetadata.class); + + bind(new TypeLiteral>() { + }).to(ProvisionableToImage.class); + + bind(new TypeLiteral>() { + }).to(StorageToVolume.class); + + bind(new TypeLiteral>() { + }).to(Class.class.cast(IdentityFunction.class)); + } + + @Provides + @Singleton + @Named(POLL_PREDICATE_DATACENTER) + Predicate provideWaitDataCenterUntilAvailablePredicate( + final ProfitBricksApi api, ComputeConstants constants) { + return Predicates2.retry(new ProvisioningStatusPollingPredicate( + api, ProvisioningStatusAware.DATACENTER, ProvisioningState.AVAILABLE), + constants.pollTimeout(), constants.pollPeriod(), constants.pollMaxPeriod(), TimeUnit.SECONDS); + } + + @Provides + @Singleton + ProvisioningManager provideProvisioningManager(Closer closer) { + ProvisioningManager provisioningManager = new ProvisioningManager(); + closer.addToClose(provisioningManager); + + return provisioningManager; + } + + @Singleton + public static class ComputeConstants { + + @Inject + @Named(POLL_TIMEOUT) + private String pollTimeout; + + @Inject + @Named(POLL_PERIOD) + private String pollPeriod; + + @Inject + @Named(POLL_MAX_PERIOD) + private String pollMaxPeriod; + + public long pollTimeout() { + return Long.parseLong(pollTimeout); + } + + public long pollPeriod() { + return Long.parseLong(pollPeriod); + } + + public long pollMaxPeriod() { + return Long.parseLong(pollMaxPeriod); + } + } +} 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 new file mode 100644 index 0000000000..93fb3a07cd --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/DataCenterToLocation.java @@ -0,0 +1,54 @@ +/* + * 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 new file mode 100644 index 0000000000..999069b726 --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/LocationToLocation.java @@ -0,0 +1,47 @@ +/* + * 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 new file mode 100644 index 0000000000..c5fcd78312 --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ProvisionableToImage.java @@ -0,0 +1,215 @@ +/* + * 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.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.regex.Pattern; + +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.domain.Location; +import org.jclouds.profitbricks.domain.OsType; +import org.jclouds.profitbricks.domain.ProvisioningState; +import org.jclouds.profitbricks.domain.Snapshot; +import org.jclouds.profitbricks.domain.internal.Provisionable; + +import com.google.common.base.Function; +import com.google.common.base.Strings; +import com.google.inject.Inject; + +public class ProvisionableToImage implements Function { + + private final ImageToImage fnImageToImage; + private final SnapshotToImage fnSnapshotToImage; + + @Inject + ProvisionableToImage(Function fnRegion) { + this.fnImageToImage = new ImageToImage(fnRegion); + this.fnSnapshotToImage = new SnapshotToImage(fnRegion); + } + + @Override + public Image apply(Provisionable input) { + checkNotNull(input, "Cannot convert null input"); + + if (input instanceof org.jclouds.profitbricks.domain.Image) + return fnImageToImage.apply((org.jclouds.profitbricks.domain.Image) input); + + else if (input instanceof Snapshot) + return fnSnapshotToImage.apply((Snapshot) input); + + else + throw new UnsupportedOperationException("No implementation found for provisionable of concrete type '" + + input.getClass().getCanonicalName() + "'"); + } + + private static OsFamily mapOsFamily(OsType osType) { + if (osType == null) + return OsFamily.UNRECOGNIZED; + switch (osType) { + case WINDOWS: + return OsFamily.WINDOWS; + case LINUX: + return OsFamily.LINUX; + case UNRECOGNIZED: + case OTHER: + default: + return OsFamily.UNRECOGNIZED; + } + } + + private static class ImageToImage implements Function { + + private static final Pattern HAS_NUMBERS = Pattern.compile(".*\\d+.*"); + + private final Function fnRegion; + + ImageToImage(Function fnRegion) { + this.fnRegion = fnRegion; + } + + @Override + public Image apply(org.jclouds.profitbricks.domain.Image from) { + String desc = from.name(); + OsFamily osFamily = parseOsFamily(desc, from.osType()); + + OperatingSystem os = OperatingSystem.builder() + .description(osFamily.value()) + .family(osFamily) + .version(parseVersion(desc)) + .is64Bit(is64Bit(desc, from.type())) + .build(); + + return new ImageBuilder() + .ids(from.id()) + .name(desc) + .location(fnRegion.apply(from.location())) + .status(Image.Status.AVAILABLE) + .operatingSystem(os) + .build(); + } + + private OsFamily parseOsFamily(String from, OsType fallbackValue) { + if (from != null) + try { + // ProfitBricks images names are usually in format: + // [osType]-[version]-[subversion]-..-[date-created] + String desc = from.toUpperCase().split("-")[0]; + OsFamily osFamily = OsFamily.fromValue(desc); + checkArgument(osFamily != OsFamily.UNRECOGNIZED); + + return osFamily; + } catch (Exception ex) { + // do nothing + } + return mapOsFamily(fallbackValue); + } + + private String parseVersion(String from) { + if (from != null) { + String[] split = from.toLowerCase().split("-"); + if (split.length >= 2) { + int i = 1; // usually on second token + String version = split[i]; + while (!HAS_NUMBERS.matcher(version).matches()) + version = split[++i]; + return version; + } + } + return ""; + } + + private boolean is64Bit(String from, org.jclouds.profitbricks.domain.Image.Type type) { + switch (type) { + case CDROM: + if (!Strings.isNullOrEmpty(from)) + return from.matches("x86_64|amd64"); + case HDD: // HDD provided by ProfitBricks are always 64-bit + default: + return true; + } + } + } + + private static class SnapshotToImage implements Function { + + private final Function fnRegion; + + SnapshotToImage(Function fnRegion) { + this.fnRegion = fnRegion; + } + + @Override + public Image apply(Snapshot from) { + String textToParse = from.name() + from.description(); + OsFamily osFamily = parseOsFamily(textToParse, from.osType()); + + OperatingSystem os = OperatingSystem.builder() + .description(osFamily.value()) + .family(osFamily) + .is64Bit(true) + .version("00.00") + .build(); + + return new ImageBuilder() + .ids(from.id()) + .name(from.name()) + .description(from.description()) + .location(fnRegion.apply(from.location())) + .status(mapStatus(from.state())) + .operatingSystem(os) + .build(); + } + + private OsFamily parseOsFamily(String text, OsType fallbackValue) { + if (text != null) + try { + // Attempt parsing OsFamily by scanning name and description + // @see ProfitBricksComputeServiceAdapter#L190 + OsFamily[] families = OsFamily.values(); + for (OsFamily family : families) + if (text.contains(family.value())) + return family; + } catch (Exception ex) { + // do nothing + } + return mapOsFamily(fallbackValue); + } + + static Image.Status mapStatus(ProvisioningState state) { + if (state == null) + return Image.Status.UNRECOGNIZED; + switch (state) { + case AVAILABLE: + return Image.Status.AVAILABLE; + case DELETED: + return Image.Status.DELETED; + case ERROR: + return Image.Status.ERROR; + case INACTIVE: + case INPROCESS: + return Image.Status.PENDING; + default: + return Image.Status.UNRECOGNIZED; + } + } + } +} 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 new file mode 100644 index 0000000000..9a8d551ffd --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadata.java @@ -0,0 +1,180 @@ +/* + * 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 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 java.util.List; +import java.util.Set; + +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadataBuilder; +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.domain.Location; +import org.jclouds.profitbricks.domain.Nic; +import org.jclouds.profitbricks.domain.OsType; +import org.jclouds.profitbricks.domain.Server; +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 Function, List> fnCollectIps; + + private final GroupNamingConvention groupNamingConvention; + + @Inject + ServerToNodeMetadata(Function fnVolume, + @Memoized Supplier> locationsSupply, + GroupNamingConvention.Factory groupNamingConvention) { + this.fnVolume = fnVolume; + this.locationSupply = locationsSupply; + this.groupNamingConvention = groupNamingConvention.createWithoutPrefix(); + this.fnCollectIps = new Function, List>() { + + @Override + public List apply(List in) { + List ips = Lists.newArrayListWithExpectedSize(in.size()); + for (Nic nic : in) + ips.addAll(nic.ips()); + return ips; + } + }; + } + + @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()); + } + }); + + float size = 0f; + List volumes = Lists.newArrayList(); + List storages = server.storages(); + if (storages != null) + for (Storage storage : storages) { + size += storage.size(); + volumes.add(fnVolume.apply(storage)); + } + + // Build hardware + String id = String.format("cpu=%d,ram=%d,disk=%.0f", server.cores(), server.ram(), size); + Hardware hardware = new HardwareBuilder() + .ids(id) + .name(id) + .ram(server.ram()) + .processor(new Processor(server.cores(), 1d)) + .hypervisor("kvm") + .volumes(volumes) + .location(location) + .build(); + + // Collect ips + List addresses = fnCollectIps.apply(server.nics()); + + // Build node + NodeMetadataBuilder nodeBuilder = new NodeMetadataBuilder(); + nodeBuilder.ids(server.id()) + .group(groupNamingConvention.extractGroup(server.name())) + .hostname(server.hostname()) + .name(server.name()) + .backendStatus(server.state().toString()) + .status(mapStatus(server.status())) + .hardware(hardware) + .operatingSystem(mapOsType(server.osType())) + .location(location) + .privateAddresses(Iterables.filter(addresses, IsPrivateIPAddress.INSTANCE)) + .publicAddresses(Iterables.filter(addresses, not(IsPrivateIPAddress.INSTANCE))); + + return nodeBuilder.build(); + } + + static NodeMetadata.Status mapStatus(Server.Status status) { + if (status == null) + return NodeMetadata.Status.UNRECOGNIZED; + switch (status) { + case SHUTDOWN: + case SHUTOFF: + case PAUSED: + return NodeMetadata.Status.SUSPENDED; + case RUNNING: + return NodeMetadata.Status.RUNNING; + case BLOCKED: + return NodeMetadata.Status.PENDING; + case CRASHED: + return NodeMetadata.Status.ERROR; + default: + return NodeMetadata.Status.UNRECOGNIZED; + } + } + + static OperatingSystem mapOsType(OsType osType) { + if (osType != null) + switch (osType) { + case WINDOWS: + return OperatingSystem.builder() + .description(OsFamily.WINDOWS.value()) + .family(OsFamily.WINDOWS) + .build(); + case LINUX: + return OperatingSystem.builder() + .description(OsFamily.LINUX.value()) + .family(OsFamily.LINUX) + .build(); + } + return OperatingSystem.builder() + .description(OsFamily.UNRECOGNIZED.value()) + .family(OsFamily.UNRECOGNIZED) + .build(); + } + +} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/StorageToVolume.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/StorageToVolume.java new file mode 100644 index 0000000000..5557bca77a --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/function/StorageToVolume.java @@ -0,0 +1,47 @@ +/* + * 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.compute.domain.Volume; +import org.jclouds.compute.domain.VolumeBuilder; +import org.jclouds.profitbricks.domain.Storage; + +import com.google.common.base.Function; + +public class StorageToVolume implements Function { + + @Override + public Volume apply(Storage storage) { + checkNotNull(storage, "Null storage"); + + String device = ""; + if (storage.deviceNumber() != null) + device = storage.deviceNumber().toString(); + + return new VolumeBuilder() + .id(storage.id()) + .size(storage.size()) + .bootDevice(storage.bootDevice()) + .device(device) + .durable(true) + .type(Volume.Type.LOCAL) + .build(); + + } +} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicate.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicate.java index f38abade51..41c3e932d5 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicate.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicate.java @@ -22,6 +22,7 @@ import org.jclouds.profitbricks.ProfitBricksApi; import org.jclouds.profitbricks.domain.ProvisioningState; import com.google.common.base.Predicate; +import org.jclouds.rest.ResourceNotFoundException; /** * A custom predicate for waiting until a virtual resource satisfies the given expected status @@ -45,19 +46,24 @@ public class ProvisioningStatusPollingPredicate implements Predicate { @Override public boolean apply(String input) { checkNotNull(input, "Virtual item id can't be null."); - switch (domain) { - case DATACENTER: - return expect == api.dataCenterApi().getDataCenterState(input); - case SERVER: - return expect == api.serverApi().getServer(input).state(); - case STORAGE: - return expect == api.storageApi().getStorage(input).state(); - case NIC: - return expect == api.nicApi().getNic(input).state(); - case SNAPSHOT: - return expect == api.snapshotApi().getSnapshot(input).state(); - default: - throw new IllegalArgumentException("Unknown domain '" + domain + "'"); + try { + switch (domain) { + case DATACENTER: + return expect == api.dataCenterApi().getDataCenterState(input); + case SERVER: + return expect == api.serverApi().getServer(input).state(); + case STORAGE: + return expect == api.storageApi().getStorage(input).state(); + case NIC: + return expect == api.nicApi().getNic(input).state(); + case SNAPSHOT: + return expect == api.snapshotApi().getSnapshot(input).state(); + default: + throw new IllegalArgumentException("Unknown domain '" + domain + "'"); + } + } catch (ResourceNotFoundException ex) { + // After provisioning, a node might still not be "fetchable" via API + return false; } } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/config/ProfitBricksComputeProperties.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/config/ProfitBricksComputeProperties.java new file mode 100644 index 0000000000..19b0e53c99 --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/config/ProfitBricksComputeProperties.java @@ -0,0 +1,31 @@ +/* + * 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.config; + +public class ProfitBricksComputeProperties { + + public static final String POLL_PREDICATE_DATACENTER = "jclouds.profitbricks.predicate.datacenter"; + + public static final String POLL_TIMEOUT = "jclouds.profitbricks.poll.timeout"; + public static final String POLL_PERIOD = "jclouds.profitbricks.operation.poll.initial-period"; + public static final String POLL_MAX_PERIOD = "jclouds.profitbricks.operation.poll.max-period"; + + private ProfitBricksComputeProperties() { + throw new AssertionError("Intentionally unimplemented"); + } + +} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Firewall.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Firewall.java index 6a3d5fa438..2108bc48a2 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Firewall.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Firewall.java @@ -17,20 +17,18 @@ package org.jclouds.profitbricks.domain; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.net.InetAddresses.isInetAddress; import static org.jclouds.profitbricks.util.MacAddresses.isMacAddress; -import com.google.auto.value.AutoValue; - import java.util.List; import org.jclouds.javax.annotation.Nullable; import org.jclouds.profitbricks.domain.internal.FirewallRuleCommonProperties; +import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import static com.google.common.net.InetAddresses.isInetAddress; - @AutoValue public abstract class Firewall { diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Image.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Image.java index d272e27008..0987324637 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Image.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Image.java @@ -16,10 +16,12 @@ */ package org.jclouds.profitbricks.domain; +import org.jclouds.profitbricks.domain.internal.Provisionable; + import com.google.auto.value.AutoValue; @AutoValue -public abstract class Image { +public abstract class Image implements Provisionable { public enum Type { @@ -34,46 +36,21 @@ public abstract class Image { } } - public abstract String id(); - - public abstract String name(); - - public abstract float size(); // MB - public abstract Type type(); - public abstract Location location(); - - public abstract OsType osType(); - public abstract boolean isPublic(); public abstract boolean isWriteable(); public abstract boolean isBootable(); - public abstract boolean isCpuHotPlug(); - - public abstract boolean isCpuHotUnPlug(); - - public abstract boolean isRamHotPlug(); - - public abstract boolean isRamHotUnPlug(); - - public abstract boolean isNicHotPlug(); - - public abstract boolean isNicHotUnPlug(); - - public abstract boolean isDiscVirtioHotPlug(); - - public abstract boolean isDiscVirtioHotUnPlug(); - public static Image create(String id, String name, float size, Type type, Location location, OsType osType, - boolean isPublic, boolean isWriteable, boolean isBootable, boolean cpuHotPlug, boolean cpuHotUnPlug, - boolean ramHotPlug, boolean ramHotUnPlug, boolean nicHotPlug, boolean nicHotUnPlug, - boolean discVirtioHotPlug, boolean discVirtioHotUnPlug) { - return new AutoValue_Image(id, name, size, type, location, osType, isPublic, isWriteable, - isBootable, cpuHotPlug, cpuHotUnPlug, ramHotPlug, ramHotUnPlug, nicHotPlug, nicHotUnPlug, discVirtioHotPlug, discVirtioHotUnPlug); + boolean isPublic, Boolean isWriteable, Boolean isBootable, Boolean cpuHotPlug, Boolean cpuHotUnPlug, + Boolean ramHotPlug, Boolean ramHotUnPlug, Boolean nicHotPlug, Boolean nicHotUnPlug, + Boolean discVirtioHotPlug, Boolean discVirtioHotUnPlug) { + return new AutoValue_Image(cpuHotPlug, cpuHotUnPlug, ramHotPlug, ramHotUnPlug, nicHotPlug, nicHotUnPlug, + discVirtioHotPlug, discVirtioHotUnPlug, id, name, size, location, osType, type, isPublic, isWriteable, + isBootable); } public static Builder builder() { @@ -84,56 +61,18 @@ public abstract class Image { return builder().fromImage(this); } - public static class Builder { + public static class Builder extends Provisionable.Builder { - private String id; - private String name; - private float size; private Type type; - private Location location; - private OsType osType; private boolean isPublic; private boolean isWriteable; private boolean isBootable; - private boolean cpuHotPlug; - private boolean cpuHotUnPlug; - private boolean ramHotPlug; - private boolean ramHotUnPlug; - private boolean nicHotPlug; - private boolean nicHotUnPlug; - private boolean discVirtioHotPlug; - private boolean discVirtioHotUnPlug; - - public Builder id(String id) { - this.id = id; - return this; - } - - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder size(float size) { - this.size = size; - return this; - } public Builder type(Type type) { this.type = type; return this; } - public Builder osType(OsType osType) { - this.osType = osType; - return this; - } - - public Builder location(Location location) { - this.location = location; - return this; - } - public Builder isPublic(boolean isPublic) { this.isPublic = isPublic; return this; @@ -149,46 +88,7 @@ public abstract class Image { return this; } - public Builder isCpuHotPlug(boolean cpuHotPlug) { - this.cpuHotPlug = cpuHotPlug; - return this; - } - - public Builder isCpuHotUnPlug(boolean cpuHotUnPlug) { - this.cpuHotUnPlug = cpuHotUnPlug; - return this; - } - - public Builder isRamHotPlug(boolean ramHotPlug) { - this.ramHotPlug = ramHotPlug; - return this; - } - - public Builder isRamHotUnPlug(boolean ramHotUnPlug) { - this.ramHotUnPlug = ramHotUnPlug; - return this; - } - - public Builder isNicHotPlug(boolean nicHotPlug) { - this.nicHotPlug = nicHotPlug; - return this; - } - - public Builder isNicHotUnPlug(boolean nicHotUnPlug) { - this.nicHotUnPlug = nicHotUnPlug; - return this; - } - - public Builder isDiscVirtioHotPlug(boolean discVirtioHotPlug) { - this.discVirtioHotPlug = discVirtioHotPlug; - return this; - } - - public Builder isDiscVirtioHotUnPlug(boolean discVirtioHotUnPlug) { - this.discVirtioHotUnPlug = discVirtioHotUnPlug; - return this; - } - + @Override public Image build() { return Image.create(id, name, size, type, location, osType, isPublic, isWriteable, isBootable, cpuHotPlug, cpuHotUnPlug, ramHotPlug, ramHotUnPlug, nicHotPlug, nicHotUnPlug, discVirtioHotPlug, discVirtioHotUnPlug); @@ -199,7 +99,12 @@ public abstract class Image { .isDiscVirtioHotPlug(in.isDiscVirtioHotPlug()).isDiscVirtioHotUnPlug(in.isDiscVirtioHotUnPlug()) .isNicHotPlug(in.isNicHotPlug()).isNicHotUnPlug(in.isNicHotUnPlug()).isPublic(in.isPublic()) .isRamHotPlug(in.isRamHotPlug()).isRamHotUnPlug(in.isRamHotUnPlug()).isWriteable(in.isWriteable()) - .location(in.location()).name(in.name()).osType(in.osType()).size(in.size()); + .location(in.location()).name(in.name()).osType(in.osType()).size(in.size()).type(in.type()); + } + + @Override + public Builder self() { + return this; } } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/LoadBalancer.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/LoadBalancer.java index bc118ea1b4..843999d581 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/LoadBalancer.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/LoadBalancer.java @@ -47,13 +47,10 @@ public abstract class LoadBalancer { public abstract String name(); @Nullable - public abstract Algorithm loadBalancerAlgorithm(); + public abstract Algorithm algorithm(); @Nullable - public abstract String dataCenterId(); - - @Nullable - public abstract String dataCenterVersion(); + public abstract DataCenter dataCenter(); @Nullable public abstract Boolean internetAccess(); @@ -79,10 +76,11 @@ public abstract class LoadBalancer { @Nullable public abstract List firewalls(); - public static LoadBalancer create(String id, String name, Algorithm loadBalancerAlgorithm, - String dataCenterId, String dataCenterVersion, boolean internetAccess, - String ip, String lanId, ProvisioningState state, Date creationTime, Date lastModificationTime, List balancedServers, List firewalls) { - return new AutoValue_LoadBalancer(id, name, loadBalancerAlgorithm, dataCenterId, dataCenterVersion, internetAccess, ip, lanId, state, creationTime, lastModificationTime, + public static LoadBalancer create(String id, String name, Algorithm algorithm, DataCenter dataCenter, + boolean internetAccess, String ip, String lanId, ProvisioningState state, Date creationTime, + Date lastModificationTime, List balancedServers, List firewalls) { + return new AutoValue_LoadBalancer(id, name, algorithm, dataCenter, + internetAccess, ip, lanId, state, creationTime, lastModificationTime, balancedServers != null ? ImmutableList.copyOf(balancedServers) : ImmutableList.of(), firewalls != null ? ImmutableList.copyOf(firewalls) : ImmutableList.of()); } @@ -102,11 +100,9 @@ public abstract class LoadBalancer { private String name; - private Algorithm loadBalancerAlgorithm; + private Algorithm algorithm; - private String dataCenterId; - - private String dataCenterVersion; + private DataCenter dataCenter; private boolean internetAccess; @@ -134,18 +130,13 @@ public abstract class LoadBalancer { return this; } - public Builder loadBalancerAlgorithm(Algorithm loadBalancerAlgorithm) { - this.loadBalancerAlgorithm = loadBalancerAlgorithm; + public Builder algorithm(Algorithm algorithm) { + this.algorithm = algorithm; return this; } - public Builder dataCenterId(String dataCenterId) { - this.dataCenterId = dataCenterId; - return this; - } - - public Builder dataCenterVersion(String dataCenterVersion) { - this.dataCenterVersion = dataCenterVersion; + public Builder dataCenter(DataCenter dataCenter) { + this.dataCenter = dataCenter; return this; } @@ -191,13 +182,16 @@ public abstract class LoadBalancer { public LoadBalancer build() { checkIp(ip); - return LoadBalancer.create(id, name, loadBalancerAlgorithm, dataCenterId, dataCenterVersion, internetAccess, ip, lanId, state, creationTime, lastModificationTime, balancedServers, firewalls); + return LoadBalancer.create(id, name, algorithm, dataCenter, internetAccess, + ip, lanId, state, creationTime, lastModificationTime, balancedServers, firewalls); } public Builder fromLoadBalancer(LoadBalancer in) { - return this.id(in.id()).name(in.name()).loadBalancerAlgorithm(in.loadBalancerAlgorithm()) - .dataCenterId(in.dataCenterId()).dataCenterVersion(in.dataCenterVersion()).internetAccess(in.internetAccess()) - .ip(in.ip()).lanId(in.lanId()).state(in.state()).creationTime(in.creationTime()).lastModificationTime(in.lastModificationTime()).balancedServers(in.balancedServers()).firewalls(in.firewalls()); + return this.id(in.id()).name(in.name()).algorithm(in.algorithm()) + .dataCenter(in.dataCenter()).internetAccess(in.internetAccess()) + .ip(in.ip()).lanId(in.lanId()).state(in.state()).creationTime(in.creationTime()) + .lastModificationTime(in.lastModificationTime()).balancedServers(in.balancedServers()) + .firewalls(in.firewalls()); } } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Location.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Location.java index 3dd888d5b5..52acaf2be7 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Location.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Location.java @@ -18,22 +18,28 @@ package org.jclouds.profitbricks.domain; public enum Location { - DE_FKB("de/fkb"), - DE_FRA("de/fra"), - US_LAS("us/las"), - US_LAS_DEV("us/lasdev"), - UNRECOGNIZED("unknown"); + DE_FKB("de/fkb", "Germany, Karlsruhe"), + DE_FRA("de/fra", "Germany, Frankfurt (M)"), + US_LAS("us/las", "USA, Las Vegas"), + US_LASDEV("us/lasdev", "USA Developer cluster"), + UNRECOGNIZED("unrecognized", "Unrecognized location"); private final String id; + private final String description; - Location(String id) { + Location(String id, String description) { this.id = id; + this.description = description; } - public String value() { + public String getId() { return id; } + public String getDescription() { + return description; + } + public static Location fromValue(String v) { try { return valueOf(v); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Nic.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Nic.java index f538d9b148..0f7427c8d7 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Nic.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Nic.java @@ -17,17 +17,15 @@ package org.jclouds.profitbricks.domain; import static com.google.common.base.Preconditions.checkArgument; - -import com.google.auto.value.AutoValue; +import static com.google.common.net.InetAddresses.isInetAddress; import java.util.List; -import org.jclouds.javax.annotation.Nullable; - +import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import static com.google.common.net.InetAddresses.isInetAddress; +import org.jclouds.javax.annotation.Nullable; @AutoValue public abstract class Nic { diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Server.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Server.java index ee1212ab70..027e016669 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Server.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Server.java @@ -27,6 +27,7 @@ import java.util.Date; import java.util.List; import org.jclouds.javax.annotation.Nullable; +import org.jclouds.profitbricks.domain.internal.HotPluggable; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -51,6 +52,9 @@ public abstract class Server implements ServerCommonProperties { } } + @Nullable + public abstract DataCenter dataCenter(); + @Nullable public abstract String id(); @@ -89,17 +93,23 @@ public abstract class Server implements ServerCommonProperties { public abstract String balancedNicId(); @Nullable - public abstract Boolean activate(); + public abstract Boolean loadBalanced(); - public static Server create(String id, String name, int cores, int ram, Boolean hasInternetAccess, ProvisioningState state, - Status status, OsType osType, AvailabilityZone availabilityZone, Date creationTime, Date lastModificationTime, - List storages, List nics, Boolean isCpuHotPlug, Boolean isRamHotPlug, Boolean isNicHotPlug, - Boolean isNicHotUnPlug, Boolean isDiscVirtioHotPlug, Boolean isDiscVirtioHotUnPlug, String balancedNicId, boolean activate) { - return new AutoValue_Server(isCpuHotPlug, isRamHotPlug, isNicHotPlug, isNicHotUnPlug, isDiscVirtioHotPlug, isDiscVirtioHotUnPlug, - cores, ram, id, name, hasInternetAccess, state, status, osType, availabilityZone, creationTime, lastModificationTime, + @Nullable + public abstract String hostname(); // Non-profitbricks property; Added to hold hostname parsed from image temporarily + + public static Server create(DataCenter dataCenter, String id, String name, int cores, int ram, + Boolean hasInternetAccess, ProvisioningState state, Status status, OsType osType, + AvailabilityZone availabilityZone, Date creationTime, Date lastModificationTime, List storages, + List nics, Boolean isCpuHotPlug, Boolean isRamHotPlug, Boolean isNicHotPlug, Boolean isNicHotUnPlug, + Boolean isDiscVirtioHotPlug, Boolean isDiscVirtioHotUnPlug, String balancedNicId, Boolean loadBalanced, + String hostname) { + return new AutoValue_Server(isCpuHotPlug, null, isRamHotPlug, null, isNicHotPlug, isNicHotUnPlug, isDiscVirtioHotPlug, + isDiscVirtioHotUnPlug, cores, ram, dataCenter, id, name, hasInternetAccess, state, status, osType, + availabilityZone, creationTime, lastModificationTime, storages != null ? ImmutableList.copyOf(storages) : Lists.newArrayList(), - nics != null ? ImmutableList.copyOf(nics) : Lists.newArrayList(), balancedNicId, activate); - + nics != null ? ImmutableList.copyOf(nics) : Lists.newArrayList(), + balancedNicId, loadBalanced, hostname); } public static DescribingBuilder builder() { @@ -110,17 +120,11 @@ public abstract class Server implements ServerCommonProperties { return builder().fromServer(this); } - public abstract static class Builder { + public abstract static class Builder extends HotPluggable.Builder { protected String name; protected int cores; protected int ram; - protected Boolean cpuHotPlug; - protected Boolean ramHotPlug; - protected Boolean nicHotPlug; - protected Boolean nicHotUnPlug; - protected Boolean discVirtioHotPlug; - protected Boolean discVirtioHotUnPlug; public B name(String name) { this.name = name; @@ -136,45 +140,11 @@ public abstract class Server implements ServerCommonProperties { this.ram = ram; return self(); } - - public B isCpuHotPlug(Boolean cpuHotPlug) { - this.cpuHotPlug = cpuHotPlug; - return self(); - } - - public B isRamHotPlug(Boolean ramHotPlug) { - this.ramHotPlug = ramHotPlug; - return self(); - - } - - public B isNicHotPlug(Boolean nicHotPlug) { - this.nicHotPlug = nicHotPlug; - return self(); - } - - public B isNicHotUnPlug(Boolean nicHotUnPlug) { - this.nicHotUnPlug = nicHotUnPlug; - return self(); - } - - public B isDiscVirtioHotPlug(Boolean discVirtioHotPlug) { - this.discVirtioHotPlug = discVirtioHotPlug; - return self(); - } - - public B isDiscVirtioHotUnPlug(Boolean discVirtioHotUnPlug) { - this.discVirtioHotUnPlug = discVirtioHotUnPlug; - return self(); - } - - public abstract B self(); - - public abstract D build(); } public static class DescribingBuilder extends Builder { + private DataCenter dataCenter; private String id; private ProvisioningState state; private Status status; @@ -185,8 +155,14 @@ public abstract class Server implements ServerCommonProperties { private Boolean hasInternetAccess; private List storages; private List nics; - private boolean activate; + private Boolean loadBalanced; private String balancedNicId; + private String hostname; + + public DescribingBuilder dataCenter(DataCenter dataCenter) { + this.dataCenter = dataCenter; + return this; + } public DescribingBuilder id(String id) { this.id = id; @@ -243,16 +219,21 @@ public abstract class Server implements ServerCommonProperties { return this; } - public DescribingBuilder activate(boolean activate) { - this.activate = activate; + public DescribingBuilder loadBalanced(Boolean loadBalanced) { + this.loadBalanced = loadBalanced; + return this; + } + + public DescribingBuilder hostname(String hostname) { + this.hostname = hostname; return this; } @Override public Server build() { - return Server.create(id, name, cores, ram, hasInternetAccess, state, status, osType, zone, creationTime, + return Server.create(dataCenter, id, name, cores, ram, hasInternetAccess, state, status, osType, zone, creationTime, lastModificationTime, storages, nics, cpuHotPlug, ramHotPlug, nicHotPlug, nicHotUnPlug, - discVirtioHotPlug, discVirtioHotUnPlug, balancedNicId, activate); + discVirtioHotPlug, discVirtioHotUnPlug, balancedNicId, loadBalanced, hostname); } private DescribingBuilder fromServer(Server in) { @@ -261,7 +242,8 @@ public abstract class Server implements ServerCommonProperties { .isDiscVirtioHotUnPlug(in.isDiscVirtioHotUnPlug()).isNicHotPlug(in.isNicHotPlug()) .isNicHotUnPlug(in.isNicHotUnPlug()).isRamHotPlug(in.isRamHotPlug()) .lastModificationTime(in.lastModificationTime()).name(in.name()).osType(in.osType()).ram(in.ram()) - .state(in.state()).status(in.status()).storages(in.storages()).nics(in.nics()).balancedNicId(in.balancedNicId()).activate(in.activate()); + .state(in.state()).status(in.status()).storages(in.storages()).nics(in.nics()).dataCenter(in.dataCenter()) + .balancedNicId(balancedNicId).loadBalanced(loadBalanced).hostname(hostname); } @Override @@ -308,14 +290,15 @@ public abstract class Server implements ServerCommonProperties { return create(dataCenterId, name, core, ram, "", "", null, false, null, null, null, null, null, null, null, null); } - public static CreatePayload create(String dataCenterId, String name, int cores, int ram, String bootFromStorageId, String bootFromImageId, - Integer lanId, Boolean hasInternetAccess, AvailabilityZone availabilityZone, OsType osType, Boolean isCpuHotPlug, Boolean isRamHotPlug, - Boolean isNicHotPlug, Boolean isNicHotUnPlug, Boolean isDiscVirtioHotPlug, Boolean isDiscVirtioHotUnPlug) { + public static CreatePayload create(String dataCenterId, String name, int cores, int ram, String bootFromStorageId, + String bootFromImageId, Integer lanId, Boolean hasInternetAccess, AvailabilityZone availabilityZone, + OsType osType, Boolean isCpuHotPlug, Boolean isRamHotPlug, Boolean isNicHotPlug, Boolean isNicHotUnPlug, + Boolean isDiscVirtioHotPlug, Boolean isDiscVirtioHotUnPlug) { validateCores(cores); validateRam(ram, isRamHotPlug); - return new AutoValue_Server_Request_CreatePayload(isCpuHotPlug, isRamHotPlug, isNicHotPlug, isNicHotUnPlug, isDiscVirtioHotPlug, - isDiscVirtioHotUnPlug, name, cores, ram, dataCenterId, bootFromStorageId, bootFromImageId, lanId, hasInternetAccess, - availabilityZone, osType); + return new AutoValue_Server_Request_CreatePayload(isCpuHotPlug, null, isRamHotPlug, null, isNicHotPlug, + isNicHotUnPlug, isDiscVirtioHotPlug, isDiscVirtioHotUnPlug, name, cores, ram, dataCenterId, + bootFromStorageId, bootFromImageId, lanId, hasInternetAccess, availabilityZone, osType); } public static class Builder extends Server.Builder { @@ -406,8 +389,9 @@ public abstract class Server implements ServerCommonProperties { public static UpdatePayload create(String id, String name, int cores, int ram, String bootFromStorageId, String bootFromImageId, AvailabilityZone availabilityZone, OsType osType, Boolean isCpuHotPlug, Boolean isRamHotPlug, Boolean isNicHotPlug, Boolean isNicHotUnPlug, Boolean isDiscVirtioHotPlug, Boolean isDiscVirtioHotUnPlug) { - return new AutoValue_Server_Request_UpdatePayload(isCpuHotPlug, isRamHotPlug, isNicHotPlug, isNicHotUnPlug, isDiscVirtioHotPlug, - isDiscVirtioHotUnPlug, cores, ram, name, id, bootFromStorageId, bootFromImageId, availabilityZone, osType); + return new AutoValue_Server_Request_UpdatePayload(isCpuHotPlug, null, isRamHotPlug, null, isNicHotPlug, + isNicHotUnPlug, isDiscVirtioHotPlug, isDiscVirtioHotUnPlug, cores, ram, name, id, bootFromStorageId, + bootFromImageId, availabilityZone, osType); } public static class Builder extends Server.Builder { diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Snapshot.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Snapshot.java index 3182711efd..60738d01d2 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Snapshot.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Snapshot.java @@ -17,45 +17,34 @@ package org.jclouds.profitbricks.domain; import com.google.auto.value.AutoValue; + import org.jclouds.javax.annotation.Nullable; import java.util.Date; +import org.jclouds.profitbricks.domain.internal.HotPluggable; +import org.jclouds.profitbricks.domain.internal.Provisionable; + @AutoValue -public abstract class Snapshot { +public abstract class Snapshot implements Provisionable { @Nullable + @Override public abstract String id(); @Nullable + @Override public abstract String name(); - public abstract float size(); - public abstract boolean bootable(); @Nullable public abstract String description(); @Nullable + @Override public abstract OsType osType(); - public abstract boolean cpuHotPlug(); - - public abstract boolean cpuHotUnPlug(); - - public abstract boolean discVirtioHotPlug(); - - public abstract boolean discVirtioHotUnPlug(); - - public abstract boolean ramHotPlug(); - - public abstract boolean ramHotUnPlug(); - - public abstract boolean nicHotPlug(); - - public abstract boolean nicHotUnPlug(); - @Nullable public abstract Date creationTime(); @@ -66,367 +55,237 @@ public abstract class Snapshot { public abstract ProvisioningState state(); @Nullable + @Override public abstract Location location(); - public static Snapshot create(String id, String name, float size, boolean bootable, String description, OsType osType, boolean cpuHotPlug, boolean cpuHotUnPlug, - boolean discVirtioHotPlug, boolean discVirtioHotUnPlug, boolean ramHotPlug, boolean ramHotUnPlug, - boolean nicHotPlug, boolean nicHotUnPlug, Date creationTime, Date lastModificationTime, ProvisioningState state, Location location) { - return new AutoValue_Snapshot(id, name, size, bootable, description, osType, cpuHotPlug, cpuHotUnPlug, - discVirtioHotPlug, discVirtioHotUnPlug, ramHotPlug, ramHotUnPlug, - nicHotPlug, nicHotUnPlug, creationTime, lastModificationTime, state, location); + public static Snapshot create(String id, String name, float size, boolean bootable, String description, OsType osType, + Boolean cpuHotPlug, Boolean cpuHotUnPlug, Boolean discVirtioHotPlug, Boolean discVirtioHotUnPlug, + Boolean ramHotPlug, Boolean ramHotUnPlug, Boolean nicHotPlug, Boolean nicHotUnPlug, Date creationTime, + Date lastModificationTime, ProvisioningState state, Location location) { + return new AutoValue_Snapshot(cpuHotPlug, cpuHotUnPlug, discVirtioHotPlug, discVirtioHotUnPlug, ramHotPlug, + ramHotUnPlug, nicHotPlug, nicHotUnPlug, size, id, name, bootable, description, osType, creationTime, + lastModificationTime, state, location); } public static Builder builder() { return new Builder(); } - public static class Builder { + public static class Builder extends Provisionable.Builder { - private String id; - @Nullable - private String name; - private float size; private Date creationTime; private Date lastModificationTime; private ProvisioningState state; private boolean bootable; - @Nullable private String description; - private OsType osType; - private boolean cpuHotPlug; - private boolean cpuHotUnPlug; - private boolean discVirtioHotPlug; - private boolean discVirtioHotUnPlug; - private boolean ramHotPlug; - private boolean ramHotUnPlug; - private boolean nicHotPlug; - private boolean nicHotUnPlug; - private Location location; - - public Builder id(String id) { - this.id = id; - return this; - } - - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder size(float size) { - this.size = size; - return this; - } public Builder creationTime(Date creationTime) { - this.creationTime = creationTime; - return this; + this.creationTime = creationTime; + return this; } public Builder lastModificationTime(Date lastModificationTime) { - this.lastModificationTime = lastModificationTime; - return this; + this.lastModificationTime = lastModificationTime; + return this; } public Builder state(ProvisioningState state) { - this.state = state; - return this; + this.state = state; + return this; } public Builder description(String description) { - this.description = description; - return this; + this.description = description; + return this; } - public Builder bootable(Boolean bootable) { - this.bootable = bootable; - return this; - } - - public Builder osType(OsType osType) { - this.osType = osType; - return this; - } - - public Builder cpuHotPlug(boolean cpuHotPlug) { - this.cpuHotPlug = cpuHotPlug; - return this; - } - - public Builder cpuHotUnPlug(boolean cpuHotUnPlug) { - this.cpuHotUnPlug = cpuHotUnPlug; - return this; - } - - public Builder discVirtioHotPlug(boolean discVirtioHotPlug) { - this.discVirtioHotPlug = discVirtioHotPlug; - return this; - } - - public Builder discVirtioHotUnPlug(boolean discVirtioHotUnPlug) { - this.discVirtioHotUnPlug = discVirtioHotUnPlug; - return this; - } - - public Builder ramHotPlug(boolean ramHotPlug) { - this.ramHotPlug = ramHotPlug; - return this; - } - - public Builder ramHotUnPlug(boolean ramHotUnPlug) { - this.ramHotUnPlug = ramHotUnPlug; - return this; - } - - public Builder nicHotPlug(boolean nicHotPlug) { - this.nicHotPlug = nicHotPlug; - return this; - } - - public Builder nicHotUnPlug(boolean nicHotUnPlug) { - this.nicHotUnPlug = nicHotUnPlug; - return this; - } - - public Builder location(Location location) { - this.location = location; - return this; + public Builder isBootable(boolean bootable) { + this.bootable = bootable; + return this; } private Builder fromSnapshot(Snapshot in) { - return this.id(in.id()).name(in.name()).size(in.size()).creationTime(in.creationTime()) - .lastModificationTime(in.lastModificationTime()).state(in.state()).bootable(in.bootable()).description(in.description()) - .cpuHotPlug(in.cpuHotPlug()).cpuHotUnPlug(in.cpuHotUnPlug()).discVirtioHotPlug(in.discVirtioHotPlug()) - .discVirtioHotUnPlug(in.discVirtioHotUnPlug()).ramHotPlug(in.ramHotPlug()).ramHotUnPlug(in.ramHotUnPlug()) - .nicHotPlug(in.nicHotPlug()).nicHotUnPlug(in.nicHotUnPlug()); + return this.id(in.id()).name(in.name()).size(in.size()).creationTime(in.creationTime()) + .lastModificationTime(in.lastModificationTime()).state(in.state()).isBootable(in.bootable()) + .description(in.description()).isCpuHotPlug(in.isCpuHotPlug()).isCpuHotUnPlug(in.isCpuHotUnPlug()) + .isDiscVirtioHotPlug(in.isDiscVirtioHotPlug()).isDiscVirtioHotUnPlug(in.isDiscVirtioHotUnPlug()) + .isRamHotPlug(in.isRamHotPlug()).isRamHotUnPlug(in.isRamHotUnPlug()) + .isNicHotPlug(in.isNicHotPlug()).isNicHotUnPlug(in.isNicHotUnPlug()); } + @Override public Snapshot build() { - return Snapshot.create(id, name, size, bootable, description, osType, cpuHotPlug, cpuHotUnPlug, discVirtioHotPlug, discVirtioHotUnPlug, ramHotPlug, ramHotUnPlug, nicHotPlug, nicHotUnPlug, creationTime, lastModificationTime, state, location); + return Snapshot.create(id, name, size, bootable, description, osType, cpuHotPlug, cpuHotUnPlug, + discVirtioHotPlug, discVirtioHotUnPlug, ramHotPlug, ramHotUnPlug, nicHotPlug, nicHotUnPlug, + creationTime, lastModificationTime, state, location); + } + + @Override + public Builder self() { + return this; } } public static final class Request { public static CreatePayload.Builder creatingBuilder() { - return new CreatePayload.Builder(); + return new CreatePayload.Builder(); } public static UpdatePayload.Builder updatingBuilder() { - return new UpdatePayload.Builder(); + return new UpdatePayload.Builder(); } public static RollbackPayload.Builder rollbackBuilder() { - return new RollbackPayload.Builder(); + return new RollbackPayload.Builder(); } @AutoValue public abstract static class CreatePayload { - public abstract String storageId(); + public abstract String storageId(); - public abstract String description(); + public abstract String description(); - public abstract String name(); + public abstract String name(); - public static CreatePayload create(String storageId, String description, String name) { - return new AutoValue_Snapshot_Request_CreatePayload(storageId, description, name); - } + public static CreatePayload create(String storageId, String description, String name) { + return new AutoValue_Snapshot_Request_CreatePayload(storageId, description, name); + } - public static class Builder { + public static class Builder { - private String storageId; - private String description; - private String name; + private String storageId; + private String description; + private String name; - public Builder storageId(String storageId) { - this.storageId = storageId; - return this; - } + public Builder storageId(String storageId) { + this.storageId = storageId; + return this; + } - public Builder description(String description) { - this.description = description; - return this; - } + public Builder description(String description) { + this.description = description; + return this; + } - public Builder name(String name) { - this.name = name; - return this; - } + public Builder name(String name) { + this.name = name; + return this; + } - public CreatePayload build() { - return CreatePayload.create(storageId, description, name); - } - } + public CreatePayload build() { + return CreatePayload.create(storageId, description, name); + } + } } @AutoValue - public abstract static class UpdatePayload { + public abstract static class UpdatePayload implements HotPluggable { - public abstract String snapshotId(); + public abstract String snapshotId(); - public abstract String description(); + public abstract String description(); - public abstract String name(); + public abstract String name(); - public abstract boolean bootable(); + public abstract boolean bootable(); - @Nullable - public abstract OsType osType(); + @Nullable + public abstract OsType osType(); - public abstract boolean cpuHotplug(); + public static UpdatePayload create(String snapshotId, String description, String name, boolean bootable, + OsType osType, Boolean cpuHotplug, Boolean cpuHotunplug, Boolean ramHotplug, Boolean ramHotunplug, + Boolean nicHotplug, Boolean nicHotunplug, Boolean discVirtioHotplug, Boolean discVirtioHotunplug) { + return new AutoValue_Snapshot_Request_UpdatePayload( + cpuHotplug, cpuHotunplug, ramHotplug, ramHotunplug, nicHotplug, nicHotunplug, discVirtioHotplug, + discVirtioHotunplug, snapshotId, description, name, bootable, osType); + } - public abstract boolean cpuHotunplug(); + public static class Builder extends HotPluggable.Builder { - public abstract boolean ramHotplug(); + private String snapshotId; - public abstract boolean ramHotunplug(); + @Nullable + private String description; - public abstract boolean nicHotplug(); + @Nullable + private String name; - public abstract boolean nicHotunplug(); + private boolean bootable; - public abstract boolean discVirtioHotplug(); + private OsType osType; - public abstract boolean discVirtioHotunplug(); + public Builder snapshotId(String snapshotId) { + this.snapshotId = snapshotId; + return this; + } - public static UpdatePayload create(String snapshotId, String description, String name, boolean bootable, OsType osType, boolean cpuHotplug, boolean cpuHotunplug, boolean ramHotplug, boolean ramHotunplug, boolean nicHotplug, boolean nicHotunplug, boolean discVirtioHotplug, boolean discVirtioHotunplug) { - return new AutoValue_Snapshot_Request_UpdatePayload(snapshotId, description, name, bootable, osType, cpuHotplug, cpuHotunplug, ramHotplug, ramHotunplug, nicHotplug, nicHotunplug, discVirtioHotplug, discVirtioHotunplug); - } + public Builder description(String description) { + this.description = description; + return this; + } - public static class Builder { + public Builder name(String name) { + this.name = name; + return this; + } - private String snapshotId; + public Builder bootable(boolean bootable) { + this.bootable = bootable; + return this; + } - @Nullable - private String description; + public Builder osType(OsType osType) { + this.osType = osType; + return this; + } - @Nullable - private String name; + @Override + public UpdatePayload build() { + return UpdatePayload.create(snapshotId, description, name, bootable, osType, cpuHotPlug, cpuHotUnPlug, + ramHotPlug, ramHotUnPlug, nicHotUnPlug, nicHotUnPlug, discVirtioHotPlug, discVirtioHotUnPlug); + } - private boolean bootable; - - private OsType osType; - - private boolean cpuHotplug; - - private boolean cpuHotunplug; - - private boolean ramHotplug; - - private boolean ramHotunplug; - - private boolean nicHotplug; - - private boolean nicHotunplug; - - private boolean discVirtioHotplug; - - private boolean discVirtioHotunplug; - - public Builder snapshotId(String snapshotId) { - this.snapshotId = snapshotId; - return this; - } - - public Builder description(String description) { - this.description = description; - return this; - } - - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder bootable(boolean bootable) { - this.bootable = bootable; - return this; - } - - public Builder osType(OsType osType) { - this.osType = osType; - return this; - } - - public Builder cpuHotplug(boolean cpuHotplug) { - this.cpuHotplug = cpuHotplug; - return this; - } - - public Builder cpuHotunplug(boolean cpuHotunplug) { - this.cpuHotunplug = cpuHotunplug; - return this; - } - - public Builder ramHotplug(boolean ramHotplug) { - this.ramHotplug = ramHotplug; - return this; - } - - public Builder ramHotunplug(boolean ramHotunplug) { - this.ramHotunplug = ramHotunplug; - return this; - } - - public Builder nicHotplug(boolean nicHotplug) { - this.nicHotplug = nicHotplug; - return this; - } - - public Builder nicHotunplug(boolean nicHotunplug) { - this.nicHotunplug = nicHotunplug; - return this; - } - - public Builder discVirtioHotplug(boolean discVirtioHotplug) { - this.discVirtioHotplug = discVirtioHotplug; - return this; - } - - public Builder discVirtioHotunplug(boolean discVirtioHotunplug) { - this.discVirtioHotunplug = discVirtioHotunplug; - return this; - } - - public UpdatePayload build() { - return UpdatePayload.create(snapshotId, description, name, bootable, osType, cpuHotplug, cpuHotunplug, ramHotplug, ramHotunplug, nicHotplug, nicHotunplug, discVirtioHotplug, discVirtioHotunplug); - } - } + @Override + public Builder self() { + return this; + } + } } @AutoValue public abstract static class RollbackPayload { - public abstract String snapshotId(); + public abstract String snapshotId(); - public abstract String storageId(); + public abstract String storageId(); - public static RollbackPayload create(String snapshotId, String storageId) { - return new AutoValue_Snapshot_Request_RollbackPayload(snapshotId, storageId); - } + public static RollbackPayload create(String snapshotId, String storageId) { + return new AutoValue_Snapshot_Request_RollbackPayload(snapshotId, storageId); + } - public static class Builder { + public static class Builder { - private String snapshotId; + private String snapshotId; - private String storageId; + private String storageId; - public Builder snapshotId(String snapshotId) { - this.snapshotId = snapshotId; - return this; - } + public Builder snapshotId(String snapshotId) { + this.snapshotId = snapshotId; + return this; + } - public Builder storageId(String storageId) { - this.storageId = storageId; - return this; - } + public Builder storageId(String storageId) { + this.storageId = storageId; + return this; + } - public RollbackPayload build() { - return RollbackPayload.create(snapshotId, storageId); - } - } + public RollbackPayload build() { + return RollbackPayload.create(snapshotId, storageId); + } + } } } } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Storage.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Storage.java index 827217b20f..21664a5d77 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Storage.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/Storage.java @@ -28,6 +28,7 @@ import org.jclouds.javax.annotation.Nullable; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import static org.jclouds.profitbricks.util.Passwords.isValidPassword; @AutoValue public abstract class Storage { @@ -194,7 +195,8 @@ public abstract class Storage { public abstract String profitBricksImagePassword(); public static CreatePayload create(String dataCenterId, float size, String name, String mountImageId, String imagePassword) { - validateSize(size); + checkSize(size); + checkPassword(imagePassword); return new AutoValue_Storage_Request_CreatePayload(dataCenterId, size, name, mountImageId, imagePassword); } @@ -258,7 +260,7 @@ public abstract class Storage { public abstract String mountImageId(); public static UpdatePayload create(String id, Float size, String name, String mountImageId) { - validateSize(size); + checkSize(size); return new AutoValue_Storage_Request_UpdatePayload(id, size, name, mountImageId); } @@ -346,10 +348,15 @@ public abstract class Storage { } } - private static void validateSize(Float size) { + private static void checkSize(Float size) { if (size != null) checkArgument(size > 1, "Storage size must be > 1GB"); + } + private static void checkPassword(String password) { + if (password != null) + checkArgument(isValidPassword(password), "Password must be between 8 and 50 characters, " + + "only a-z, A-Z, 0-9 without characters i, I, l, o, O, w, W, y, Y, z, Z and 1, 0"); } } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/HotPluggable.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/HotPluggable.java new file mode 100644 index 0000000000..98faf41a20 --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/HotPluggable.java @@ -0,0 +1,102 @@ +/* + * 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.domain.internal; + +import org.jclouds.javax.annotation.Nullable; + +public interface HotPluggable { + + @Nullable + Boolean isCpuHotPlug(); + + @Nullable + Boolean isCpuHotUnPlug(); + + @Nullable + Boolean isRamHotPlug(); + + @Nullable + Boolean isRamHotUnPlug(); + + @Nullable + Boolean isNicHotPlug(); + + @Nullable + Boolean isNicHotUnPlug(); + + @Nullable + Boolean isDiscVirtioHotPlug(); + + @Nullable + Boolean isDiscVirtioHotUnPlug(); + + public abstract static class Builder { + + protected Boolean cpuHotPlug; + protected Boolean cpuHotUnPlug; + protected Boolean ramHotPlug; + protected Boolean ramHotUnPlug; + protected Boolean nicHotPlug; + protected Boolean nicHotUnPlug; + protected Boolean discVirtioHotPlug; + protected Boolean discVirtioHotUnPlug; + + public B isCpuHotPlug(Boolean cpuHotPlug) { + this.cpuHotPlug = cpuHotPlug; + return self(); + } + + public B isCpuHotUnPlug(Boolean cpuHotUnplug) { + this.cpuHotUnPlug = cpuHotUnplug; + return self(); + } + + public B isRamHotPlug(Boolean ramHotPlug) { + this.ramHotPlug = ramHotPlug; + return self(); + } + + public B isRamHotUnPlug(Boolean ramHotUnplug) { + this.ramHotUnPlug = ramHotUnplug; + return self(); + } + + public B isNicHotPlug(Boolean nicHotPlug) { + this.nicHotPlug = nicHotPlug; + return self(); + } + + public B isNicHotUnPlug(Boolean nicHotUnPlug) { + this.nicHotUnPlug = nicHotUnPlug; + return self(); + } + + public B isDiscVirtioHotPlug(Boolean discVirtioHotPlug) { + this.discVirtioHotPlug = discVirtioHotPlug; + return self(); + } + + public B isDiscVirtioHotUnPlug(Boolean discVirtioHotUnPlug) { + this.discVirtioHotUnPlug = discVirtioHotUnPlug; + return self(); + } + + public abstract B self(); + + public abstract D build(); + } +} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/Provisionable.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/Provisionable.java new file mode 100644 index 0000000000..b81dc3b3bf --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/Provisionable.java @@ -0,0 +1,67 @@ +/* + * 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.domain.internal; + +import org.jclouds.profitbricks.domain.Location; +import org.jclouds.profitbricks.domain.OsType; + +public interface Provisionable extends HotPluggable { + + String id(); + + String name(); + + float size(); // MB + + Location location(); + + OsType osType(); + + public abstract static class Builder extends HotPluggable.Builder { + + protected String id; + protected String name; + protected float size; + protected Location location; + protected OsType osType; + + public B id(String id) { + this.id = id; + return self(); + } + + public B name(String name) { + this.name = name; + return self(); + } + + public B size(float size) { + this.size = size; + return self(); + } + + public B location(Location location) { + this.location = location; + return self(); + } + + public B osType(OsType osType) { + this.osType = osType; + return self(); + } + } +} diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/ServerCommonProperties.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/ServerCommonProperties.java index 7366fb111c..382f2cf040 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/ServerCommonProperties.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/domain/internal/ServerCommonProperties.java @@ -16,30 +16,10 @@ */ package org.jclouds.profitbricks.domain.internal; -import org.jclouds.javax.annotation.Nullable; - /** * An interface used as common data type for {@link org.jclouds.profitbricks.domain.Server.Builder} */ -public interface ServerCommonProperties { - - @Nullable - Boolean isCpuHotPlug(); - - @Nullable - Boolean isRamHotPlug(); - - @Nullable - Boolean isNicHotPlug(); - - @Nullable - Boolean isNicHotUnPlug(); - - @Nullable - Boolean isDiscVirtioHotPlug(); - - @Nullable - Boolean isDiscVirtioHotUnPlug(); +public interface ServerCommonProperties extends HotPluggable { String name(); diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/features/LoadBalancerApi.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/features/LoadBalancerApi.java index cbac54a9a5..3d371836b4 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/features/LoadBalancerApi.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/features/LoadBalancerApi.java @@ -80,7 +80,7 @@ public interface LoadBalancerApi { @POST @Named("loadbalancer:delete") @Payload("{id}") - boolean deleteLoadbalancer(@PayloadParam("id") String id); + boolean deleteLoadBalancer(@PayloadParam("id") String id); @POST @Named("loadbalancer:update") diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/firewall/FirewallListResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/firewall/FirewallListResponseHandler.java index b654801343..df0d3e0b37 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/firewall/FirewallListResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/firewall/FirewallListResponseHandler.java @@ -16,15 +16,15 @@ */ package org.jclouds.profitbricks.http.parser.firewall; -import com.google.common.collect.Lists; -import com.google.inject.Inject; - import java.util.List; import org.jclouds.profitbricks.domain.Firewall; import org.jclouds.profitbricks.http.parser.firewall.rule.FirewallRuleListResponseHandler; import org.xml.sax.SAXException; +import com.google.inject.Inject; +import com.google.common.collect.Lists; + public class FirewallListResponseHandler extends BaseFirewallResponseHandler> { private List firewalls; diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/ipblock/IpBlockListResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/ipblock/IpBlockListResponseHandler.java index 6a0b419e48..3ef85b3e65 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/ipblock/IpBlockListResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/ipblock/IpBlockListResponseHandler.java @@ -16,15 +16,15 @@ */ package org.jclouds.profitbricks.http.parser.ipblock; -import com.google.common.collect.Lists; -import com.google.inject.Inject; - import java.util.List; import org.jclouds.profitbricks.domain.IpBlock; import org.jclouds.profitbricks.http.parser.publicip.PublicIpListResponseHandler; import org.xml.sax.SAXException; +import com.google.inject.Inject; +import com.google.common.collect.Lists; + public class IpBlockListResponseHandler extends BaseIpBlockResponseHandler> { private final List ipBlocks; diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/BaseLoadBalancerResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/BaseLoadBalancerResponseHandler.java index e093977210..96256bbece 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/BaseLoadBalancerResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/BaseLoadBalancerResponseHandler.java @@ -16,9 +16,12 @@ */ package org.jclouds.profitbricks.http.parser.loadbalancer; +import static com.google.common.base.Preconditions.checkNotNull; + import java.util.Date; -import org.jclouds.date.DateCodec; -import org.jclouds.date.DateCodecFactory; + +import org.jclouds.date.DateService; +import org.jclouds.profitbricks.domain.DataCenter; import org.jclouds.profitbricks.domain.LoadBalancer; import org.jclouds.profitbricks.domain.LoadBalancer.Algorithm; import org.jclouds.profitbricks.domain.ProvisioningState; @@ -34,23 +37,23 @@ public abstract class BaseLoadBalancerResponseHandler extends BaseProfitBrick protected final FirewallListResponseHandler firewallListResponseHandler; protected LoadBalancer.Builder builder; - protected final DateCodec dateCodec; + protected DataCenter.Builder dataCenterBuilder; + + protected final DateService dateService; protected boolean useBalancedServerParser = false; protected boolean useFirewallParser = false; - protected BaseLoadBalancerResponseHandler(DateCodecFactory dateCodec, + protected BaseLoadBalancerResponseHandler(DateService dateService, ServerListResponseHandler balancedServerResponseHandler, FirewallListResponseHandler firewallResponseHandler) { - if (dateCodec == null) - throw new NullPointerException("DateCodecFactory cannot be null"); - if (balancedServerResponseHandler == null) - throw new NullPointerException("BalancedServerResponseHandler cannot be null"); - if (firewallResponseHandler == null) - throw new NullPointerException("FirewallListResponseHandler cannot be null"); + checkNotNull(dateService, "DateService cannot be null"); + checkNotNull(balancedServerResponseHandler, "BalancedServerResponseHandler cannot be null"); + checkNotNull(firewallResponseHandler, "FirewallListResponseHandler cannot be null"); - this.dateCodec = dateCodec.iso8601(); + this.dateService = dateService; this.builder = LoadBalancer.builder(); + this.dataCenterBuilder = DataCenter.builder(); this.balancedServerResponseHandler = balancedServerResponseHandler; this.firewallListResponseHandler = firewallResponseHandler; @@ -80,7 +83,7 @@ public abstract class BaseLoadBalancerResponseHandler extends BaseProfitBrick } protected final Date textToIso8601Date() { - return dateCodec.toDate(textToStringValue()); + return dateService.iso8601DateOrSecondsDateParse(textToStringValue()); } @Override @@ -90,11 +93,11 @@ public abstract class BaseLoadBalancerResponseHandler extends BaseProfitBrick else if ("loadBalancerName".equals(qName)) builder.name(textToStringValue()); else if ("loadBalancerAlgorithm".equals(qName)) - builder.loadBalancerAlgorithm(Algorithm.fromValue(textToStringValue())); + builder.algorithm(Algorithm.fromValue(textToStringValue())); else if ("dataCenterId".equals(qName)) - builder.dataCenterId(textToStringValue()); + dataCenterBuilder.id(textToStringValue()); else if ("dataCenterVersion".equals(qName)) - builder.dataCenterVersion(textToStringValue()); + dataCenterBuilder.version(textToIntValue()); else if ("internetAccess".equals(qName)) builder.internetAccess(textToBooleanValue()); else if ("ip".equals(qName)) diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerListResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerListResponseHandler.java index 50c1bea5a0..9c60d330a5 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerListResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerListResponseHandler.java @@ -21,7 +21,8 @@ import com.google.inject.Inject; import java.util.List; -import org.jclouds.date.DateCodecFactory; +import org.jclouds.date.DateService; +import org.jclouds.profitbricks.domain.DataCenter; import org.jclouds.profitbricks.domain.LoadBalancer; import org.jclouds.profitbricks.http.parser.firewall.FirewallListResponseHandler; import org.jclouds.profitbricks.http.parser.server.ServerListResponseHandler; @@ -32,39 +33,45 @@ public class LoadBalancerListResponseHandler extends BaseLoadBalancerResponseHan private final List loadBalancers; @Inject - LoadBalancerListResponseHandler(DateCodecFactory dateCodec, ServerListResponseHandler balancedServerResponseHandler, FirewallListResponseHandler firewallListResponseHandler) { - super(dateCodec, balancedServerResponseHandler, firewallListResponseHandler); + LoadBalancerListResponseHandler(DateService dateService, ServerListResponseHandler balancedServerResponseHandler, FirewallListResponseHandler firewallListResponseHandler) { + super(dateService, balancedServerResponseHandler, firewallListResponseHandler); this.loadBalancers = Lists.newArrayList(); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { - if (useBalancedServerParser) { + if (useBalancedServerParser) balancedServerResponseHandler.endElement(uri, localName, qName); - } else if (useFirewallParser) { + else if (useFirewallParser) firewallListResponseHandler.endElement(uri, localName, qName); - } else { + else { setPropertyOnEndTag(qName); if ("return".equals(qName)) { loadBalancers.add(builder + .dataCenter(dataCenterBuilder.build()) .firewalls(firewallListResponseHandler.getResult()) .balancedServers(balancedServerResponseHandler.getResult()) .build()); balancedServerResponseHandler.reset(); firewallListResponseHandler.reset(); + builder = LoadBalancer.builder(); } clearTextBuffer(); } - if ("firewall".equals(qName)) { + if ("firewall".equals(qName)) useFirewallParser = false; - } else if ("balancedServers".equals(qName)) { + else if ("balancedServers".equals(qName)) useBalancedServerParser = false; - } } + @Override + public void reset() { + this.dataCenterBuilder = DataCenter.builder(); + } + @Override public List getResult() { return loadBalancers; diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerResponseHandler.java index 8c795129db..4a175351dc 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerResponseHandler.java @@ -17,7 +17,8 @@ package org.jclouds.profitbricks.http.parser.loadbalancer; import com.google.inject.Inject; -import org.jclouds.date.DateCodecFactory; + +import org.jclouds.date.DateService; import org.jclouds.profitbricks.domain.LoadBalancer; import org.jclouds.profitbricks.http.parser.firewall.FirewallListResponseHandler; import org.jclouds.profitbricks.http.parser.server.ServerListResponseHandler; @@ -28,8 +29,9 @@ public class LoadBalancerResponseHandler extends BaseLoadBalancerResponseHandler private boolean done = false; @Inject - LoadBalancerResponseHandler(DateCodecFactory dateCodec, ServerListResponseHandler serverListResponseHandler, FirewallListResponseHandler firewallListResponseHandler) { - super(dateCodec, serverListResponseHandler, firewallListResponseHandler); + LoadBalancerResponseHandler(DateService dateService, ServerListResponseHandler serverListResponseHandler, + FirewallListResponseHandler firewallListResponseHandler) { + super(dateService, serverListResponseHandler, firewallListResponseHandler); } @Override @@ -45,8 +47,9 @@ public class LoadBalancerResponseHandler extends BaseLoadBalancerResponseHandler setPropertyOnEndTag(qName); if ("return".equals(qName)) { done = true; - builder.balancedServers(balancedServerResponseHandler.getResult()); - builder.firewalls(firewallListResponseHandler.getResult()); + builder.dataCenter(dataCenterBuilder.build()) + .balancedServers(balancedServerResponseHandler.getResult()) + .firewalls(firewallListResponseHandler.getResult()); } clearTextBuffer(); } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/BaseServerResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/BaseServerResponseHandler.java index 60fb4bf717..37aabd5696 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/BaseServerResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/BaseServerResponseHandler.java @@ -16,10 +16,13 @@ */ package org.jclouds.profitbricks.http.parser.server; +import static com.google.common.base.Preconditions.checkNotNull; + import java.util.Date; -import org.jclouds.date.DateCodec; -import org.jclouds.date.DateCodecFactory; + +import org.jclouds.date.DateService; import org.jclouds.profitbricks.domain.AvailabilityZone; +import org.jclouds.profitbricks.domain.DataCenter; import org.jclouds.profitbricks.domain.OsType; import org.jclouds.profitbricks.domain.ProvisioningState; import org.jclouds.profitbricks.domain.Server; @@ -31,29 +34,28 @@ import org.xml.sax.SAXException; public abstract class BaseServerResponseHandler extends BaseProfitBricksResponseHandler { - protected StorageListResponseHandler storageListResponseHandler; - protected NicListResponseHandler nicListResponseHandler; + protected final StorageListResponseHandler storageListResponseHandler; + protected final NicListResponseHandler nicListResponseHandler; + protected DataCenter.Builder dataCenterBuilder; protected Server.DescribingBuilder builder; - protected final DateCodec dateCodec; + protected final DateService dateService; protected boolean useStorageParser = false; protected boolean useNicParser = false; - BaseServerResponseHandler(DateCodecFactory dateCodec, StorageListResponseHandler storageListResponseHandler, + BaseServerResponseHandler(DateService dateService, StorageListResponseHandler storageListResponseHandler, NicListResponseHandler nicListResponseHandler) { - if (dateCodec == null) - throw new NullPointerException("DateCodecFactory cannot be null"); - if (storageListResponseHandler == null) - throw new NullPointerException("StorageListResponseHandler cannot be null"); - if (nicListResponseHandler == null) - throw new NullPointerException("NicListResponseHandler cannot be null"); + checkNotNull(dateService, "DateService cannot be null"); + checkNotNull(storageListResponseHandler, "StorageListResponseHandler cannot be null"); + checkNotNull(nicListResponseHandler, "NicListResponseHandler cannot be null"); - this.dateCodec = dateCodec.iso8601(); + this.dateService = dateService; this.storageListResponseHandler = storageListResponseHandler; this.nicListResponseHandler = nicListResponseHandler; this.builder = Server.builder(); + this.dataCenterBuilder = DataCenter.builder(); } @Override @@ -82,12 +84,16 @@ public abstract class BaseServerResponseHandler extends BaseProfitBricksRespo } protected final Date textToIso8601Date() { - return dateCodec.toDate(textToStringValue()); + return dateService.iso8601DateOrSecondsDateParse(textToStringValue()); } @Override protected void setPropertyOnEndTag(String qName) { - if ("serverId".equals(qName)) + if ("dataCenterId".equals(qName)) + dataCenterBuilder.id(textToStringValue()); + else if ("dataCenterVersion".equals(qName)) + dataCenterBuilder.version(textToIntValue()); + else if ("serverId".equals(qName)) builder.id(textToStringValue()); else if ("serverName".equals(qName)) builder.name(textToStringValue()); @@ -122,7 +128,7 @@ public abstract class BaseServerResponseHandler extends BaseProfitBricksRespo else if ("discVirtioHotUnPlug".equals(qName)) builder.isDiscVirtioHotUnPlug(textToBooleanValue()); else if ("activate".equals(qName)) - builder.activate(textToBooleanValue()); + builder.loadBalanced(textToBooleanValue()); else if ("balancedNicId".equals(qName)) builder.balancedNicId(textToStringValue()); } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/ServerInfoResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/ServerInfoResponseHandler.java index 68ee696469..016e16487e 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/ServerInfoResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/ServerInfoResponseHandler.java @@ -18,7 +18,7 @@ package org.jclouds.profitbricks.http.parser.server; import com.google.inject.Inject; -import org.jclouds.date.DateCodecFactory; +import org.jclouds.date.DateService; import org.jclouds.profitbricks.domain.Server; import org.jclouds.profitbricks.http.parser.nic.NicListResponseHandler; import org.jclouds.profitbricks.http.parser.storage.StorageListResponseHandler; @@ -29,9 +29,9 @@ public class ServerInfoResponseHandler extends BaseServerResponseHandler private boolean done = false; @Inject - ServerInfoResponseHandler(DateCodecFactory dateCodec, StorageListResponseHandler storageListResponseHandler, + ServerInfoResponseHandler(DateService dateService, StorageListResponseHandler storageListResponseHandler, NicListResponseHandler nicListResponseHandler) { - super(dateCodec, storageListResponseHandler, nicListResponseHandler); + super(dateService, storageListResponseHandler, nicListResponseHandler); } @Override @@ -48,6 +48,7 @@ public class ServerInfoResponseHandler extends BaseServerResponseHandler if ("return".equals(qName)) { done = true; builder + .dataCenter(dataCenterBuilder.build()) .storages(storageListResponseHandler.getResult()) .nics(nicListResponseHandler.getResult()); } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/ServerListResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/ServerListResponseHandler.java index 362e378c1d..24a5daaf99 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/ServerListResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/server/ServerListResponseHandler.java @@ -21,7 +21,8 @@ import com.google.inject.Inject; import java.util.List; -import org.jclouds.date.DateCodecFactory; +import org.jclouds.date.DateService; +import org.jclouds.profitbricks.domain.DataCenter; import org.jclouds.profitbricks.domain.Server; import org.jclouds.profitbricks.http.parser.nic.NicListResponseHandler; import org.jclouds.profitbricks.http.parser.storage.StorageListResponseHandler; @@ -32,9 +33,9 @@ public class ServerListResponseHandler extends BaseServerResponseHandler servers; @Inject - ServerListResponseHandler(DateCodecFactory dateCodec, StorageListResponseHandler storageListResponseHandler, + ServerListResponseHandler(DateService dateService, StorageListResponseHandler storageListResponseHandler, NicListResponseHandler nicListResponseHandler) { - super(dateCodec, storageListResponseHandler, nicListResponseHandler); + super(dateService, storageListResponseHandler, nicListResponseHandler); this.servers = Lists.newArrayList(); } @@ -48,10 +49,18 @@ public class ServerListResponseHandler extends BaseServerResponseHandler extends BaseProfitBricksRes protected Snapshot.Builder builder; - protected final DateCodec dateCodec; + protected final DateService dateService; - BaseSnapshotResponseHandler(DateCodecFactory dateCodec) { - this.dateCodec = dateCodec.iso8601(); + BaseSnapshotResponseHandler(DateService dateService) { + this.dateService = dateService; this.builder = Snapshot.builder(); } protected final Date textToIso8601Date() { - return dateCodec.toDate(textToStringValue()); + return dateService.iso8601DateOrSecondsDateParse(textToStringValue()); } @Override protected void setPropertyOnEndTag(String qName) { if ("snapshotId".equals(qName)) - builder.id(textToStringValue()); + builder.id(textToStringValue()); else if ("snapshotName".equals(qName)) - builder.name(textToStringValue()); + builder.name(textToStringValue()); else if ("snapshotSize".equals(qName)) - builder.size(textToFloatValue()); + builder.size(textToFloatValue()); else if ("osType".equals(qName)) - builder.osType(OsType.fromValue(textToStringValue())); + builder.osType(OsType.fromValue(textToStringValue())); else if ("location".equals(qName)) - builder.location(Location.fromId(textToStringValue())); + builder.location(Location.fromId(textToStringValue())); else if ("description".equals(qName)) - builder.description(qName); + builder.description(qName); else if ("bootable".equals(qName)) - builder.bootable(textToBooleanValue()); + builder.isBootable(textToBooleanValue()); else if ("cpuHotPlug".equals(qName)) - builder.cpuHotPlug(textToBooleanValue()); + builder.isCpuHotPlug(textToBooleanValue()); else if ("cpuHotUnPlug".equals(qName)) - builder.cpuHotUnPlug(textToBooleanValue()); + builder.isCpuHotUnPlug(textToBooleanValue()); else if ("ramHotPlug".equals(qName)) - builder.ramHotPlug(textToBooleanValue()); + builder.isRamHotPlug(textToBooleanValue()); else if ("ramHotUnPlug".equals(qName)) - builder.ramHotUnPlug(textToBooleanValue()); + builder.isRamHotUnPlug(textToBooleanValue()); else if ("nicHotPlug".equals(qName)) - builder.nicHotPlug(textToBooleanValue()); + builder.isNicHotPlug(textToBooleanValue()); else if ("nicHotUnPlug".equals(qName)) - builder.nicHotUnPlug(textToBooleanValue()); + builder.isNicHotUnPlug(textToBooleanValue()); else if ("discVirtioHotPlug".equals(qName)) - builder.discVirtioHotPlug(textToBooleanValue()); + builder.isDiscVirtioHotPlug(textToBooleanValue()); else if ("discVirtioHotUnPlug".equals(qName)) - builder.discVirtioHotUnPlug(textToBooleanValue()); + builder.isDiscVirtioHotUnPlug(textToBooleanValue()); else if ("provisioningState".equals(qName)) - builder.state(ProvisioningState.fromValue(textToStringValue())); + builder.state(ProvisioningState.fromValue(textToStringValue())); else if ("creationTimestamp".equals(qName)) - builder.creationTime(textToIso8601Date()); + builder.creationTime(textToIso8601Date()); else if ("modificationTimestamp".equals(qName)) - builder.lastModificationTime(textToIso8601Date()); + builder.lastModificationTime(textToIso8601Date()); } } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandler.java index ae7a355881..27e8583923 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandler.java @@ -18,19 +18,21 @@ package org.jclouds.profitbricks.http.parser.snapshot; import com.google.common.collect.Lists; import com.google.inject.Inject; + import org.jclouds.profitbricks.domain.Snapshot; import org.xml.sax.SAXException; import java.util.List; -import org.jclouds.date.DateCodecFactory; + +import org.jclouds.date.DateService; public class SnapshotListResponseHandler extends BaseSnapshotResponseHandler> { private final List snapshots; @Inject - SnapshotListResponseHandler(DateCodecFactory dateCodec) { - super(dateCodec); + SnapshotListResponseHandler(DateService dateService) { + super(dateService); this.snapshots = Lists.newArrayList(); } @@ -38,8 +40,8 @@ public class SnapshotListResponseHandler extends BaseSnapshotResponseHandler extends BaseProfitBricksResponseHandler { - protected final DateCodec dateCodec; + protected final DateService dateService; protected Storage.Builder builder; protected List serverIds; @Inject - BaseStorageResponseHandler(DateCodecFactory dateCodec) { - this.dateCodec = dateCodec.iso8601(); + BaseStorageResponseHandler(DateService dateService) { + this.dateService = dateService; this.builder = Storage.builder(); this.serverIds = Lists.newArrayList(); } protected final Date textToIso8601Date() { - return dateCodec.toDate(textToStringValue()); + return dateService.iso8601DateOrSecondsDateParse(textToStringValue()); } @Override diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/storage/StorageInfoResponseHandler.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/storage/StorageInfoResponseHandler.java index 2bc1ed6701..ae667ca006 100644 --- a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/storage/StorageInfoResponseHandler.java +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/http/parser/storage/StorageInfoResponseHandler.java @@ -17,7 +17,8 @@ package org.jclouds.profitbricks.http.parser.storage; import com.google.inject.Inject; -import org.jclouds.date.DateCodecFactory; + +import org.jclouds.date.DateService; import org.jclouds.profitbricks.domain.Storage; import org.xml.sax.SAXException; @@ -26,8 +27,8 @@ public class StorageInfoResponseHandler extends BaseStorageResponseHandler> { private List storages; @Inject - StorageListResponseHandler(DateCodecFactory dateCodec) { - super(dateCodec); + StorageListResponseHandler(DateService dateService) { + super(dateService); this.storages = Lists.newArrayList(); } diff --git a/providers/profitbricks/src/main/java/org/jclouds/profitbricks/util/Passwords.java b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/util/Passwords.java new file mode 100644 index 0000000000..338f0640c9 --- /dev/null +++ b/providers/profitbricks/src/main/java/org/jclouds/profitbricks/util/Passwords.java @@ -0,0 +1,64 @@ +/* + * 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.util; + +import java.util.Random; +import java.util.regex.Pattern; + +import com.google.common.collect.ImmutableSet; + +public class Passwords { + + private static final Random random = new Random(); + + private static final int MIN_CHAR = 8; + private static final int MAX_CHAR = 50; + private static final String PASSWORD_FORMAT = String.format( + "[a-zA-Z0-9][^iIloOwWyYzZ10]{%d,%d}", MIN_CHAR - 1, MAX_CHAR); + private static final Pattern PASSWORD_PATTERN = Pattern.compile(PASSWORD_FORMAT); + + private static final ImmutableSet INVALID_CHARS = ImmutableSet.of( + 'i', 'I', 'l', 'o', 'O', 'w', 'W', 'y', 'Y', 'z', 'Z', '1', '0'); + + public static boolean isValidPassword(String password) { + return PASSWORD_PATTERN.matcher(password).matches(); + } + + public static String generate() { + int count = random.nextInt(MAX_CHAR - MIN_CHAR) + MIN_CHAR; + + final char[] buffer = new char[count]; + + final int start = 'A'; + final int end = 'z'; + final int gap = end - start + 1; + + while (count-- != 0) { + char ch = (char) (random.nextInt(gap) + start); + if ((isBetween(ch, start, 'Z') || isBetween(ch, 'a', end)) + && !INVALID_CHARS.contains(ch)) + buffer[count] = ch; + else + count++; + } + return new String(buffer); + } + + private static boolean isBetween(char ch, int start, int end) { + return ch >= start && ch <= end; + } +} diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinderTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinderTest.java index dda2ed6908..42a1ad92f2 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinderTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/CreateSnapshotRequestBinderTest.java @@ -37,11 +37,11 @@ public class CreateSnapshotRequestBinderTest { } private final String expectedPayload - = (" \n" - + "\n" - + "123-1233-1324\n" - + "describing the snapshot\n" - + "snapshot name\n" - + "\n" - + "").replaceAll("\\s+", ""); + = (" \n" + + "\n" + + "123-1233-1324\n" + + "describing the snapshot\n" + + "snapshot name\n" + + "\n" + + "").replaceAll("\\s+", ""); } diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinderTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinderTest.java index 206cd79fc8..e1ba061f5d 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinderTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/binder/snapshot/RollbackSnapshotRequestBinderTest.java @@ -29,9 +29,9 @@ public class RollbackSnapshotRequestBinderTest { RollbackSnapshotRequestBinder binder = new RollbackSnapshotRequestBinder(); Snapshot.Request.RollbackPayload payload = Snapshot.Request.rollbackBuilder() - .snapshotId("snapshot-id") - .storageId("storage-id") - .build(); + .snapshotId("snapshot-id") + .storageId("storage-id") + .build(); String actual = binder.createPayload(payload); assertNotNull(actual, "Binder returned null payload"); @@ -39,9 +39,9 @@ public class RollbackSnapshotRequestBinderTest { } private final String expectedPayload = "" - + "" - + "snapshot-id" - + "storage-id" - + "" - + "".replaceAll("\\s", ""); + + "" + + "snapshot-id" + + "storage-id" + + "" + + "".replaceAll("\\s", ""); } diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapterLiveTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapterLiveTest.java new file mode 100644 index 0000000000..83540a57c4 --- /dev/null +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksComputeServiceAdapterLiveTest.java @@ -0,0 +1,74 @@ +/* + * 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 org.jclouds.compute.domain.NodeMetadata; +import org.testng.annotations.Test; + +import org.jclouds.compute.internal.BaseComputeServiceLiveTest; +import org.jclouds.sshj.config.SshjSshClientModule; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; +import org.jclouds.compute.domain.ExecResponse; +import org.jclouds.logging.config.LoggingModule; +import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; + +@Test(groups = "live", singleThreaded = true, testName = "ProfitBricksComputeServiceAdapterLiveTest") +public class ProfitBricksComputeServiceAdapterLiveTest extends BaseComputeServiceLiveTest { + + public ProfitBricksComputeServiceAdapterLiveTest() { + provider = "profitbricks"; + } + + @Override + protected Module getSshModule() { + return new SshjSshClientModule(); + } + + @Override + protected LoggingModule getLoggingModule() { + return new SLF4JLoggingModule(); + } + + @Override + public void testOptionToNotBlock() throws Exception { + // ProfitBricks implementation intentionally blocks until the node is 'AVAILABLE' + } + + @Override + protected void checkTagsInNodeEquals(NodeMetadata node, ImmutableSet tags) { + // ProfitBricks doesn't support tags + } + + @Override + protected void checkUserMetadataContains(NodeMetadata node, ImmutableMap userMetadata) { + // ProfitBricks doesn't support user metadata + } + + @Override + protected void checkResponseEqualsHostname(ExecResponse execResponse, NodeMetadata node1) { + // ProfitBricks doesn't support hostname + } + + @Override + protected void checkOsMatchesTemplate(NodeMetadata node) { + // Not enough description from API to match template + } + +} diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksTemplateBuilderLiveTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksTemplateBuilderLiveTest.java new file mode 100644 index 0000000000..eff7b011ae --- /dev/null +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/ProfitBricksTemplateBuilderLiveTest.java @@ -0,0 +1,37 @@ +/* + * 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 java.util.Set; + +import com.google.common.collect.ImmutableSet; +import org.jclouds.compute.internal.BaseTemplateBuilderLiveTest; +import org.testng.annotations.Test; + +@Test(groups = "live", testName = "ProfitBricksTemplateBuilderLiveTest") +public class ProfitBricksTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { + + public ProfitBricksTemplateBuilderLiveTest() { + this.provider = "profitbricks"; + } + + @Override + protected Set getIso3166Codes() { + return ImmutableSet.of(); + } + +} diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningManagerTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningManagerTest.java new file mode 100644 index 0000000000..dd115cc7bb --- /dev/null +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/concurrent/ProvisioningManagerTest.java @@ -0,0 +1,118 @@ +/* + * 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.concurrent; + +import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterruptibly; +import static java.util.logging.Logger.getAnonymousLogger; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.base.Throwables; + +@Test(groups = "unit", testName = "ProvisioningManagerTest") +public class ProvisioningManagerTest { + + @Test + public void testProvision() throws IOException { + ProvisioningManager manager = new ProvisioningManager(); + AtomicInteger completedJobs = new AtomicInteger(0); + + try { + for (int i = 0; i < 5; i++) { + manager.provision(new MockJob(200, "slow", completedJobs)); + manager.provision(new MockJob(0, "fast", completedJobs)); + manager.provision(new MockJob(100, "normal", completedJobs)); + } + } finally { + manager.close(); + } + + assertEquals(completedJobs.get(), 15); + } + + @Test + public void testProvisionInterrupted() { + ProvisioningManager manager = new ProvisioningManager(); + AtomicInteger completedJobs = new AtomicInteger(0); + + manager.provision(new ShutdownExecutorJob(manager, completedJobs)); + manager.provision(new MockJob(0, "rejected", completedJobs)); + + assertEquals(completedJobs.get(), 1); + } + + private static class MockJob extends ProvisioningJob { + + private final long delay; + private final AtomicInteger completedJobs; + + public MockJob(long delay, String group, AtomicInteger completedJobs) { + super(sleepPredicate(delay), group, Suppliers.ofInstance((Object) 0)); + this.delay = delay; + this.completedJobs = completedJobs; + } + + @Override + public Integer call() throws Exception { + getAnonymousLogger().info("ProvisioningManagerTest: Starting " + this); + super.call(); + getAnonymousLogger().info("ProvisioningManagerTest: Completed " + this); + return completedJobs.incrementAndGet(); + } + + @Override + public String toString() { + return "MockJob [id=" + hashCode() + ", group=" + getGroup() + ", delay=" + delay + "]"; + } + } + + private static class ShutdownExecutorJob extends ProvisioningJob { + + public ShutdownExecutorJob(final ProvisioningManager manager, final AtomicInteger completedJobs) { + super(Predicates.alwaysTrue(), "shutdown", new Supplier() { + @Override + public Integer get() { + try { + manager.close(); + return completedJobs.incrementAndGet(); + } catch (IOException ex) { + throw Throwables.propagate(ex); + } + } + }); + } + } + + private static Predicate sleepPredicate(final long delay) { + return new Predicate() { + @Override + public boolean apply(String input) { + sleepUninterruptibly(delay, TimeUnit.MILLISECONDS); + return true; + } + }; + } +} 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 new file mode 100644 index 0000000000..7dcf69cdc5 --- /dev/null +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/DataCenterToLocationTest.java @@ -0,0 +1,77 @@ +/* + * 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 new file mode 100644 index 0000000000..3967cf580e --- /dev/null +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/LocationToLocationTest.java @@ -0,0 +1,62 @@ +/* + * 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 new file mode 100644 index 0000000000..d114efb7e2 --- /dev/null +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ProvisionableToImageTest.java @@ -0,0 +1,260 @@ +/* + * 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 java.util.Date; + +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.profitbricks.domain.OsType; +import org.jclouds.profitbricks.domain.ProvisioningState; +import org.jclouds.profitbricks.domain.Snapshot; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableSet; + +@Test(groups = "unit", testName = "ProvisionableToImageTest") +public class ProvisionableToImageTest { + + private ProvisionableToImage fnImage; + 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.fnImage = new ProvisionableToImage(fnRegion); + } + + @Test + public void testImageToImage() { + org.jclouds.profitbricks.domain.Image image + = org.jclouds.profitbricks.domain.Image.builder() + .isBootable(true) + .isCpuHotPlug(true) + .isCpuHotUnPlug(false) + .isDiscVirtioHotPlug(true) + .isDiscVirtioHotUnPlug(true) + .id("5ad99c9e-9166-11e4-9d74-52540066fee9") + .name("Ubuntu-14.04-LTS-server-2015-01-01") + .size(2048f) + .type(org.jclouds.profitbricks.domain.Image.Type.HDD) + .location(Location.US_LAS) + .isNicHotPlug(true) + .isNicHotUnPlug(true) + .osType(OsType.LINUX) + .isPublic(true) + .isRamHotPlug(true) + .isRamHotUnPlug(false) + .isWriteable(true) + .build(); + + Image actual = fnImage.apply(image); + + Image expected = new ImageBuilder() + .ids(image.id()) + .name(image.name()) + .location(fnRegion.apply(Location.US_LAS)) + .status(Image.Status.AVAILABLE) + .operatingSystem(OperatingSystem.builder() + .description("UBUNTU") + .family(OsFamily.UBUNTU) + .version("14.04") + .is64Bit(false) + .build()) + .build(); + + assertEquals(actual, expected); + } + + @Test + public void testImageDescriptionParsing() { + org.jclouds.profitbricks.domain.Image image1 + = org.jclouds.profitbricks.domain.Image.builder() + .id("f4742db0-9160-11e4-9d74-52540066fee9") + .name("Fedora-19-server-2015-01-01") + .size(2048f) + .type(org.jclouds.profitbricks.domain.Image.Type.HDD) + .location(Location.DE_FRA) + .osType(OsType.LINUX) + .build(); + + Image actual1 = fnImage.apply(image1); + + Image expected1 = new ImageBuilder() + .ids(image1.id()) + .name(image1.name()) + .location(fnRegion.apply(image1.location())) + .status(Image.Status.AVAILABLE) + .operatingSystem(OperatingSystem.builder() + .description("FEDORA") + .family(OsFamily.FEDORA) + .version("7") + .is64Bit(true) + .build()) + .build(); + + assertEquals(actual1, expected1); + + org.jclouds.profitbricks.domain.Image image2 + = org.jclouds.profitbricks.domain.Image.builder() + .id("457bf707-d5d1-11e3-8b4f-52540066fee9") + .name("clearos-community-6.5.0-x86_64.iso") + .size(2048f) + .type(org.jclouds.profitbricks.domain.Image.Type.CDROM) + .location(Location.DE_FKB) + .osType(OsType.LINUX) + .build(); + + Image actual2 = fnImage.apply(image2); + + Image expected2 = new ImageBuilder() + .ids(image2.id()) + .name(image2.name()) + .location(fnRegion.apply(image2.location())) + .status(Image.Status.AVAILABLE) + .operatingSystem(OperatingSystem.builder() + .description("UNRECOGNIZED") + .family(OsFamily.UNRECOGNIZED) + .version("6.5.0") + .is64Bit(true) + .build()) + .build(); + + assertEquals(actual2, expected2); + + org.jclouds.profitbricks.domain.Image image3 + = org.jclouds.profitbricks.domain.Image.builder() + .id("e54af701-53b8-11e3-8f17-52540066fee9") + .name("windows-2008-r2-server-setup.iso") + .size(2048f) + .type(org.jclouds.profitbricks.domain.Image.Type.CDROM) + .location(Location.US_LASDEV) + .osType(OsType.WINDOWS) + .build(); + + Image actual3 = fnImage.apply(image3); + + Image expected3 = new ImageBuilder() + .ids(image3.id()) + .name(image3.name()) + .location(fnRegion.apply(image3.location())) + .status(Image.Status.AVAILABLE) + .operatingSystem(OperatingSystem.builder() + .description("WINDOWS") + .family(OsFamily.WINDOWS) + .version("2008") + .is64Bit(false) + .build()) + .build(); + + assertEquals(actual3, expected3); + + } + + @Test + public void testSnapshotToImage() { + Snapshot snapshot1 = Snapshot.builder() + .isBootable(true) + .isCpuHotPlug(true) + .isCpuHotUnPlug(false) + .isDiscVirtioHotPlug(true) + .isDiscVirtioHotUnPlug(true) + .id("qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh") + .name("placeholder-snapshot-04/13/2015") + .description("Created from \"placeholder\" in Data Center \"sbx-computeservice\"") + .size(2048f) + .location(Location.US_LAS) + .isNicHotPlug(true) + .isNicHotUnPlug(true) + .osType(OsType.LINUX) + .isRamHotPlug(true) + .isRamHotUnPlug(false) + .creationTime(new Date(2015, 4, 13)) + .lastModificationTime(new Date()) + .state(ProvisioningState.AVAILABLE) + .build(); + + Image actual1 = fnImage.apply(snapshot1); + + Image expected1 = new ImageBuilder() + .ids(snapshot1.id()) + .name(snapshot1.name()) + .location(fnRegion.apply(Location.US_LAS)) + .status(Image.Status.AVAILABLE) + .operatingSystem(OperatingSystem.builder() + .description(snapshot1.description()) + .family(OsFamily.LINUX) + .is64Bit(true) + .build()) + .build(); + + assertEquals(actual1, expected1); + + Snapshot snapshot2 = Snapshot.builder() + .isBootable(true) + .isCpuHotPlug(true) + .isCpuHotUnPlug(false) + .isDiscVirtioHotPlug(true) + .isDiscVirtioHotUnPlug(true) + .id("d80bf9c0-ce6e-4283-9ea4-2906635f6137") + .name("jclouds-ubuntu14.10-template") + .description("Created from \"jclouds-ubuntu14.10 Storage\" in Data Center \"jclouds-computeservice\"") + .size(10240f) + .location(Location.DE_FKB) + .isNicHotPlug(true) + .isNicHotUnPlug(true) + .osType(OsType.LINUX) + .isRamHotPlug(true) + .isRamHotUnPlug(false) + .creationTime(new Date(2015, 4, 13)) + .lastModificationTime(new Date()) + .state(ProvisioningState.INPROCESS) + .build(); + + Image actual2 = fnImage.apply(snapshot2); + + Image expected2 = new ImageBuilder() + .ids(snapshot2.id()) + .name(snapshot2.name()) + .location(fnRegion.apply(Location.DE_FKB)) + .status(Image.Status.PENDING) + .operatingSystem(OperatingSystem.builder() + .description("ubuntu") + .family(OsFamily.UBUNTU) + .is64Bit(true) + .version("00.00") + .build()) + .build(); + + assertEquals(actual2, expected2); + assertEquals(actual2.getOperatingSystem(), expected2.getOperatingSystem()); + + } +} 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 new file mode 100644 index 0000000000..5fba62bb10 --- /dev/null +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/ServerToNodeMetadataTest.java @@ -0,0 +1,184 @@ +/* + * 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 static org.testng.Assert.assertNotNull; + +import java.util.Set; + +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadataBuilder; +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.domain.VolumeBuilder; +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.ProfitBricksApiMetadata; +import org.jclouds.profitbricks.domain.AvailabilityZone; +import org.jclouds.profitbricks.domain.DataCenter; +import org.jclouds.profitbricks.domain.Nic; +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.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; +import com.google.inject.name.Names; + +@Test(groups = "unit", testName = "ServerToNodeMetadataTest") +public class ServerToNodeMetadataTest { + + private ServerToNodeMetadata fnNodeMetadata; + + @BeforeTest + 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")) + .parent(new LocationBuilder() + .id("de/fra") + .description("Germany, Frankfurt (M)") + .scope(LocationScope.PROVIDER) + .build()) + .build()); + } + }; + + GroupNamingConvention.Factory namingConvention = Guice.createInjector(new AbstractModule() { + @Override + protected void configure() { + Names.bindProperties(binder(), new ProfitBricksApiMetadata().getDefaultProperties()); + } + }).getInstance(GroupNamingConvention.Factory.class); + + this.fnNodeMetadata = new ServerToNodeMetadata(new StorageToVolume(), locationsSupply, namingConvention); + } + + @Test + public void testServerToNodeMetadata() { + Server server = Server.builder() + .dataCenter(DataCenter.builder() + .id("12345678-abcd-efgh-ijkl-987654321000").version(10) + .build()) + .id("qwertyui-qwer-qwer-qwer-qwertyyuiiop") + .name("mock-facebook-node") + .cores(4) + .ram(4096) + .hasInternetAccess(true) + .state(ProvisioningState.AVAILABLE) + .status(Server.Status.RUNNING) + .osType(OsType.LINUX) + .availabilityZone(AvailabilityZone.AUTO) + .isCpuHotPlug(true) + .isRamHotPlug(true) + .isNicHotPlug(true) + .isNicHotUnPlug(true) + .isDiscVirtioHotPlug(true) + .isDiscVirtioHotUnPlug(true) + .storages(ImmutableList.of( + Storage.builder() + .bootDevice(true) + .busType(Storage.BusType.VIRTIO) + .deviceNumber(1) + .size(40f) + .id("qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh") + .name("facebook-storage") + .build() + ) + ) + .nics(ImmutableList.of( + Nic.builder() + .id("qwqwqwqw-wewe-erer-rtrt-tytytytytyty") + .lanId(1) + .dataCenterId("12345678-abcd-efgh-ijkl-987654321000") + .internetAccess(true) + .serverId("qwertyui-qwer-qwer-qwer-qwertyyuiiop") + .macAddress("02:01:09:cd:f0:b0") + .ip("173.252.120.6") + .build() + ) + ) + .build(); + + NodeMetadata expected = fnNodeMetadata.apply(server); + assertNotNull(expected); + + NodeMetadata actual = new NodeMetadataBuilder() + .group("mock") + .ids(server.id()) + .name(server.name()) + .backendStatus("AVAILABLE") + .status(NodeMetadata.Status.RUNNING) + .hardware(new HardwareBuilder() + .ids("cpu=4,ram=4096,disk=40") + .name("cpu=4,ram=4096,disk=40") + .ram(server.ram()) + .processor(new Processor(server.cores(), 1d)) + .hypervisor("kvm") + .volume(new VolumeBuilder() + .bootDevice(true) + .size(40f) + .id("qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh") + .durable(true) + .type(Volume.Type.LOCAL) + .build()) + .build()) + .operatingSystem(new OperatingSystem.Builder() + .description(OsFamily.LINUX.value()) + .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")) + .parent(new LocationBuilder() + .id("de/fra") + .description("Germany, Frankfurt (M)") + .scope(LocationScope.PROVIDER) + .build()) + .build()) + .publicAddresses(ImmutableList.of("173.252.120.6")) + .build(); + + assertEquals(actual, expected); + } +} diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/StorageToVolumeTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/StorageToVolumeTest.java new file mode 100644 index 0000000000..8a782e7fbc --- /dev/null +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/function/StorageToVolumeTest.java @@ -0,0 +1,61 @@ +/* + * 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 org.jclouds.compute.domain.Volume; +import org.jclouds.compute.domain.VolumeBuilder; +import org.jclouds.profitbricks.domain.Storage; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "StorageToVolumeTest") +public class StorageToVolumeTest { + + private StorageToVolume fnVolume; + + @BeforeTest + public void setup() { + this.fnVolume = new StorageToVolume(); + } + + @Test + public void testStorageToVolume() { + Storage storage = Storage.builder() + .id("qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh") + .size(40) + .name("hdd-1") + .busType(Storage.BusType.VIRTIO) + .bootDevice(true) + .deviceNumber(1) + .build(); + + Volume actual = fnVolume.apply(storage); + + Volume expected = new VolumeBuilder() + .id(storage.id()) + .size(40f) + .bootDevice(true) + .device("1") + .type(Volume.Type.LOCAL) + .durable(true) + .build(); + + assertEquals(actual, expected); + } +} diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicateTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicateTest.java index 857a8ff89b..690412ac7d 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicateTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/compute/internal/ProvisioningStatusPollingPredicateTest.java @@ -136,10 +136,10 @@ public class ProvisioningStatusPollingPredicateTest extends BaseProfitBricksMock server.shutdown(); } } - + @Test - public void testSnapshotPredicate() throws Exception{ - MockWebServer server = mockWebServer(); + public void testSnapshotPredicate() throws Exception { + MockWebServer server = mockWebServer(); byte[] payloadInProcess = payloadFromResource("/snapshot/snapshot-state-inprocess.xml"); byte[] payloadAvailable = payloadFromResource("/snapshot/snapshot.xml"); diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/DrivesApiLiveTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/DrivesApiLiveTest.java index 20cf5f801d..8e84746cba 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/DrivesApiLiveTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/DrivesApiLiveTest.java @@ -16,16 +16,15 @@ */ package org.jclouds.profitbricks.features; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; + import java.util.List; import org.jclouds.profitbricks.BaseProfitBricksLiveTest; import org.jclouds.profitbricks.domain.Drive; import org.jclouds.profitbricks.domain.Image; import org.jclouds.profitbricks.domain.Server; - -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNotNull; - import org.testng.annotations.Test; import com.google.common.collect.Iterables; @@ -67,7 +66,7 @@ public class DrivesApiLiveTest extends BaseProfitBricksLiveTest { assertNotNull(requestId); } - @Test (dependsOnMethods = "addRomDriveToServerTest") + @Test(dependsOnMethods = "addRomDriveToServerTest") public void removeRomDriveFromServerTest() { String requestId = api.drivesApi().removeRomDriveFromServer(imageId, serverId); diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/FirewallApiLiveTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/FirewallApiLiveTest.java index cd38494b8b..ddf94d411f 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/FirewallApiLiveTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/FirewallApiLiveTest.java @@ -16,7 +16,6 @@ */ package org.jclouds.profitbricks.features; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import java.util.List; @@ -41,6 +40,7 @@ import org.testng.annotations.AfterClass; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; @Test(groups = "live", testName = "FirewallApiLiveTest", singleThreaded = true) public class FirewallApiLiveTest extends BaseProfitBricksLiveTest { diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/IpBlockApiLiveTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/IpBlockApiLiveTest.java index 227cfc7ee6..e7c2eda498 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/IpBlockApiLiveTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/IpBlockApiLiveTest.java @@ -47,7 +47,7 @@ public class IpBlockApiLiveTest extends BaseProfitBricksLiveTest { @Test public void testReservePublicIpBlock() { - newIpBlock = api.ipBlockApi().reservePublicIpBlock("2", Location.US_LAS.value()); + newIpBlock = api.ipBlockApi().reservePublicIpBlock("2", Location.US_LAS.getId()); assertNotNull(newIpBlock); assertNotNull(newIpBlock.ips()); diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/IpBlockApiMockTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/IpBlockApiMockTest.java index b0d33561c5..e948e767bf 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/IpBlockApiMockTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/IpBlockApiMockTest.java @@ -122,9 +122,9 @@ public class IpBlockApiMockTest extends BaseProfitBricksMockTest { String blockSize = "2"; Location location = Location.US_LAS; - String content = "" + blockSize + "" + location.value() + ""; + String content = "" + blockSize + "" + location.getId() + ""; try { - IpBlock ipBlock = api.reservePublicIpBlock(blockSize, location.value()); + IpBlock ipBlock = api.reservePublicIpBlock(blockSize, location.getId()); assertRequestHasCommonProperties(server.takeRequest(), content); assertNotNull(ipBlock); } finally { diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/LoadbalancerApiLiveTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/LoadbalancerApiLiveTest.java index a79f9ae19c..d5e64cf577 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/LoadbalancerApiLiveTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/LoadbalancerApiLiveTest.java @@ -128,7 +128,7 @@ public class LoadbalancerApiLiveTest extends BaseProfitBricksLiveTest { @AfterClass(alwaysRun = true) public void testDeleteLoadBalancer() { - boolean result = api.loadBalancerApi().deleteLoadbalancer(loadBalancerID); + boolean result = api.loadBalancerApi().deleteLoadBalancer(loadBalancerID); Assert.assertTrue(result); } diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/LoadbalancerApiMockTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/LoadbalancerApiMockTest.java index f91083acc9..1271244781 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/LoadbalancerApiMockTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/LoadbalancerApiMockTest.java @@ -273,7 +273,7 @@ public class LoadbalancerApiMockTest extends BaseProfitBricksMockTest { String content = "" + loadBalancerId + ""; try { - boolean done = api.deleteLoadbalancer(loadBalancerId); + boolean done = api.deleteLoadBalancer(loadBalancerId); assertRequestHasCommonProperties(server.takeRequest(), content); assertTrue(done); diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiLiveTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiLiveTest.java index 957555b30e..6c50f2ab3a 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiLiveTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiLiveTest.java @@ -89,20 +89,20 @@ public class SnapshotApiLiveTest extends BaseProfitBricksLiveTest { String newName = "new name"; api.snapshotApi().updateSnapshot(Snapshot.Request.updatingBuilder() - .snapshotId(snapshotId) - .description("new description") - .name(newName) - .bootable(true) - .osType(OsType.LINUX) - .cpuHotplug(true) - .cpuHotunplug(true) - .discVirtioHotplug(true) - .discVirtioHotunplug(true) - .nicHotplug(true) - .nicHotunplug(true) - .ramHotplug(true) - .ramHotunplug(true) - .build()); + .snapshotId(snapshotId) + .description("new description") + .name(newName) + .bootable(true) + .osType(OsType.LINUX) + .isCpuHotPlug(true) + .isCpuHotUnPlug(true) + .isDiscVirtioHotPlug(true) + .isDiscVirtioHotUnPlug(true) + .isNicHotPlug(true) + .isNicHotUnPlug(true) + .isRamHotPlug(true) + .isRamHotUnPlug(true) + .build()); Snapshot snapshot = api.snapshotApi().getSnapshot(snapshotId); @@ -126,7 +126,7 @@ public class SnapshotApiLiveTest extends BaseProfitBricksLiveTest { private void initializeWaitPredicate() { this.snapshotWaitingPredicate = Predicates2.retry( - new ProvisioningStatusPollingPredicate(api, ProvisioningStatusAware.SNAPSHOT, ProvisioningState.AVAILABLE), - 2l * 60l, 2l, TimeUnit.SECONDS); + new ProvisioningStatusPollingPredicate(api, ProvisioningStatusAware.SNAPSHOT, ProvisioningState.AVAILABLE), + 2l * 60l, 2l, TimeUnit.SECONDS); } } diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiMockTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiMockTest.java index 80342b02da..528f893269 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiMockTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/features/SnapshotApiMockTest.java @@ -47,13 +47,13 @@ public class SnapshotApiMockTest extends BaseProfitBricksMockTest { SnapshotApi api = pbApi.snapshotApi(); try { - List snapshots = api.getAllSnapshots(); - assertRequestHasCommonProperties(server.takeRequest(), ""); - assertNotNull(snapshots); - assertEquals(snapshots.size(), 2); + List snapshots = api.getAllSnapshots(); + assertRequestHasCommonProperties(server.takeRequest(), ""); + assertNotNull(snapshots); + assertEquals(snapshots.size(), 2); } finally { - pbApi.close(); - server.shutdown(); + pbApi.close(); + server.shutdown(); } } @@ -66,12 +66,12 @@ public class SnapshotApiMockTest extends BaseProfitBricksMockTest { SnapshotApi api = pbApi.snapshotApi(); try { - List snapshots = api.getAllSnapshots(); - assertRequestHasCommonProperties(server.takeRequest()); - assertTrue(snapshots.isEmpty()); + List snapshots = api.getAllSnapshots(); + assertRequestHasCommonProperties(server.takeRequest()); + assertTrue(snapshots.isEmpty()); } finally { - pbApi.close(); - server.shutdown(); + pbApi.close(); + server.shutdown(); } } @@ -88,13 +88,13 @@ public class SnapshotApiMockTest extends BaseProfitBricksMockTest { String content = "" + id + ""; try { - Snapshot snapshot = api.getSnapshot(id); - assertRequestHasCommonProperties(server.takeRequest(), content); - assertNotNull(snapshot); - assertEquals(snapshot.id(), id); + Snapshot snapshot = api.getSnapshot(id); + assertRequestHasCommonProperties(server.takeRequest(), content); + assertNotNull(snapshot); + assertEquals(snapshot.id(), id); } finally { - pbApi.close(); - server.shutdown(); + pbApi.close(); + server.shutdown(); } } @@ -108,12 +108,12 @@ public class SnapshotApiMockTest extends BaseProfitBricksMockTest { String id = "random-non-existing-id"; try { - Snapshot snapshot = api.getSnapshot(id); - assertRequestHasCommonProperties(server.takeRequest()); - assertNull(snapshot); + Snapshot snapshot = api.getSnapshot(id); + assertRequestHasCommonProperties(server.takeRequest()); + assertNull(snapshot); } finally { - pbApi.close(); - server.shutdown(); + pbApi.close(); + server.shutdown(); } } @@ -128,27 +128,27 @@ public class SnapshotApiMockTest extends BaseProfitBricksMockTest { String storageId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"; String content = "" - + "" - + "" + storageId + "" - + "description" - + "snapshot-name" - + "" - + ""; + + "" + + "" + storageId + "" + + "description" + + "snapshot-name" + + "" + + ""; try { - Snapshot snapshot = api.createSnapshot( - Snapshot.Request.creatingBuilder() - .storageId(storageId) - .description("description") - .name("snapshot-name") - .build()); - assertRequestHasCommonProperties(server.takeRequest(), content); - assertNotNull(snapshot.id()); - assertEquals(snapshot.id(), "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"); + Snapshot snapshot = api.createSnapshot( + Snapshot.Request.creatingBuilder() + .storageId(storageId) + .description("description") + .name("snapshot-name") + .build()); + assertRequestHasCommonProperties(server.takeRequest(), content); + assertNotNull(snapshot.id()); + assertEquals(snapshot.id(), "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"); } finally { - pbApi.close(); - server.shutdown(); + pbApi.close(); + server.shutdown(); } } @@ -163,35 +163,43 @@ public class SnapshotApiMockTest extends BaseProfitBricksMockTest { String snapshotId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"; String content = "" - + "" - + "" + snapshotId + "" - + "description" - + "snapshot-name" - + "false" - + "LINUX" - + "false" - + "false" - + "false" - + "false" - + "false" - + "false" - + "false" - + "false" - + "" - + ""; + + "" + + "" + snapshotId + "" + + "description" + + "snapshot-name" + + "false" + + "LINUX" + + "false" + + "false" + + "false" + + "false" + + "false" + + "false" + + "false" + + "false" + + "" + + ""; try { - String requestId = api.updateSnapshot(Snapshot.Request.updatingBuilder() - .snapshotId(snapshotId) - .name("snapshot-name") - .description("description") - .osType(OsType.LINUX) - .build()); - assertRequestHasCommonProperties(server.takeRequest(), content); - assertNotNull(requestId); + String requestId = api.updateSnapshot(Snapshot.Request.updatingBuilder() + .snapshotId(snapshotId) + .name("snapshot-name") + .description("description") + .osType(OsType.LINUX) + .isCpuHotPlug(false) + .isCpuHotUnPlug(false) + .isDiscVirtioHotPlug(false) + .isDiscVirtioHotUnPlug(false) + .isNicHotPlug(false) + .isNicHotUnPlug(false) + .isRamHotPlug(false) + .isRamHotUnPlug(false) + .build()); + assertRequestHasCommonProperties(server.takeRequest(), content); + assertNotNull(requestId); } finally { - pbApi.close(); - server.shutdown(); + pbApi.close(); + server.shutdown(); } } @@ -207,12 +215,12 @@ public class SnapshotApiMockTest extends BaseProfitBricksMockTest { String content = "" + snapshotId + ""; try { - boolean result = api.deleteSnapshot(snapshotId); - assertRequestHasCommonProperties(server.takeRequest(), content); - assertTrue(result); + boolean result = api.deleteSnapshot(snapshotId); + assertRequestHasCommonProperties(server.takeRequest(), content); + assertTrue(result); } finally { - pbApi.close(); - server.shutdown(); + pbApi.close(); + server.shutdown(); } } @@ -226,12 +234,12 @@ public class SnapshotApiMockTest extends BaseProfitBricksMockTest { String id = "random-non-existing-id"; try { - boolean result = api.deleteSnapshot(id); - assertRequestHasCommonProperties(server.takeRequest()); - Assert.assertFalse(result); + boolean result = api.deleteSnapshot(id); + assertRequestHasCommonProperties(server.takeRequest()); + Assert.assertFalse(result); } finally { - pbApi.close(); - server.shutdown(); + pbApi.close(); + server.shutdown(); } } @@ -248,15 +256,15 @@ public class SnapshotApiMockTest extends BaseProfitBricksMockTest { String content = "" + snapshotId + "" + storageId + ""; try { - String result = api.rollbackSnapshot(Snapshot.Request.rollbackBuilder() - .snapshotId(snapshotId) - .storageId(storageId) - .build()); - assertRequestHasCommonProperties(server.takeRequest(), content); - assertNotNull(result); + String result = api.rollbackSnapshot(Snapshot.Request.rollbackBuilder() + .snapshotId(snapshotId) + .storageId(storageId) + .build()); + assertRequestHasCommonProperties(server.takeRequest(), content); + assertNotNull(result); } finally { - pbApi.close(); - server.shutdown(); + pbApi.close(); + server.shutdown(); } } } diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/datacenter/DataCenterInfoResponseHandlerTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/datacenter/DataCenterInfoResponseHandlerTest.java index e2ee87e16e..16b25043cf 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/datacenter/DataCenterInfoResponseHandlerTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/datacenter/DataCenterInfoResponseHandlerTest.java @@ -19,8 +19,7 @@ package org.jclouds.profitbricks.http.parser.datacenter; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; -import org.jclouds.date.DateCodec; -import org.jclouds.date.DateCodecFactory; +import org.jclouds.date.DateService; import org.jclouds.http.functions.ParseSax; import org.jclouds.profitbricks.domain.AvailabilityZone; import org.jclouds.profitbricks.domain.DataCenter; @@ -44,8 +43,8 @@ public class DataCenterInfoResponseHandlerTest extends BaseResponseHandlerTestof( Server.builder() + .dataCenter(DataCenter.builder() + .id("12345678-abcd-efgh-ijkl-987654321000") + .version(10) + .build() + ) .id("qqqqqqqq-wwww-eeee-rrrr-tttttttttttt") .name("jnode1") .cores(4) @@ -72,8 +76,8 @@ public class DataCenterInfoResponseHandlerTest extends BaseResponseHandlerTest actual = parser.parse(payloadFromResource("/loadbalancer/loadbalancers.xml")); assertNotNull(actual, "Parsed content returned null"); - DateCodec dateParser = createDateParser().iso8601(); + DateService dateParser = createDateParser(); - List expected = ImmutableList.of(LoadBalancer.builder().id("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee").loadBalancerAlgorithm(Algorithm.ROUND_ROBIN).name("load-1234567890-name") - .dataCenterId("datacenter-id").dataCenterVersion("datacenter-version").internetAccess(true).ip("192.168.0.1").lanId("lan-id").state(ProvisioningState.AVAILABLE).creationTime(dateParser.toDate("2014-12-04T07:09:23.138Z")).lastModificationTime(dateParser.toDate("2014-12-04T07:09:23.138Z")) + List expected = ImmutableList.of( + LoadBalancer.builder() + .id("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee") + .algorithm(Algorithm.ROUND_ROBIN) + .name("load-1234567890-name") + .dataCenter(DataCenter.builder() + .id("datacenter-id") + .version(4) + .build()) + .internetAccess(true) + .ip("192.168.0.1") + .lanId("lan-id") + .state(ProvisioningState.AVAILABLE) + .creationTime(dateParser.iso8601DateOrSecondsDateParse("2014-12-04T07:09:23.138Z")) + .lastModificationTime(dateParser.iso8601DateOrSecondsDateParse("2014-12-04T07:09:23.138Z")) .firewalls(ImmutableList.of( - Firewall.builder().id("firewall-id").nicId("nic-id").active(false).state(ProvisioningState.AVAILABLE).build() + Firewall.builder() + .id("firewall-id") + .nicId("nic-id") + .active(false) + .state(ProvisioningState.AVAILABLE) + .build() )) .balancedServers(ImmutableList.of( - Server.builder().activate(true).balancedNicId("balanced-nic-id").id("server-id").name("server-name").build() + Server.builder() + .loadBalanced(true) + .balancedNicId("balanced-nic-id") + .id("server-id") + .name("server-name") + .build() )).build(), - LoadBalancer.builder().id("qqqqqqqq-wwww-rrrr-tttt-yyyyyyyyyyyy").loadBalancerAlgorithm(Algorithm.ROUND_ROBIN).name("load-balancer-name") - .dataCenterId("datacenter-id").dataCenterVersion("datacenter-version").internetAccess(false).ip("192.168.0.1").lanId("lan-id").state(ProvisioningState.AVAILABLE).creationTime(dateParser.toDate("2014-12-04T07:09:23.138Z")).lastModificationTime(dateParser.toDate("2014-12-04T07:09:23.138Z")) + LoadBalancer.builder() + .id("qqqqqqqq-wwww-rrrr-tttt-yyyyyyyyyyyy") + .algorithm(Algorithm.ROUND_ROBIN) + .name("load-balancer-name") + .dataCenter(DataCenter.builder() + .id("datacenter-id") + .version(4) + .build()) + .internetAccess(false) + .ip("192.168.0.1") + .lanId("lan-id") + .state(ProvisioningState.AVAILABLE) + .creationTime(dateParser.iso8601DateOrSecondsDateParse("2014-12-04T07:09:23.138Z")) + .lastModificationTime(dateParser.iso8601DateOrSecondsDateParse("2014-12-04T07:09:23.138Z")) .firewalls(ImmutableList.of( - Firewall.builder().id("firewall-id").nicId("nic-id").active(false).state(ProvisioningState.AVAILABLE).build() + Firewall.builder() + .id("firewall-id") + .nicId("nic-id") + .active(false) + .state(ProvisioningState.AVAILABLE) + .build() )) .balancedServers(ImmutableList.of( - Server.builder().activate(false).balancedNicId("balanced-nic-id").id("server-id").name("server-name").build() + Server.builder() + .loadBalanced(false) + .balancedNicId("balanced-nic-id") + .id("server-id") + .name("server-name") + .build() )) .build() ); diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerResponseHandlerTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerResponseHandlerTest.java index 365383b2d9..079c5c06c0 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerResponseHandlerTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/loadbalancer/LoadBalancerResponseHandlerTest.java @@ -17,9 +17,9 @@ package org.jclouds.profitbricks.http.parser.loadbalancer; import com.google.common.collect.Lists; + import java.util.List; -import org.jclouds.date.DateCodec; -import org.jclouds.date.DateCodecFactory; + import org.jclouds.http.functions.ParseSax; import org.jclouds.profitbricks.domain.Firewall; import org.jclouds.profitbricks.domain.LoadBalancer; @@ -28,8 +28,12 @@ import org.jclouds.profitbricks.domain.ProvisioningState; import org.jclouds.profitbricks.domain.Server; import org.jclouds.profitbricks.domain.Storage; import org.jclouds.profitbricks.http.parser.BaseResponseHandlerTest; + import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; + +import org.jclouds.date.DateService; +import org.jclouds.profitbricks.domain.DataCenter; import org.testng.annotations.Test; @Test(groups = "unit", testName = "LoadBalancerResponseHandlerTest") @@ -40,8 +44,8 @@ public class LoadBalancerResponseHandlerTest extends BaseResponseHandlerTest emptyStorages = Lists.newArrayList(); List balancedServers = Lists.newArrayList(); balancedServers.add(Server.builder() - .activate(true) + .loadBalanced(true) .balancedNicId("balanced-nic-id") .id("server-id") .name("server-name") @@ -73,16 +77,18 @@ public class LoadBalancerResponseHandlerTest extends BaseResponseHandlerTestof( Storage.builder() diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/server/ServerListResponseHandlerTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/server/ServerListResponseHandlerTest.java index 1442ba97aa..ea5d46d406 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/server/ServerListResponseHandlerTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/server/ServerListResponseHandlerTest.java @@ -20,8 +20,6 @@ import com.google.common.collect.ImmutableList; import java.util.List; -import org.jclouds.date.DateCodec; -import org.jclouds.date.DateCodecFactory; import org.jclouds.http.functions.ParseSax; import org.jclouds.profitbricks.domain.AvailabilityZone; import org.jclouds.profitbricks.domain.OsType; @@ -32,6 +30,8 @@ import org.jclouds.profitbricks.http.parser.BaseResponseHandlerTest; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; +import org.jclouds.date.DateService; +import org.jclouds.profitbricks.domain.DataCenter; import org.jclouds.profitbricks.domain.Firewall; import org.jclouds.profitbricks.domain.Nic; import org.jclouds.profitbricks.domain.Storage; @@ -45,8 +45,8 @@ public class ServerListResponseHandlerTest extends BaseResponseHandlerTest actual = parser.parse(payloadFromResource("/server/servers.xml")); assertNotNull(actual, "Parsed content returned null"); - DateCodec dateParser = createDateParser().iso8601(); + DateService dateParser = createDateParser(); List expected = ImmutableList.of( Server.builder() + .dataCenter(DataCenter.builder() + .id("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee") + .version(10) + .build() + ) .id("qwertyui-qwer-qwer-qwer-qwertyyuiiop") .name("facebook-node") .cores(4) @@ -67,8 +72,8 @@ public class ServerListResponseHandlerTest extends BaseResponseHandlerTestof( Storage.builder() @@ -113,6 +118,11 @@ public class ServerListResponseHandlerTest extends BaseResponseHandlerTestof( Storage.builder() diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandlerTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandlerTest.java index 38dfa1e683..f9f93d0414 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandlerTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotListResponseHandlerTest.java @@ -17,17 +17,20 @@ package org.jclouds.profitbricks.http.parser.snapshot; import com.google.common.collect.Lists; + import java.util.List; -import org.jclouds.date.DateCodec; -import org.jclouds.date.DateCodecFactory; + import org.jclouds.http.functions.ParseSax; import org.jclouds.profitbricks.domain.Location; import org.jclouds.profitbricks.domain.OsType; import org.jclouds.profitbricks.domain.ProvisioningState; import org.jclouds.profitbricks.domain.Snapshot; import org.jclouds.profitbricks.http.parser.BaseResponseHandlerTest; + import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; + +import org.jclouds.date.DateService; import org.testng.annotations.Test; @Test(groups = "unit", testName = "SnapshotListResponseHandlerTest") @@ -38,8 +41,8 @@ public class SnapshotListResponseHandlerTest extends BaseResponseHandlerTest actual = parser.parse(payloadFromResource("/snapshot/snapshots.xml")); assertNotNull(actual); - DateCodec dateParser = createDateParser().iso8601(); + DateService dateParser = createDateParser(); List expected = Lists.newArrayList(); expected.add(Snapshot.builder() - .id("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee") - .description("description") - .size(1024) - .name("snapshot01") - .state(ProvisioningState.AVAILABLE) - .bootable(true) - .osType(OsType.LINUX) - .cpuHotPlug(true) - .cpuHotUnPlug(true) - .discVirtioHotPlug(true) - .discVirtioHotUnPlug(true) - .ramHotPlug(true) - .ramHotUnPlug(true) - .nicHotPlug(true) - .nicHotUnPlug(true) - .location(Location.US_LAS) - .creationTime(dateParser.toDate("2015-01-26T07:09:23.138Z")) - .lastModificationTime(dateParser.toDate("2015-01-26T07:09:23.138Z")) - .build()); + .id("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee") + .description("description") + .size(1024) + .name("snapshot01") + .state(ProvisioningState.AVAILABLE) + .isBootable(true) + .osType(OsType.LINUX) + .isCpuHotPlug(true) + .isCpuHotUnPlug(true) + .isDiscVirtioHotPlug(true) + .isDiscVirtioHotUnPlug(true) + .isRamHotPlug(true) + .isRamHotUnPlug(true) + .isNicHotPlug(true) + .isNicHotUnPlug(true) + .location(Location.US_LAS) + .creationTime(dateParser.iso8601DateOrSecondsDateParse("2015-01-26T07:09:23.138Z")) + .lastModificationTime(dateParser.iso8601DateOrSecondsDateParse("2015-01-26T07:09:23.138Z")) + .build()); expected.add(Snapshot.builder() - .id("qqqqqqqq-wwww-rrrr-tttt-yyyyyyyyyyyy") - .description("description") - .size(1024) - .name("snapshot02") - .state(ProvisioningState.AVAILABLE) - .bootable(true) - .osType(OsType.LINUX) - .cpuHotPlug(true) - .cpuHotUnPlug(true) - .discVirtioHotPlug(true) - .discVirtioHotUnPlug(true) - .ramHotPlug(true) - .ramHotUnPlug(true) - .nicHotPlug(true) - .nicHotUnPlug(true) - .location(Location.US_LAS) - .creationTime(dateParser.toDate("2015-01-26T07:09:23.138Z")) - .lastModificationTime(dateParser.toDate("2015-01-26T07:09:23.138Z")) - .build()); + .id("qqqqqqqq-wwww-rrrr-tttt-yyyyyyyyyyyy") + .description("description") + .size(1024) + .name("snapshot02") + .state(ProvisioningState.AVAILABLE) + .isBootable(true) + .osType(OsType.LINUX) + .isCpuHotPlug(true) + .isCpuHotUnPlug(true) + .isDiscVirtioHotPlug(true) + .isDiscVirtioHotUnPlug(true) + .isRamHotPlug(true) + .isRamHotUnPlug(true) + .isNicHotPlug(true) + .isNicHotUnPlug(true) + .location(Location.US_LAS) + .creationTime(dateParser.iso8601DateOrSecondsDateParse("2015-01-26T07:09:23.138Z")) + .lastModificationTime(dateParser.iso8601DateOrSecondsDateParse("2015-01-26T07:09:23.138Z")) + .build()); assertEquals(actual, expected); } diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandlerTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandlerTest.java index 9928e92e6c..ced181414b 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandlerTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/snapshot/SnapshotResponseHandlerTest.java @@ -16,16 +16,17 @@ */ package org.jclouds.profitbricks.http.parser.snapshot; -import org.jclouds.date.DateCodec; -import org.jclouds.date.DateCodecFactory; import org.jclouds.http.functions.ParseSax; import org.jclouds.profitbricks.domain.Location; import org.jclouds.profitbricks.domain.OsType; import org.jclouds.profitbricks.domain.ProvisioningState; import org.jclouds.profitbricks.domain.Snapshot; import org.jclouds.profitbricks.http.parser.BaseResponseHandlerTest; + import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; + +import org.jclouds.date.DateService; import org.testng.annotations.Test; @Test(groups = "unit", testName = "ServerResponseHandlerTest") @@ -36,8 +37,8 @@ public class SnapshotResponseHandlerTest extends BaseResponseHandlerTestof("qwertyui-qwer-qwer-qwer-qwertyyuiiop")) - .creationTime(dateParser.toDate("2014-12-04T07:09:23.138Z")) - .lastModificationTime(dateParser.toDate("2014-12-12T03:14:48.316Z")) + .creationTime(dateParser.iso8601DateOrSecondsDateParse("2014-12-04T07:09:23.138Z")) + .lastModificationTime(dateParser.iso8601DateOrSecondsDateParse("2014-12-12T03:14:48.316Z")) .build(); assertEquals(actual, expected); diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/storage/StorageListResponseHandlerTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/storage/StorageListResponseHandlerTest.java index 62e43fca85..9ac696dd1f 100644 --- a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/storage/StorageListResponseHandlerTest.java +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/http/parser/storage/StorageListResponseHandlerTest.java @@ -23,8 +23,7 @@ import com.google.common.collect.ImmutableList; import java.util.List; -import org.jclouds.date.DateCodec; -import org.jclouds.date.DateCodecFactory; +import org.jclouds.date.DateService; import org.jclouds.http.functions.ParseSax; import org.jclouds.profitbricks.domain.ProvisioningState; import org.jclouds.profitbricks.domain.Storage; @@ -40,8 +39,8 @@ public class StorageListResponseHandlerTest extends BaseResponseHandlerTest actual = parser.parse(payloadFromResource("/storage/storages.xml")); assertNotNull(actual, "Parsed content returned null"); - DateCodec dateParser = createDateParser().iso8601(); + DateService dateParser = createDateParser(); List expected = ImmutableList.of( Storage.builder() @@ -60,8 +59,8 @@ public class StorageListResponseHandlerTest extends BaseResponseHandlerTestof("qwertyui-qwer-qwer-qwer-qwertyyuiiop")) - .creationTime(dateParser.toDate("2014-12-04T07:09:23.138Z")) - .lastModificationTime(dateParser.toDate("2014-12-12T03:14:48.316Z")) + .creationTime(dateParser.iso8601DateOrSecondsDateParse("2014-12-04T07:09:23.138Z")) + .lastModificationTime(dateParser.iso8601DateOrSecondsDateParse("2014-12-12T03:14:48.316Z")) .build(), Storage.builder() .id("asfasfle-f23n-cu89-klfr-njkdsvwllkfa") @@ -69,8 +68,8 @@ public class StorageListResponseHandlerTest extends BaseResponseHandlerTestof("asdfghjk-asdf-asdf-asdf-asdfghjklkjl")) - .creationTime(dateParser.toDate("2014-11-04T07:09:23.138Z")) - .lastModificationTime(dateParser.toDate("2014-11-12T03:14:48.316Z")) + .creationTime(dateParser.iso8601DateOrSecondsDateParse("2014-11-04T07:09:23.138Z")) + .lastModificationTime(dateParser.iso8601DateOrSecondsDateParse("2014-11-12T03:14:48.316Z")) .build() ); diff --git a/providers/profitbricks/src/test/java/org/jclouds/profitbricks/util/PasswordsTest.java b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/util/PasswordsTest.java new file mode 100644 index 0000000000..fc7be1f40f --- /dev/null +++ b/providers/profitbricks/src/test/java/org/jclouds/profitbricks/util/PasswordsTest.java @@ -0,0 +1,53 @@ +/* + * 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.util; + +import com.google.common.collect.ImmutableList; +import java.util.List; +import static org.jclouds.profitbricks.util.Passwords.isValidPassword; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import org.testng.annotations.Test; + +@Test(groups = "unit", testName = "PasswordsTest") +public class PasswordsTest { + + private final List validPasswords = ImmutableList.of( + "fKVasTnNm", "84625894", "QQQQQQQQ", "qqqqqqqq", "asdfghjk" + ); + private final List invalidPasswords = ImmutableList.of( + "", "apachejclouds", "s0merand0mpassw0rd" + ); + + @Test + public void testPasswordValidation() { + for (String pwd : validPasswords) + assertTrue(isValidPassword(pwd), "Should've been valid: " + pwd); + + for (String pwd : invalidPasswords) + assertFalse(isValidPassword(pwd), "Should've been invalid: " + pwd); + } + + @Test + public void testGeneratorGeneratesValidPassword() { + final int times = 50; + for (int i = 0; i < times; i++) { + String pwd = Passwords.generate(); + assertTrue(isValidPassword(pwd), "Failed with: " + pwd); + } + } +} diff --git a/providers/profitbricks/src/test/resources/datacenter/datacenter-deleted.xml b/providers/profitbricks/src/test/resources/datacenter/datacenter-deleted.xml index c09858e62d..531ed530d9 100644 --- a/providers/profitbricks/src/test/resources/datacenter/datacenter-deleted.xml +++ b/providers/profitbricks/src/test/resources/datacenter/datacenter-deleted.xml @@ -1,10 +1,10 @@ - - - - 11411363 - - - + + + + 11411363 + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/datacenter/datacenter-not-found.xml b/providers/profitbricks/src/test/resources/datacenter/datacenter-not-found.xml index 486706dce3..e4a9701a9b 100644 --- a/providers/profitbricks/src/test/resources/datacenter/datacenter-not-found.xml +++ b/providers/profitbricks/src/test/resources/datacenter/datacenter-not-found.xml @@ -1,17 +1,17 @@ - - - S:Server - The requested resource could not be found. Please refer to Request Id : 11122416. [VDC-6-404] The requested data center does not exist or already deleted by the users. ResourceId random-non-existing-id - - - RESOURCE_NOT_FOUND - 404 - The requested resource could not be found. Please refer to Request Id : 11122416. [VDC-6-404] The requested data center does not exist or already deleted by the users. ResourceId random-non-existing-id - 11122416 - - - - + + + S:Server + The requested resource could not be found. Please refer to Request Id : 11122416. [VDC-6-404] The requested data center does not exist or already deleted by the users. ResourceId random-non-existing-id + + + RESOURCE_NOT_FOUND + 404 + The requested resource could not be found. Please refer to Request Id : 11122416. [VDC-6-404] The requested data center does not exist or already deleted by the users. ResourceId random-non-existing-id + 11122416 + + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/datacenter/datacenter-state-inprocess.xml b/providers/profitbricks/src/test/resources/datacenter/datacenter-state-inprocess.xml index 77d41e3b90..722c653ccf 100644 --- a/providers/profitbricks/src/test/resources/datacenter/datacenter-state-inprocess.xml +++ b/providers/profitbricks/src/test/resources/datacenter/datacenter-state-inprocess.xml @@ -1,8 +1,8 @@ - - - INPROCESS - - + + + INPROCESS + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/datacenter/datacenter-state.xml b/providers/profitbricks/src/test/resources/datacenter/datacenter-state.xml index 8bd56e2752..3327c82448 100644 --- a/providers/profitbricks/src/test/resources/datacenter/datacenter-state.xml +++ b/providers/profitbricks/src/test/resources/datacenter/datacenter-state.xml @@ -1,8 +1,8 @@ - - - AVAILABLE - - + + + AVAILABLE + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/drives/drives-add.xml b/providers/profitbricks/src/test/resources/drives/drives-add.xml index 752f8f33b1..52a04f5b86 100644 --- a/providers/profitbricks/src/test/resources/drives/drives-add.xml +++ b/providers/profitbricks/src/test/resources/drives/drives-add.xml @@ -1,12 +1,12 @@ - - - - request-id - datacenter-id - datacenter-version - - - + + + + request-id + datacenter-id + datacenter-version + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/drives/drives-remove.xml b/providers/profitbricks/src/test/resources/drives/drives-remove.xml index ccfd400e26..699b3595ae 100644 --- a/providers/profitbricks/src/test/resources/drives/drives-remove.xml +++ b/providers/profitbricks/src/test/resources/drives/drives-remove.xml @@ -1,12 +1,12 @@ - - - - request-id - datacenter-id - datacenter-version - - - + + + + request-id + datacenter-id + datacenter-version + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/firewall/firewall-activate.xml b/providers/profitbricks/src/test/resources/firewall/firewall-activate.xml index 2150c6b976..16e32b9302 100644 --- a/providers/profitbricks/src/test/resources/firewall/firewall-activate.xml +++ b/providers/profitbricks/src/test/resources/firewall/firewall-activate.xml @@ -1,12 +1,12 @@ - - - - request-id - datacenter-id - datacenter-version - - - + + + + request-id + datacenter-id + datacenter-version + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/firewall/firewall-addtonic.xml b/providers/profitbricks/src/test/resources/firewall/firewall-addtonic.xml index 12670408f5..740c042eec 100644 --- a/providers/profitbricks/src/test/resources/firewall/firewall-addtonic.xml +++ b/providers/profitbricks/src/test/resources/firewall/firewall-addtonic.xml @@ -1,23 +1,23 @@ - - - - active - firewall-id - - firewall-rule-id - name - 45678 - 12345 - TCP - 192.168.0.1 - aa:bb:cc:dd:ee:ff - 192.168.0.2 - - nic-id - AVAILABLE - - - + + + + active + firewall-id + + firewall-rule-id + name + 45678 + 12345 + TCP + 192.168.0.1 + aa:bb:cc:dd:ee:ff + 192.168.0.2 + + nic-id + AVAILABLE + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/firewall/firewall-deactivate.xml b/providers/profitbricks/src/test/resources/firewall/firewall-deactivate.xml index a0bca259b2..0adaabdad7 100644 --- a/providers/profitbricks/src/test/resources/firewall/firewall-deactivate.xml +++ b/providers/profitbricks/src/test/resources/firewall/firewall-deactivate.xml @@ -1,12 +1,12 @@ - - - - request-id1111 - datacenter-id - datacenter-version - - - + + + + request-id1111 + datacenter-id + datacenter-version + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/firewall/firewall-delete.xml b/providers/profitbricks/src/test/resources/firewall/firewall-delete.xml index 2c7364fe54..26371a9c59 100644 --- a/providers/profitbricks/src/test/resources/firewall/firewall-delete.xml +++ b/providers/profitbricks/src/test/resources/firewall/firewall-delete.xml @@ -1,12 +1,12 @@ - - - - request-id - datacenter-id - datacenter-version - - - + + + + request-id + datacenter-id + datacenter-version + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/firewall/firewall-remove.xml b/providers/profitbricks/src/test/resources/firewall/firewall-remove.xml index 793bdd0152..6301e6a62b 100644 --- a/providers/profitbricks/src/test/resources/firewall/firewall-remove.xml +++ b/providers/profitbricks/src/test/resources/firewall/firewall-remove.xml @@ -1,12 +1,12 @@ - - - - request-id - datacenter-id - datacenter-version - - - + + + + request-id + datacenter-id + datacenter-version + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/firewall/firewall.xml b/providers/profitbricks/src/test/resources/firewall/firewall.xml index 3275a70842..839502c99a 100644 --- a/providers/profitbricks/src/test/resources/firewall/firewall.xml +++ b/providers/profitbricks/src/test/resources/firewall/firewall.xml @@ -1,23 +1,23 @@ - - - - true - firewall-id - - firewall-rule-id - name - 45678 - 12345 - TCP - 192.168.0.1 - aa:bb:cc:dd:ee:ff - 192.168.0.2 - - nic-id - AVAILABLE - - - + + + + true + firewall-id + + firewall-rule-id + name + 45678 + 12345 + TCP + 192.168.0.1 + aa:bb:cc:dd:ee:ff + 192.168.0.2 + + nic-id + AVAILABLE + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/ipblock/ipblock-addtonic.xml b/providers/profitbricks/src/test/resources/ipblock/ipblock-addtonic.xml index a9c1974cd1..8496660003 100644 --- a/providers/profitbricks/src/test/resources/ipblock/ipblock-addtonic.xml +++ b/providers/profitbricks/src/test/resources/ipblock/ipblock-addtonic.xml @@ -1,12 +1,12 @@ - - - - request-id - datacenter-id - datacenter-version - - - + + + + request-id + datacenter-id + datacenter-version + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/ipblock/ipblock-release.xml b/providers/profitbricks/src/test/resources/ipblock/ipblock-release.xml index a9f22bf746..d10e6754cf 100644 --- a/providers/profitbricks/src/test/resources/ipblock/ipblock-release.xml +++ b/providers/profitbricks/src/test/resources/ipblock/ipblock-release.xml @@ -1,10 +1,10 @@ - - - - request-id - - - + + + + request-id + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/ipblock/ipblock-removefromnic.xml b/providers/profitbricks/src/test/resources/ipblock/ipblock-removefromnic.xml index a9c1974cd1..8496660003 100644 --- a/providers/profitbricks/src/test/resources/ipblock/ipblock-removefromnic.xml +++ b/providers/profitbricks/src/test/resources/ipblock/ipblock-removefromnic.xml @@ -1,12 +1,12 @@ - - - - request-id - datacenter-id - datacenter-version - - - + + + + request-id + datacenter-id + datacenter-version + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/ipblock/ipblock-reserve.xml b/providers/profitbricks/src/test/resources/ipblock/ipblock-reserve.xml index 863e9ff786..8586aaff43 100644 --- a/providers/profitbricks/src/test/resources/ipblock/ipblock-reserve.xml +++ b/providers/profitbricks/src/test/resources/ipblock/ipblock-reserve.xml @@ -1,13 +1,13 @@ - - - - request-id - block-id - us/las - ip - - - + + + + request-id + block-id + us/las + ip + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/ipblock/ipblock.xml b/providers/profitbricks/src/test/resources/ipblock/ipblock.xml index 2dd54f2907..339fdfb1c2 100644 --- a/providers/profitbricks/src/test/resources/ipblock/ipblock.xml +++ b/providers/profitbricks/src/test/resources/ipblock/ipblock.xml @@ -1,18 +1,18 @@ - - - - qwertyui-qwer-qwer-qwer-qwertyyuiiop - us/las - - ip - nic-id - - - ip - - - - + + + + qwertyui-qwer-qwer-qwer-qwertyyuiiop + us/las + + ip + nic-id + + + ip + + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-create.xml b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-create.xml index 14ad678b2b..33eb41b327 100644 --- a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-create.xml +++ b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-create.xml @@ -1,6 +1,6 @@ + xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' + xmlns:ws='http://ws.api.profitbricks.com/'> diff --git a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-delete.xml b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-delete.xml index b699be684f..8396174149 100644 --- a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-delete.xml +++ b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-delete.xml @@ -1,12 +1,12 @@ - - - - request-id - datacenter-id - datacenter-version - - - + + + + request-id + datacenter-id + datacenter-version + + + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-deregister.xml b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-deregister.xml index ee03c4749d..86ef94cbde 100644 --- a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-deregister.xml +++ b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-deregister.xml @@ -1,14 +1,14 @@ + xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' + xmlns:ws='http://ws.api.profitbricks.com/'> - + 1 2 load-balancer-id - + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-register.xml b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-register.xml index 48a1ff11dc..a32c65a0fd 100644 --- a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-register.xml +++ b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-register.xml @@ -1,13 +1,13 @@ + xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' + xmlns:ws='http://ws.api.profitbricks.com/'> - + 1234 load-balancer-id - + \ No newline at end of file diff --git a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-update.xml b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-update.xml index 7a39dea7a2..87c1f02b0b 100644 --- a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-update.xml +++ b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer-update.xml @@ -1,6 +1,6 @@ + xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' + xmlns:ws='http://ws.api.profitbricks.com/'> diff --git a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer.xml b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer.xml index 501e470433..302c10e69f 100644 --- a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer.xml +++ b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancer.xml @@ -4,7 +4,7 @@ datacenter-id - datacenter-version + 4 aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee load-balancer-name ROUND_ROBIN diff --git a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancers.xml b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancers.xml index 155a1e347d..54d194979b 100644 --- a/providers/profitbricks/src/test/resources/loadbalancer/loadbalancers.xml +++ b/providers/profitbricks/src/test/resources/loadbalancer/loadbalancers.xml @@ -4,7 +4,7 @@ datacenter-id - datacenter-version + 4 aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee load-1234567890-name ROUND_ROBIN @@ -29,7 +29,7 @@ datacenter-id - datacenter-version + 4 qqqqqqqq-wwww-rrrr-tttt-yyyyyyyyyyyy load-balancer-name ROUND_ROBIN diff --git a/providers/profitbricks/src/test/resources/server/server.xml b/providers/profitbricks/src/test/resources/server/server.xml index 33fa82431f..c78721f4c4 100644 --- a/providers/profitbricks/src/test/resources/server/server.xml +++ b/providers/profitbricks/src/test/resources/server/server.xml @@ -12,8 +12,8 @@ 4096 true 173.252.120.6 - qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh - true + qswdefrg-qaws-qaws-defe-rgrgdsvcxbrh + true true VIRTIO diff --git a/providers/profitbricks/src/test/resources/snapshot/snapshots.xml b/providers/profitbricks/src/test/resources/snapshot/snapshots.xml index d59826a544..1b3ab72145 100644 --- a/providers/profitbricks/src/test/resources/snapshot/snapshots.xml +++ b/providers/profitbricks/src/test/resources/snapshot/snapshots.xml @@ -3,25 +3,25 @@ - aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee - description - 1024 - snapshot01 - AVAILABLE - true - LINUX - true - true - true - true - true - true - true - true - 2015-01-26T07:09:23.138Z - 2015-01-26T07:09:23.138Z - us/las - + aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee + description + 1024 + snapshot01 + AVAILABLE + true + LINUX + true + true + true + true + true + true + true + true + 2015-01-26T07:09:23.138Z + 2015-01-26T07:09:23.138Z + us/las + qqqqqqqq-wwww-rrrr-tttt-yyyyyyyyyyyy description