Repository: jclouds-labs
Updated Branches:
  refs/heads/2.0.x b151914f0 -> c1d36ce79


JCLOUDS-1210: Implement the ImageExtension in ProfitBricks REST


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/c1d36ce7
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/c1d36ce7
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/c1d36ce7

Branch: refs/heads/2.0.x
Commit: c1d36ce7910f8de278e4375889be7dadd0278d96
Parents: b151914
Author: Ali Bazlamit <[email protected]>
Authored: Tue Mar 7 19:48:12 2017 +0100
Committer: Ignasi Barrera <[email protected]>
Committed: Tue Mar 7 21:26:51 2017 +0100

----------------------------------------------------------------------
 .../ProfitBricksComputeServiceAdapter.java      |   2 +-
 ...ProfitBricksComputeServiceContextModule.java |   9 +-
 .../extensions/ProfitBricksImageExtension.java  | 141 +++++++++++++++++++
 .../ProfitBricksTemplateBuilderLiveTest.java    |   2 -
 .../ProfitBricksImageExtensionLiveTest.java     |  46 ++++++
 .../rest/features/IpblockApiLiveTest.java       |   3 +-
 6 files changed, 196 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/c1d36ce7/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git 
a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksComputeServiceAdapter.java
 
b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksComputeServiceAdapter.java
index 0f15123..4c79640 100644
--- 
a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksComputeServiceAdapter.java
+++ 
b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksComputeServiceAdapter.java
@@ -438,7 +438,7 @@ public class ProfitBricksComputeServiceAdapter implements 
ComputeServiceAdapter<
          logger.trace(">> found snapshot [%s]", snapshot.properties().name());
          return snapshot;
       }
-      throw new ResourceNotFoundException("No image/snapshot with id '" + id + 
"' was found");
+      return null;
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/c1d36ce7/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/config/ProfitBricksComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git 
a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/config/ProfitBricksComputeServiceContextModule.java
 
b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/config/ProfitBricksComputeServiceContextModule.java
index b244fb2..a144418 100644
--- 
a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/config/ProfitBricksComputeServiceContextModule.java
+++ 
b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/config/ProfitBricksComputeServiceContextModule.java
@@ -32,6 +32,7 @@ import org.apache.jclouds.profitbricks.rest.ProfitBricksApi;
 import 
org.apache.jclouds.profitbricks.rest.compute.ProfitBricksComputeServiceAdapter;
 import org.apache.jclouds.profitbricks.rest.compute.concurrent.ProvisioningJob;
 import 
org.apache.jclouds.profitbricks.rest.compute.concurrent.ProvisioningManager;
+import 
org.apache.jclouds.profitbricks.rest.compute.extensions.ProfitBricksImageExtension;
 import 
org.apache.jclouds.profitbricks.rest.compute.function.ProvisionableToImage;
 import 
org.apache.jclouds.profitbricks.rest.compute.function.ServerInDataCenterToNodeMetadata;
 import org.apache.jclouds.profitbricks.rest.compute.function.VolumeToVolume;
@@ -62,6 +63,7 @@ import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.Volume;
 import org.jclouds.compute.domain.internal.ArbitraryCpuRamTemplateBuilderImpl;
 import org.jclouds.compute.domain.internal.TemplateBuilderImpl;
+import org.jclouds.compute.extensions.ImageExtension;
 import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
 import org.jclouds.domain.Location;
 import org.jclouds.functions.IdentityFunction;
@@ -86,9 +88,9 @@ public class ProfitBricksComputeServiceContextModule extends
 
       bind(new TypeLiteral<ComputeServiceAdapter<ServerInDataCenter, Hardware, 
Provisionable, Location>>() {
       }).to(ProfitBricksComputeServiceAdapter.class);
-      
+
       
bind(TemplateBuilderImpl.class).to(ArbitraryCpuRamTemplateBuilderImpl.class);
-      
+
       bind(new TypeLiteral<Function<ServerInDataCenter, NodeMetadata>>() {
       }).to(ServerInDataCenterToNodeMetadata.class);
 
@@ -100,6 +102,9 @@ public class ProfitBricksComputeServiceContextModule extends
 
       bind(new TypeLiteral<Function<Hardware, Hardware>>() {
       }).to(Class.class.cast(IdentityFunction.class));
+
+      bind(new TypeLiteral<ImageExtension>() {
+      }).to(ProfitBricksImageExtension.class);
    }
 
    @Provides

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/c1d36ce7/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/extensions/ProfitBricksImageExtension.java
----------------------------------------------------------------------
diff --git 
a/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/extensions/ProfitBricksImageExtension.java
 
b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/extensions/ProfitBricksImageExtension.java
new file mode 100644
index 0000000..2f55b4a
--- /dev/null
+++ 
b/profitbricks-rest/src/main/java/org/apache/jclouds/profitbricks/rest/compute/extensions/ProfitBricksImageExtension.java
@@ -0,0 +1,141 @@
+/*
+ * 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.apache.jclouds.profitbricks.rest.compute.extensions;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+import static com.google.common.collect.Iterables.find;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+import java.net.URI;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import org.apache.jclouds.profitbricks.rest.ProfitBricksApi;
+import static 
org.apache.jclouds.profitbricks.rest.config.ProfitBricksComputeProperties.POLL_PREDICATE_SNAPSHOT;
+import org.apache.jclouds.profitbricks.rest.domain.Server;
+import org.apache.jclouds.profitbricks.rest.domain.Snapshot;
+import org.apache.jclouds.profitbricks.rest.domain.Volume;
+import org.apache.jclouds.profitbricks.rest.domain.zonescoped.DataCenterAndId;
+import org.apache.jclouds.profitbricks.rest.util.Trackables;
+import org.jclouds.Constants;
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.CloneImageTemplate;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.ImageTemplate;
+import org.jclouds.compute.domain.ImageTemplateBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.domain.Location;
+import static org.jclouds.location.predicates.LocationPredicates.idEquals;
+import org.jclouds.logging.Logger;
+
+public class ProfitBricksImageExtension implements ImageExtension {
+
+   @Resource
+   @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+   protected Logger logger = Logger.NULL;
+
+   private final ProfitBricksApi client;
+   private final ListeningExecutorService userExecutor;
+   private final Supplier<Set<? extends Location>> locations;
+   private final Predicate<String> snapshotAvailablePredicate;
+   private final Trackables trackables;
+
+   @Inject
+   ProfitBricksImageExtension(ProfitBricksApi client,
+           @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService 
userExecutor,
+           @Memoized Supplier<Set<? extends Location>> locations,
+           @Named(POLL_PREDICATE_SNAPSHOT) Predicate<String> 
snapshotAvailablePredicate,
+           Trackables trackables) {
+      this.client = client;
+      this.userExecutor = userExecutor;
+      this.locations = locations;
+      this.snapshotAvailablePredicate = snapshotAvailablePredicate;
+      this.trackables = trackables;
+   }
+
+   @Override
+   public ImageTemplate buildImageTemplateFromNode(String name, String id) {
+      DataCenterAndId datacenterAndId = DataCenterAndId.fromSlashEncoded(id);
+      Server server = 
client.serverApi().getServer(datacenterAndId.getDataCenter(), 
datacenterAndId.getId());
+      if (server == null) {
+         throw new IllegalArgumentException("Cannot find server with id: " + 
id);
+      }
+      CloneImageTemplate template = new 
ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name).build();
+      return template;
+   }
+
+   @Override
+   public ListenableFuture<Image> createImage(ImageTemplate template) {
+      final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
+      final DataCenterAndId datacenterAndId = 
DataCenterAndId.fromSlashEncoded(cloneTemplate.getSourceNodeId());
+
+      final Server server = 
client.serverApi().getServer(datacenterAndId.getDataCenter(), 
datacenterAndId.getId());
+      List<Volume> volumes = client.volumeApi().getList(server.dataCenterId());
+
+      final Volume volume = Iterables.getOnlyElement(volumes);
+
+      return userExecutor.submit(new Callable<Image>() {
+         @Override
+         public Image call() throws Exception {
+            Snapshot snapshot = 
client.volumeApi().createSnapshot(Volume.Request.createSnapshotBuilder()
+                    .dataCenterId(datacenterAndId.getDataCenter())
+                    .volumeId(volume.id())
+                    .name(cloneTemplate.getName())
+                    .description(cloneTemplate.getName())
+                    .build());
+
+            trackables.waitUntilRequestCompleted(snapshot);
+            logger.info(">> Registered new snapshot %s, waiting for it to 
become available.", snapshot.id());
+
+            final Image image = new ImageBuilder()
+                    .location(find(locations.get(), 
idEquals(snapshot.properties().location().getId())))
+                    .id(snapshot.id())
+                    .providerId(snapshot.id())
+                    .name(cloneTemplate.getName())
+                    .description(cloneTemplate.getName())
+                    
.operatingSystem(OperatingSystem.builder().description(cloneTemplate.getName()).build())
+                    .status(Image.Status.PENDING).build();
+
+            if (snapshotAvailablePredicate.apply(image.getId())) {
+               return image;
+            }
+            throw new UncheckedTimeoutException("Image was not created within 
the time limit: " + image);
+         }
+      });
+   }
+
+   @Override
+   public boolean deleteImage(String id) {
+      try {
+         URI deleteJob = client.snapshotApi().delete(id);
+         trackables.waitUntilRequestCompleted(deleteJob);
+         return true;
+      } catch (Exception e) {
+         return false;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/c1d36ce7/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksTemplateBuilderLiveTest.java
----------------------------------------------------------------------
diff --git 
a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksTemplateBuilderLiveTest.java
 
b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksTemplateBuilderLiveTest.java
index f029c41..a9c8d9d 100644
--- 
a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksTemplateBuilderLiveTest.java
+++ 
b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/compute/ProfitBricksTemplateBuilderLiveTest.java
@@ -18,9 +18,7 @@ package org.apache.jclouds.profitbricks.rest.compute;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Module;
-
 import java.util.Set;
-
 import org.apache.jclouds.profitbricks.rest.config.ProfitBricksRateLimitModule;
 import org.jclouds.compute.internal.BaseTemplateBuilderLiveTest;
 import org.testng.annotations.Test;

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/c1d36ce7/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/compute/extensions/ProfitBricksImageExtensionLiveTest.java
----------------------------------------------------------------------
diff --git 
a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/compute/extensions/ProfitBricksImageExtensionLiveTest.java
 
b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/compute/extensions/ProfitBricksImageExtensionLiveTest.java
new file mode 100644
index 0000000..a492216
--- /dev/null
+++ 
b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/compute/extensions/ProfitBricksImageExtensionLiveTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.apache.jclouds.profitbricks.rest.compute.extensions;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+import org.apache.jclouds.profitbricks.rest.config.ProfitBricksRateLimitModule;
+import org.jclouds.compute.extensions.internal.BaseImageExtensionLiveTest;
+import org.jclouds.sshj.config.SshjSshClientModule;
+import org.testng.annotations.Test;
+
+@Test(groups = "live", singleThreaded = true, testName = 
"ProfitBricksImageExtensionLiveTest")
+public class ProfitBricksImageExtensionLiveTest extends 
BaseImageExtensionLiveTest {
+
+   public ProfitBricksImageExtensionLiveTest() {
+      provider = "profitbricks-rest";
+   }
+
+   @Override
+   protected Iterable<Module> setupModules() {
+      ImmutableSet.Builder<Module> modules = ImmutableSet.builder();
+      modules.addAll(super.setupModules());
+      modules.add(new ProfitBricksRateLimitModule());
+      return modules.build();
+   }
+
+   @Override
+   protected Module getSshModule() {
+      return new SshjSshClientModule();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/c1d36ce7/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/IpblockApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/IpblockApiLiveTest.java
 
b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/IpblockApiLiveTest.java
index 5965f8c..6ecdfd3 100644
--- 
a/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/IpblockApiLiveTest.java
+++ 
b/profitbricks-rest/src/test/java/org/apache/jclouds/profitbricks/rest/features/IpblockApiLiveTest.java
@@ -17,7 +17,6 @@
 package org.apache.jclouds.profitbricks.rest.features;
 
 import com.google.common.base.Predicate;
-
 import java.net.URI;
 import java.util.List;
 import org.apache.jclouds.profitbricks.rest.domain.IpBlock;
@@ -59,7 +58,7 @@ public class IpblockApiLiveTest extends 
BaseProfitBricksLiveTest {
    }
 
    @Test
-   public void testGetNic() {
+   public void testGet() {
       IpBlock ipBlock = ipBlockApi().get(testIpBlock.id());
 
       assertNotNull(ipBlock);

Reply via email to