You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2014/11/23 23:00:57 UTC

[16/50] [abbrv] jclouds git commit: JCLOUDS-274 Implement listCookbookVersionsInEnvironment in ChefService API

JCLOUDS-274 Implement listCookbookVersionsInEnvironment in ChefService API


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

Branch: refs/heads/1.8.x
Commit: 89a2b8ab36d677d9ad4e343049ff22de6a0bae51
Parents: d786daa
Author: Noorul Islam K M <no...@noorul.com>
Authored: Fri Oct 4 14:09:05 2013 +0530
Committer: Ignasi Barrera <na...@apache.org>
Committed: Tue Nov 5 12:10:58 2013 +0100

----------------------------------------------------------------------
 .../main/java/org/jclouds/chef/ChefService.java |  19 +++
 .../jclouds/chef/internal/BaseChefService.java  |  16 +-
 .../ListCookbookVersionsInEnvironment.java      |  41 +++++
 .../ListCookbookVersionsInEnvironmentImpl.java  | 113 ++++++++++++
 ...okbookVersionsInEnvironmentImplLiveTest.java | 171 +++++++++++++++++++
 5 files changed, 359 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/89a2b8ab/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/ChefService.java b/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
index f20df68..8006b88 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/ChefService.java
@@ -187,6 +187,25 @@ public interface ChefService {
    Iterable<? extends CookbookVersion> listCookbookVersions();
 
    /**
+    * Lists the details of all existing cookbooks in an environment.
+    *
+    * @param environmentName The environment name.
+    * @return The details of all existing cookbooks in an environment.
+    */
+   Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName);
+
+   /**
+    * Lists the details of all existing cookbooks in an environment
+    * limiting number of versions.
+    *
+    * @param environmentName The environment name.
+    * @param numVersions The number of cookbook versions to include.
+    *                    Use 'all' to return all cookbook versions.
+    * @return The details of all existing cookbooks in environment.
+    */
+   Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName, String numVersions);
+
+   /**
     * Lists the details of all existing environments.
     * 
     * @return The details of all existing environments.

http://git-wip-us.apache.org/repos/asf/jclouds/blob/89a2b8ab/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java b/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
index 4600ffc..a841922 100644
--- a/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
+++ b/apis/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java
@@ -49,6 +49,7 @@ import org.jclouds.chef.strategy.DeleteAllClientsInList;
 import org.jclouds.chef.strategy.DeleteAllNodesInList;
 import org.jclouds.chef.strategy.ListClients;
 import org.jclouds.chef.strategy.ListCookbookVersions;
+import org.jclouds.chef.strategy.ListCookbookVersionsInEnvironment;
 import org.jclouds.chef.strategy.ListNodesInEnvironment;
 import org.jclouds.chef.strategy.ListEnvironments;
 import org.jclouds.chef.strategy.ListNodes;
@@ -88,6 +89,7 @@ public class BaseChefService implements ChefService {
    private final BootstrapConfigForGroup bootstrapConfigForGroup;
    private final RunListForGroup runListForGroup;
    private final ListCookbookVersions listCookbookVersions;
+   private final ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment;
    private final ListEnvironments listEnvironments;
    private final ListNodesInEnvironment listNodesInEnvironment;
    private final Json json;
@@ -104,7 +106,8 @@ public class BaseChefService implements ChefService {
          UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Supplier<PrivateKey> privateKey,
          @Named(CHEF_BOOTSTRAP_DATABAG) String databag, GroupToBootScript groupToBootScript,
          BootstrapConfigForGroup bootstrapConfigForGroup, RunListForGroup runListForGroup,
-         ListEnvironments listEnvironments, ListNodesInEnvironment listNodesInEnvironment, Json json) {
+         ListEnvironments listEnvironments, ListNodesInEnvironment listNodesInEnvironment,
+         ListCookbookVersionsInEnvironment listCookbookVersionsInEnvironment, Json json) {
       this.chefContext = checkNotNull(chefContext, "chefContext");
       this.api = checkNotNull(api, "api");
       this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients");
@@ -124,6 +127,7 @@ public class BaseChefService implements ChefService {
       this.runListForGroup = checkNotNull(runListForGroup, "runListForGroup");
       this.listEnvironments = checkNotNull(listEnvironments, "listEnvironments");
       this.listNodesInEnvironment = checkNotNull(listNodesInEnvironment, "listNodesInEnvironment");
+      this.listCookbookVersionsInEnvironment = checkNotNull(listCookbookVersionsInEnvironment, "listCookbookVersionsInEnvironment");
       this.json = checkNotNull(json, "json");
    }
 
@@ -238,6 +242,16 @@ public class BaseChefService implements ChefService {
    }
 
    @Override
+   public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName) {
+      return listCookbookVersionsInEnvironment.execute(environmentName);
+   }
+
+   @Override
+   public Iterable<? extends CookbookVersion> listCookbookVersionsInEnvironment(String environmentName, String numVersions) {
+      return listCookbookVersionsInEnvironment.execute(environmentName, numVersions);
+   }
+
+   @Override
    public Iterable<? extends Environment> listEnvironments() {
       return listEnvironments.execute();
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/89a2b8ab/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersionsInEnvironment.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersionsInEnvironment.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersionsInEnvironment.java
new file mode 100644
index 0000000..e19918c
--- /dev/null
+++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/ListCookbookVersionsInEnvironment.java
@@ -0,0 +1,41 @@
+/*
+ * 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.chef.strategy;
+
+import org.jclouds.chef.domain.CookbookDefinition;
+import org.jclouds.chef.domain.CookbookVersion;
+import org.jclouds.chef.strategy.internal.ListCookbookVersionsInEnvironmentImpl;
+
+import com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.inject.ImplementedBy;
+
+/**
+ *
+ * @author Noorul Islam K M
+ */
+@ImplementedBy(ListCookbookVersionsInEnvironmentImpl.class)
+public interface ListCookbookVersionsInEnvironment {
+
+   Iterable<? extends CookbookVersion> execute(String environmentName);
+
+   Iterable<? extends CookbookVersion> execute(String environmentName, String numVersions);
+
+   Iterable<? extends CookbookVersion> execute(ListeningExecutorService executor, String environmentName);
+
+   Iterable<? extends CookbookVersion> execute(ListeningExecutorService executor, String environmentName, String numVersions);
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/89a2b8ab/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImpl.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImpl.java
new file mode 100644
index 0000000..48d563e
--- /dev/null
+++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImpl.java
@@ -0,0 +1,113 @@
+/*
+ * 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.chef.strategy.internal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.contains;
+import static com.google.common.collect.Iterables.filter;
+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 java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.chef.ChefApi;
+import org.jclouds.chef.config.ChefProperties;
+import org.jclouds.chef.domain.CookbookDefinition;
+import org.jclouds.chef.domain.CookbookVersion;
+import org.jclouds.chef.strategy.ListCookbookVersionsInEnvironment;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.inject.Inject;
+
+/**
+ *
+ * @author Noorul Islam K M
+ */
+@Singleton
+public class ListCookbookVersionsInEnvironmentImpl implements ListCookbookVersionsInEnvironment {
+
+   protected final ChefApi api;
+   protected final ListeningExecutorService userExecutor;
+   @Resource
+   @Named(ChefProperties.CHEF_LOGGER)
+   protected Logger logger = Logger.NULL;
+
+   @Inject
+   ListCookbookVersionsInEnvironmentImpl(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, ChefApi api) {
+      this.userExecutor = checkNotNull(userExecutor, "userExecuor");
+      this.api = checkNotNull(api, "api");
+   }
+
+   @Override
+   public Iterable<? extends CookbookVersion> execute(String environmentName) {
+      return execute(userExecutor, environmentName);
+   }
+
+   @Override
+   public Iterable<? extends CookbookVersion> execute(String environmentName, String numVersions) {
+      return execute(userExecutor, environmentName, numVersions);
+   }
+
+   public Iterable<? extends CookbookVersion> execute(ListeningExecutorService executor, String environmentName) {
+      return execute(executor, api.listCookbooksInEnvironment(environmentName));
+   }
+
+   @Override
+   public Iterable<? extends CookbookVersion> execute(ListeningExecutorService executor, String environmentName, String numVersions) {
+      return execute(executor, api.listCookbooksInEnvironment(environmentName, numVersions));
+   }
+
+   private Iterable<? extends CookbookVersion> execute(final ListeningExecutorService executor,
+         Iterable<CookbookDefinition> cookbookDefs) {
+      return concat(transform(cookbookDefs, new Function<CookbookDefinition, Iterable<? extends CookbookVersion>>() {
+
+         @Override
+         public Iterable<? extends CookbookVersion> apply(final CookbookDefinition cookbookDef) {
+            // TODO getting each version could also go parallel
+            Set<CookbookDefinition.Version> cookbookVersions = cookbookDef.getVersions();
+            ListenableFuture<List<CookbookVersion>> futures = allAsList(transform(cookbookVersions,
+                  new Function<CookbookDefinition.Version, ListenableFuture<CookbookVersion>>() {
+                     @Override
+                     public ListenableFuture<CookbookVersion> apply(final CookbookDefinition.Version version) {
+                        return executor.submit(new Callable<CookbookVersion>() {
+                           @Override
+                           public CookbookVersion call() throws Exception {
+                              return api.getCookbook(cookbookDef.getName(), version.getVersion());
+                           }
+                        });
+                     }
+                  }));
+
+            logger.trace(String.format("getting versions of cookbook %s: ", cookbookDef.getName()));
+            return getUnchecked(futures);
+         }
+      }));
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/89a2b8ab/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImplLiveTest.java
----------------------------------------------------------------------
diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImplLiveTest.java
new file mode 100644
index 0000000..1868256
--- /dev/null
+++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImplLiveTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.chef.strategy.internal;
+
+import static com.google.common.collect.Iterables.size;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import org.jclouds.chef.ChefApi;
+import org.jclouds.chef.domain.ChecksumStatus;
+import org.jclouds.chef.domain.CookbookDefinition;
+import org.jclouds.chef.domain.CookbookVersion;
+import org.jclouds.chef.domain.Metadata;
+import org.jclouds.chef.domain.Resource;
+import org.jclouds.chef.domain.Sandbox;
+import org.jclouds.chef.domain.UploadSandbox;
+import org.jclouds.chef.internal.BaseChefLiveTest;
+import org.jclouds.io.Payloads;
+import org.jclouds.io.payloads.FilePayload;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.Test;
+
+import java.io.File;
+import java.util.List;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.primitives.Bytes;
+
+/**
+ * Tests behavior of {@code ListCookbookVersionsInEnvironmentImpl} strategies
+ *
+ * @author Noorul Islam K M
+ */
+@Test(groups = "live", testName = "ListCookbookVersionsInEnvironmentImplLiveTest")
+public class ListCookbookVersionsInEnvironmentImplLiveTest extends BaseChefLiveTest<ChefApi> {
+   public static final String PREFIX = "jcloudstest-strategy-" + System.getProperty("user.name");
+
+   private ListCookbookVersionsInEnvironmentImpl strategy;
+   private CreateNodeAndPopulateAutomaticAttributesImpl creator;
+
+   @Override
+   protected void initialize() {
+      super.initialize();
+
+      try {
+         createCookbooksWithMultipleVersions(PREFIX);
+         createCookbooksWithMultipleVersions(PREFIX + 1);
+      } catch (Exception e) {
+         fail("Could not create cookbooks", e);
+      }
+
+      this.strategy = injector.getInstance(ListCookbookVersionsInEnvironmentImpl.class);
+   }
+
+   @AfterClass(groups = { "integration", "live" })
+   @Override
+   protected void tearDown() {
+      api.deleteCookbook(PREFIX, "0.0.0");
+      api.deleteCookbook(PREFIX, "1.0.0");
+      api.deleteCookbook(PREFIX + 1, "0.0.0");
+      api.deleteCookbook(PREFIX + 1, "1.0.0");
+      super.tearDown();
+   }
+
+   @Test
+   public void testExecute() {
+      assertTrue(size(strategy.execute("_default")) > 0, "Expected one or more elements");
+   }
+
+   @Test
+   public void testExecuteWithNumVersions() {
+      assertTrue(size(strategy.execute("_default", "2")) > 0, "Expected one or more elements");
+   }
+
+   @Test
+   public void testExecuteWithNumVersionsAll() {
+      assertTrue(size(strategy.execute("_default", "all")) > 0, "Expected one or more elements");
+   }
+
+   private FilePayload uploadContent(String fileName) throws Exception {
+      // Define the file you want in the cookbook
+      FilePayload content = Payloads.newFilePayload(new File(System.getProperty("user.dir"), fileName));
+      content.getContentMetadata().setContentType("application/x-binary");
+
+      // Get an md5 so that you can see if the server already has it or not
+      Payloads.calculateMD5(content);
+
+      // Note that java collections cannot effectively do equals or hashcodes on
+      // byte arrays, so let's convert to a list of bytes.
+      List<Byte> md5 = Bytes.asList(content.getContentMetadata().getContentMD5());
+
+      // Request an upload site for this file
+      UploadSandbox site = api.createUploadSandboxForChecksums(ImmutableSet.of(md5));
+      assertTrue(site.getChecksums().containsKey(md5), md5 + " not in " + site.getChecksums());
+
+      try {
+         // Upload the file contents, if still not uploaded
+         ChecksumStatus status = site.getChecksums().get(md5);
+         if (status.needsUpload()) {
+            api.uploadContent(status.getUrl(), content);
+         }
+         Sandbox sandbox = api.commitSandbox(site.getSandboxId(), true);
+         assertTrue(sandbox.isCompleted(), "Sandbox should be completed after uploading");
+      } catch (RuntimeException e) {
+         api.commitSandbox(site.getSandboxId(), false);
+         fail("Could not upload content", e);
+      }
+
+      return content;
+   }
+
+   private void createCookbooksWithMultipleVersions(String cookbookName) throws Exception {
+      FilePayload v0content = uploadContent("pom.xml");
+      FilePayload v1content = uploadContent("../README.md");
+
+      // Create the metadata of the cookbook
+      Metadata metadata = Metadata.builder() //
+            .name(cookbookName) //
+            .version("0.0.0") //
+            .description("Jclouds test uploaded cookbook") //
+            .maintainer("jclouds") //
+            .maintainerEmail("someone@jclouds.org") //
+            .license("Apache 2.0") //
+            .build();
+
+      // Create new cookbook version
+      CookbookVersion cookbook = CookbookVersion.builder(cookbookName, "0.0.0") //
+            .metadata(metadata) //
+            .rootFile(Resource.builder().fromPayload(v0content).build()) //
+            .build();
+
+      // upload the cookbook to the remote server
+      api.updateCookbook(cookbookName, "0.0.0", cookbook);
+
+      // Create the metadata of the cookbook
+      metadata = Metadata.builder() //
+            .name(cookbookName) //
+            .version("1.0.0") //
+            .description("Jclouds test uploaded cookbook") //
+            .maintainer("jclouds") //
+            .maintainerEmail("someone@jclouds.org") //
+            .license("Apache 2.0") //
+            .build();
+
+      // Create a new cookbook version
+      cookbook = CookbookVersion.builder(cookbookName, "1.0.0") //
+            .metadata(metadata) //
+            .rootFile(Resource.builder().fromPayload(v1content).build()) //
+            .build();
+
+      // upload the cookbook to the remote server
+      api.updateCookbook(cookbookName, "1.0.0", cookbook);
+   }
+}