mirror of https://github.com/apache/jclouds.git
Issue 191: updated to fix an attribute bug and added RunListBuilder
This commit is contained in:
parent
0b11e7d652
commit
df6d350820
|
@ -20,6 +20,12 @@
|
|||
package org.jclouds.chef.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.any;
|
||||
import static com.google.common.collect.Iterables.concat;
|
||||
import static com.google.common.collect.Iterables.getLast;
|
||||
import static org.jclouds.chef.predicates.CookbookVersionPredicates.containsRecipe;
|
||||
import static org.jclouds.chef.predicates.CookbookVersionPredicates.containsRecipes;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.runScript;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -27,16 +33,17 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.chef.ChefContext;
|
||||
import org.jclouds.chef.ChefContextFactory;
|
||||
import org.jclouds.chef.domain.CookbookVersion;
|
||||
import org.jclouds.chef.util.RunListBuilder;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
|
@ -48,7 +55,6 @@ import org.testng.annotations.Test;
|
|||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.inject.Module;
|
||||
|
||||
|
@ -101,24 +107,38 @@ public class ChefComputeServiceLiveTest {
|
|||
|
||||
@Test
|
||||
public void testCanUpdateRunList() throws IOException {
|
||||
chefContext.getChefService().updateRunListForTag(Collections.singleton("recipe[apache2]"), tag);
|
||||
assertEquals(chefContext.getChefService().getRunListForTag(tag), Collections.singleton("recipe[apache2]"));
|
||||
String recipe = "apache2";
|
||||
|
||||
Iterable<? extends CookbookVersion> cookbookVersions = chefContext.getChefService().listCookbookVersions();
|
||||
|
||||
if (any(cookbookVersions, containsRecipe(recipe))) {
|
||||
List<String> runList = new RunListBuilder().addRecipe(recipe).build();
|
||||
chefContext.getChefService().updateRunListForTag(runList, tag);
|
||||
assertEquals(chefContext.getChefService().getRunListForTag(tag), runList);
|
||||
} else {
|
||||
assert false : String.format("recipe %s not in %s", recipe, cookbookVersions);
|
||||
}
|
||||
|
||||
// TODO move this to a unit test
|
||||
assert any(cookbookVersions, containsRecipe("apache2::mod_proxy"));
|
||||
assert any(cookbookVersions, containsRecipes("apache2", "apache2::mod_proxy", "apache2::mod_proxy_http"));
|
||||
assert !any(cookbookVersions, containsRecipe("apache2::bar"));
|
||||
assert !any(cookbookVersions, containsRecipe("foo::bar"));
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCanUpdateRunList")
|
||||
public void testRunNodesWithBootstrap() throws IOException {
|
||||
|
||||
Payload bootstrap = chefContext.getChefService().createClientAndBootstrapScriptForTag(tag);
|
||||
TemplateOptions options = computeContext.getComputeService().templateOptions().runScript(bootstrap);
|
||||
|
||||
try {
|
||||
nodes = computeContext.getComputeService().runNodesWithTag(tag, 1, options);
|
||||
nodes = computeContext.getComputeService().runNodesWithTag(tag, 1, runScript(bootstrap));
|
||||
} catch (RunNodesException e) {
|
||||
nodes = Iterables.concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet());
|
||||
nodes = concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet());
|
||||
}
|
||||
|
||||
for (NodeMetadata node : nodes) {
|
||||
URI uri = URI.create("http://" + Iterables.getLast(node.getPublicAddresses()));
|
||||
URI uri = URI.create("http://" + getLast(node.getPublicAddresses()));
|
||||
InputStream content = computeContext.utils().http().get(uri);
|
||||
String string = Utils.toStringAndClose(content);
|
||||
assert string.indexOf("It works!") >= 0 : string;
|
||||
|
|
|
@ -129,7 +129,37 @@ unit testing"
|
|||
"Retrieve the existing nodes in your chef server including all details."
|
||||
([] (nodes *chef*))
|
||||
([#^ChefService chef]
|
||||
(seq (.listNodesDetails chef))))
|
||||
(seq (.listNodes chef))))
|
||||
|
||||
(defn clients
|
||||
"Retrieve the names of the existing clients in your chef server."
|
||||
([] (clients *chef*))
|
||||
([#^ChefService chef]
|
||||
(seq (.listClients (as-chef-api chef)))))
|
||||
|
||||
(defn clients-with-details
|
||||
"Retrieve the existing clients in your chef server including all details."
|
||||
([] (clients *chef*))
|
||||
([#^ChefService chef]
|
||||
(seq (.listClients chef))))
|
||||
|
||||
(defn cookbooks
|
||||
"Retrieve the names of the existing cookbooks in your chef server."
|
||||
([] (cookbooks *chef*))
|
||||
([#^ChefService chef]
|
||||
(seq (.listCookbooks (as-chef-api chef)))))
|
||||
|
||||
(defn cookbook-versions
|
||||
"Retrieve the versions of an existing cookbook in your chef server."
|
||||
([name] (cookbook-versions *chef*))
|
||||
([#^ChefService name chef]
|
||||
(seq (.getVersionsOfCookbook (as-chef-api chef) name))))
|
||||
|
||||
(defn cookbook-versions-with-details
|
||||
"Retrieve the existing cookbook versions in your chef server including all details."
|
||||
([] (cookbook-versions *chef*))
|
||||
([#^ChefService chef]
|
||||
(seq (.listCookbookVersions chef))))
|
||||
|
||||
(defn update-run-list
|
||||
"Updates the run-list associated with a tag"
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.io.InputStream;
|
|||
import java.util.List;
|
||||
|
||||
import org.jclouds.chef.domain.Client;
|
||||
import org.jclouds.chef.domain.CookbookVersion;
|
||||
import org.jclouds.chef.domain.Node;
|
||||
import org.jclouds.chef.internal.BaseChefService;
|
||||
import org.jclouds.io.Payload;
|
||||
|
@ -97,9 +98,9 @@ public interface ChefService {
|
|||
|
||||
void deleteAllNodesInList(Iterable<String> names);
|
||||
|
||||
Iterable<? extends Node> listNodesDetails();
|
||||
Iterable<? extends Node> listNodes();
|
||||
|
||||
Iterable<? extends Node> listNodesDetailsMatching(Predicate<String> nodeNameSelector);
|
||||
Iterable<? extends Node> listNodesMatching(Predicate<String> nodeNameSelector);
|
||||
|
||||
Iterable<? extends Node> listNodesNamed(Iterable<String> names);
|
||||
|
||||
|
@ -111,5 +112,11 @@ public interface ChefService {
|
|||
|
||||
Iterable<? extends Client> listClientsNamed(Iterable<String> names);
|
||||
|
||||
Iterable<? extends CookbookVersion> listCookbookVersions();
|
||||
|
||||
Iterable<? extends CookbookVersion> listCookbookVersionsMatching(Predicate<String> cookbookNameSelector);
|
||||
|
||||
Iterable<? extends CookbookVersion> listCookbookVersionsNamed(Iterable<String> cookbookNames);
|
||||
|
||||
void updateAutomaticAttributesOnNode(String nodeName);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ package org.jclouds.chef.domain;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.domain.JsonBall;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
@ -37,14 +39,14 @@ public class Attribute {
|
|||
private boolean calculated;
|
||||
private List<String> choice = Lists.newArrayList();
|
||||
@SerializedName("default")
|
||||
private String defaultValue;
|
||||
private JsonBall defaultValue;
|
||||
private String type;
|
||||
private List<String> recipes = Lists.newArrayList();
|
||||
@SerializedName("display_name")
|
||||
private String displayName;
|
||||
private String description;
|
||||
|
||||
public Attribute(String required, boolean calculated, Set<String> choice, String defaultValue, String type,
|
||||
public Attribute(String required, boolean calculated, Set<String> choice, JsonBall defaultValue, String type,
|
||||
List<String> recipes, String displayName, String description) {
|
||||
this.required = required;
|
||||
this.calculated = calculated;
|
||||
|
@ -71,7 +73,7 @@ public class Attribute {
|
|||
return choice;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
public JsonBall getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ public class CookbookVersion {
|
|||
|
||||
private String name;
|
||||
private Set<Resource> definitions = Sets.newLinkedHashSet();
|
||||
private Set<Resource> attributes = Sets.newLinkedHashSet();
|
||||
private Set<Attribute> attributes = Sets.newLinkedHashSet();
|
||||
private Set<Resource> files = Sets.newLinkedHashSet();
|
||||
private Metadata metadata = new Metadata();
|
||||
private Set<Resource> providers = Sets.newLinkedHashSet();
|
||||
|
@ -62,10 +62,10 @@ public class CookbookVersion {
|
|||
this.name = cookbookName + "-" + version;
|
||||
}
|
||||
|
||||
public CookbookVersion(String name, Set<Resource> definitions, Set<Resource> attributes, Set<Resource> files,
|
||||
Metadata metadata, Set<Resource> providers, String cookbookName, Set<Resource> resources,
|
||||
Set<Resource> templates, Set<Resource> libraries, String version, Set<Resource> recipes,
|
||||
Set<Resource> rootFiles) {
|
||||
public CookbookVersion(String name, Set<Resource> definitions, Set<Attribute> attributes, Set<Resource> files,
|
||||
Metadata metadata, Set<Resource> providers, String cookbookName, Set<Resource> resources,
|
||||
Set<Resource> templates, Set<Resource> libraries, String version, Set<Resource> recipes,
|
||||
Set<Resource> rootFiles) {
|
||||
this.name = name;
|
||||
Iterables.addAll(this.definitions, definitions);
|
||||
Iterables.addAll(this.attributes, attributes);
|
||||
|
@ -94,7 +94,7 @@ public class CookbookVersion {
|
|||
return definitions;
|
||||
}
|
||||
|
||||
public Set<Resource> getAttributes() {
|
||||
public Set<Attribute> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
|
@ -238,9 +238,9 @@ public class CookbookVersion {
|
|||
@Override
|
||||
public String toString() {
|
||||
return "Cookbook [attributes=" + attributes + ", cookbookName=" + cookbookName + ", definitions=" + definitions
|
||||
+ ", files=" + files + ", libraries=" + libraries + ", metadata=" + metadata + ", name=" + name
|
||||
+ ", providers=" + providers + ", recipes=" + recipes + ", resources=" + resources + ", rootFiles="
|
||||
+ rootFiles + ", templates=" + templates + ", version=" + version + "]";
|
||||
+ ", files=" + files + ", libraries=" + libraries + ", metadata=" + metadata + ", name=" + name
|
||||
+ ", providers=" + providers + ", recipes=" + recipes + ", resources=" + resources + ", rootFiles="
|
||||
+ rootFiles + ", templates=" + templates + ", version=" + version + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.chef.ChefContext;
|
||||
import org.jclouds.chef.ChefService;
|
||||
import org.jclouds.chef.domain.Client;
|
||||
import org.jclouds.chef.domain.CookbookVersion;
|
||||
import org.jclouds.chef.domain.DatabagItem;
|
||||
import org.jclouds.chef.domain.Node;
|
||||
import org.jclouds.chef.functions.RunListForTag;
|
||||
|
@ -46,6 +47,7 @@ import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes;
|
|||
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.ListNodes;
|
||||
import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode;
|
||||
import org.jclouds.io.Payload;
|
||||
|
@ -83,14 +85,16 @@ public class BaseChefService implements ChefService {
|
|||
private final TagToBootScript tagToBootScript;
|
||||
private final String databag;
|
||||
private final RunListForTag runListForTag;
|
||||
private final ListCookbookVersions listCookbookVersions;
|
||||
|
||||
@Inject
|
||||
protected BaseChefService(ChefContext chefContext, CleanupStaleNodesAndClients cleanupStaleNodesAndClients,
|
||||
CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes,
|
||||
DeleteAllNodesInList deleteAllNodesInList, ListNodes listNodes,
|
||||
DeleteAllClientsInList deleteAllClientsInList, ListClients listClients,
|
||||
UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Provider<PrivateKey> privateKey,
|
||||
@Named(CHEF_BOOTSTRAP_DATABAG) String databag, TagToBootScript tagToBootScript, RunListForTag runListForTag) {
|
||||
ListCookbookVersions listCookbookVersions, UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode,
|
||||
Provider<PrivateKey> privateKey, @Named(CHEF_BOOTSTRAP_DATABAG) String databag,
|
||||
TagToBootScript tagToBootScript, RunListForTag runListForTag) {
|
||||
this.chefContext = checkNotNull(chefContext, "chefContext");
|
||||
this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients");
|
||||
this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes,
|
||||
|
@ -99,6 +103,7 @@ public class BaseChefService implements ChefService {
|
|||
this.listNodes = checkNotNull(listNodes, "listNodes");
|
||||
this.deleteAllClientsInList = checkNotNull(deleteAllClientsInList, "deleteAllClientsInList");
|
||||
this.listClients = checkNotNull(listClients, "listClients");
|
||||
this.listCookbookVersions = checkNotNull(listCookbookVersions, "listCookbookVersions");
|
||||
this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode,
|
||||
"updateAutomaticAttributesOnNode");
|
||||
this.privateKey = checkNotNull(privateKey, "privateKey");
|
||||
|
@ -123,12 +128,12 @@ public class BaseChefService implements ChefService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends Node> listNodesDetails() {
|
||||
public Iterable<? extends Node> listNodes() {
|
||||
return listNodes.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends Node> listNodesDetailsMatching(Predicate<String> nodeNameSelector) {
|
||||
public Iterable<? extends Node> listNodesMatching(Predicate<String> nodeNameSelector) {
|
||||
return listNodes.execute(nodeNameSelector);
|
||||
}
|
||||
|
||||
|
@ -157,6 +162,22 @@ public class BaseChefService implements ChefService {
|
|||
return listClients.execute(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends CookbookVersion> listCookbookVersions() {
|
||||
return listCookbookVersions.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends CookbookVersion> listCookbookVersionsMatching(Predicate<String> cookbookNameSelector) {
|
||||
return listCookbookVersions.execute(cookbookNameSelector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends CookbookVersion> listCookbookVersionsNamed(Iterable<String> names) {
|
||||
return listCookbookVersions.execute(names);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateAutomaticAttributesOnNode(String nodeName) {
|
||||
updateAutomaticAttributesOnNode.execute(nodeName);
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.any;
|
||||
import static com.google.common.collect.Iterables.get;
|
||||
|
||||
import org.jclouds.chef.domain.CookbookVersion;
|
||||
import org.jclouds.chef.domain.Resource;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.LinkedListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
* Container for cookbook filters (predicates).
|
||||
*
|
||||
* This class has static methods that create customized predicates to use with
|
||||
* {@link org.jclouds.chef.ChefService}.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class CookbookVersionPredicates {
|
||||
/**
|
||||
* @see #containsRecipes
|
||||
*/
|
||||
public static Predicate<CookbookVersion> containsRecipe(String recipe) {
|
||||
return containsRecipes(checkNotNull(recipe, "recipe must be defined"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that the default recipe of a cookbook is its name. Otherwise, you prefix the recipe with
|
||||
* the name of the cookbook. ex. {@code apache2} will be the default recipe where {@code
|
||||
* apache2::mod_proxy} is a specific one in the cookbook.
|
||||
*
|
||||
* @param recipes
|
||||
* names of the recipes.
|
||||
* @return true if the cookbook version contains a recipe in the list.
|
||||
*/
|
||||
public static Predicate<CookbookVersion> containsRecipes(String... recipes) {
|
||||
checkNotNull(recipes, "recipes must be defined");
|
||||
final Multimap<String, String> search = LinkedListMultimap.create();
|
||||
for (String recipe : recipes) {
|
||||
if (recipe.indexOf("::") != -1) {
|
||||
Iterable<String> nameRecipe = Splitter.on("::").split(recipe);
|
||||
search.put(get(nameRecipe, 0), get(nameRecipe, 1) + ".rb");
|
||||
} else {
|
||||
search.put(recipe, "default.rb");
|
||||
}
|
||||
}
|
||||
return new Predicate<CookbookVersion>() {
|
||||
@Override
|
||||
public boolean apply(final CookbookVersion cookbookVersion) {
|
||||
return search.containsKey(cookbookVersion.getCookbookName())
|
||||
&& any(search.get(cookbookVersion.getCookbookName()), new Predicate<String>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(final String recipeName) {
|
||||
return any(cookbookVersion.getRecipes(), new Predicate<Resource>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Resource resource) {
|
||||
return resource.getName().equals(recipeName);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "containsRecipes(" + search + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.CookbookVersion;
|
||||
import org.jclouds.chef.strategy.internal.ListCookbookVersionsImpl;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@ImplementedBy(ListCookbookVersionsImpl.class)
|
||||
public interface ListCookbookVersions {
|
||||
|
||||
Iterable<? extends CookbookVersion> execute();
|
||||
|
||||
Iterable<? extends CookbookVersion> execute(Predicate<String> cookbookNameSelector);
|
||||
|
||||
Iterable<? extends CookbookVersion> execute(Iterable<String> cookbookNames);
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.concat;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.jclouds.concurrent.FutureIterables.transformParallel;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.chef.ChefAsyncClient;
|
||||
import org.jclouds.chef.ChefClient;
|
||||
import org.jclouds.chef.domain.CookbookVersion;
|
||||
import org.jclouds.chef.reference.ChefConstants;
|
||||
import org.jclouds.chef.strategy.ListCookbookVersions;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class ListCookbookVersionsImpl implements ListCookbookVersions {
|
||||
|
||||
protected final ChefClient chefClient;
|
||||
protected final ChefAsyncClient chefAsyncClient;
|
||||
protected final ExecutorService userExecutor;
|
||||
@Resource
|
||||
@Named(ChefConstants.CHEF_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
@Inject(optional = true)
|
||||
@Named(Constants.PROPERTY_REQUEST_TIMEOUT)
|
||||
protected Long maxTime;
|
||||
|
||||
@Inject
|
||||
ListCookbookVersionsImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
|
||||
ChefClient getAllCookbookVersion, ChefAsyncClient ablobstore) {
|
||||
this.userExecutor = userExecutor;
|
||||
this.chefAsyncClient = ablobstore;
|
||||
this.chefClient = getAllCookbookVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends CookbookVersion> execute() {
|
||||
return execute(chefClient.listCookbooks());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends CookbookVersion> execute(Predicate<String> cookbookNameSelector) {
|
||||
return execute(filter(chefClient.listCookbooks(), cookbookNameSelector));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends CookbookVersion> execute(Iterable<String> toGet) {
|
||||
return concat(transform(toGet, new Function<String, Iterable<? extends CookbookVersion>>() {
|
||||
|
||||
@Override
|
||||
public Iterable<? extends CookbookVersion> apply(final String cookbook) {
|
||||
// TODO getting each version could also go parallel
|
||||
return transformParallel(chefClient.getVersionsOfCookbook(cookbook),
|
||||
new Function<String, Future<CookbookVersion>>() {
|
||||
|
||||
@Override
|
||||
public Future<CookbookVersion> apply(String version) {
|
||||
return chefAsyncClient.getCookbook(cookbook, version);
|
||||
}
|
||||
|
||||
}, userExecutor, maxTime, logger, "getting versions of cookbook " + cookbook);
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.util;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.addAll;
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static com.google.common.collect.Lists.transform;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* builds a run list in the correct syntax for chef.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RunListBuilder {
|
||||
private List<String> list = newArrayList();
|
||||
|
||||
/**
|
||||
* Add the following recipe to the run list
|
||||
*/
|
||||
public RunListBuilder addRecipe(String recipe) {
|
||||
return addRecipes(checkNotNull(recipe, "recipe"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the following recipes to the run list
|
||||
*/
|
||||
public RunListBuilder addRecipes(String... recipes) {
|
||||
addAll(list, transform(Arrays.asList(checkNotNull(recipes, "recipes")), new Function<String, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(String from) {
|
||||
return "recipe[" + from + "]";
|
||||
}
|
||||
|
||||
}));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the following role to the run list
|
||||
*/
|
||||
public RunListBuilder addRole(String role) {
|
||||
return addRoles(checkNotNull(role, "role"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the following roles to the run list
|
||||
*/
|
||||
public RunListBuilder addRoles(String... roles) {
|
||||
addAll(list, transform(Arrays.asList(checkNotNull(roles, "roles")), new Function<String, String>() {
|
||||
|
||||
@Override
|
||||
public String apply(String from) {
|
||||
return "role[" + from + "]";
|
||||
}
|
||||
|
||||
}));
|
||||
return this;
|
||||
}
|
||||
|
||||
public List<String> build() {
|
||||
return ImmutableList.copyOf(list);
|
||||
}
|
||||
}
|
|
@ -20,12 +20,14 @@
|
|||
package org.jclouds.chef;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.chef.config.ChefParserModule;
|
||||
import org.jclouds.chef.domain.CookbookVersion;
|
||||
import org.jclouds.json.Json;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||
|
@ -76,7 +78,7 @@ public class ChefClientLiveTest extends BaseChefClientLiveTest {
|
|||
Properties props = new Properties();
|
||||
props.setProperty("chef.endpoint", endpoint);
|
||||
return new ChefContextFactory().createContext(identity, key, ImmutableSet.<Module> of(new Log4JLoggingModule()),
|
||||
props);
|
||||
props);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -106,6 +108,12 @@ public class ChefClientLiveTest extends BaseChefClientLiveTest {
|
|||
clientConnection = createConnection(PREFIX, clientKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListCookbookVersionsWithChefService() throws Exception {
|
||||
Iterable<? extends CookbookVersion> cookbooks = adminConnection.getChefService().listCookbookVersions();
|
||||
assertNotNull(cookbooks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeContexts() {
|
||||
if (clientConnection != null)
|
||||
|
|
|
@ -103,7 +103,7 @@ public class ParseCookbookVersionFromJsonTest {
|
|||
new CookbookVersion(
|
||||
"apache-chef-demo-0.0.0",
|
||||
ImmutableSet.<Resource> of(),
|
||||
ImmutableSet.<Resource> of(),
|
||||
ImmutableSet.<Attribute> of(),
|
||||
ImmutableSet.<Resource> of(),
|
||||
new Metadata("Apache v2.0", "Your Name", ImmutableMap.<String, String> of(), ImmutableMap
|
||||
.<String, Set<String>> of(), "youremail@example.com", ImmutableMap
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||
*
|
||||
* ====================================================================
|
||||
* Licensed 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.util;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Tests possible uses of RunListBuilder
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class RunListBuilderTest {
|
||||
|
||||
@Test
|
||||
public void testRecipeAndRole() {
|
||||
RunListBuilder options = new RunListBuilder();
|
||||
options.addRecipe("recipe").addRole("role");
|
||||
assertEquals(options.build(),ImmutableList.of("recipe[recipe]","role[role]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecipe() {
|
||||
RunListBuilder options = new RunListBuilder();
|
||||
options.addRecipe("test");
|
||||
assertEquals(options.build(),ImmutableList.of("recipe[test]"));
|
||||
}
|
||||
@Test
|
||||
public void testRecipes() {
|
||||
RunListBuilder options = new RunListBuilder();
|
||||
options.addRecipes("test", "test2");
|
||||
assertEquals(options.build(),ImmutableList.of("recipe[test]","recipe[test2]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRole() {
|
||||
RunListBuilder options = new RunListBuilder();
|
||||
options.addRole("test");
|
||||
assertEquals(options.build(),ImmutableList.of("role[test]"));
|
||||
}
|
||||
@Test
|
||||
public void testRoles() {
|
||||
RunListBuilder options = new RunListBuilder();
|
||||
options.addRoles("test", "test2");
|
||||
assertEquals(options.build(),ImmutableList.of("role[test]","role[test2]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoneRecipe() {
|
||||
RunListBuilder options = new RunListBuilder();
|
||||
assertEquals(options.build(), ImmutableList.<String>of());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue