diff --git a/apis/chef/src/main/java/org/jclouds/chef/ChefApi.java b/apis/chef/src/main/java/org/jclouds/chef/ChefApi.java index 3c3d2bc27a..faa189c212 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/ChefApi.java +++ b/apis/chef/src/main/java/org/jclouds/chef/ChefApi.java @@ -26,7 +26,6 @@ import javax.inject.Named; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; -import javax.ws.rs.HEAD; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; @@ -36,7 +35,6 @@ import javax.ws.rs.core.MediaType; import org.jclouds.Constants; import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404; -import org.jclouds.Fallbacks.FalseOnNotFoundOr404; import org.jclouds.Fallbacks.NullOnNotFoundOr404; import org.jclouds.Fallbacks.VoidOnNotFoundOr404; import org.jclouds.chef.binders.BindChecksumsToJsonPayload; @@ -86,6 +84,7 @@ import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; import org.jclouds.rest.annotations.SinceApiVersion; +import org.jclouds.rest.annotations.SkipEncoding; import org.jclouds.rest.binders.BindToJsonPayload; /** @@ -294,20 +293,6 @@ public interface ChefApi extends Closeable { @Fallback(EmptySetOnNotFoundOr404.class) Set listClients(); - /** - * @return true if the specified client name exists. - * @throws AuthorizationException - *

- * "401 Unauthorized" if you are not a recognized user. - *

- * "403 Forbidden" if you do not have rights to view the client. - */ - @Named("client:exists") - @HEAD - @Path("/clients/{clientname}") - @Fallback(FalseOnNotFoundOr404.class) - boolean clientExists(@PathParam("clientname") String clientname); - /** * deletes an existing client. * @@ -384,20 +369,6 @@ public interface ChefApi extends Closeable { @Fallback(EmptySetOnNotFoundOr404.class) Set listNodes(); - /** - * @return true if the specified node name exists. - * @throws AuthorizationException - *

- * "401 Unauthorized" if you are not a recognized user. - *

- * "403 Forbidden" if you do not have rights to view the node. - */ - @Named("node:exists") - @HEAD - @Path("/nodes/{nodename}") - @Fallback(FalseOnNotFoundOr404.class) - boolean nodeExists(@PathParam("nodename") String nodename); - /** * deletes an existing node. * @@ -473,20 +444,6 @@ public interface ChefApi extends Closeable { @Fallback(EmptySetOnNotFoundOr404.class) Set listRoles(); - /** - * @return true if the specified role name exists. - * @throws AuthorizationException - *

- * "401 Unauthorized" if you are not a recognized user. - *

- * "403 Forbidden" if you do not have rights to view the role. - */ - @Named("role:exists") - @HEAD - @Path("/roles/{rolename}") - @Fallback(FalseOnNotFoundOr404.class) - boolean roleExists(@PathParam("rolename") String rolename); - /** * deletes an existing role. * @@ -548,21 +505,6 @@ public interface ChefApi extends Closeable { @Path("/data") void createDatabag(@BinderParam(BindNameToJsonPayload.class) String databagName); - /** - * true is a databag exists - * - * @throws AuthorizationException - *

- * "401 Unauthorized" if you are not a recognized user. - *

- * "403 Forbidden" if you do not have view rights on the databag. - */ - @Named("databag:exists") - @HEAD - @Path("/data/{name}") - @Fallback(FalseOnNotFoundOr404.class) - boolean databagExists(@PathParam("name") String databagName); - /** * Delete a data bag, including its items * @@ -628,22 +570,6 @@ public interface ChefApi extends Closeable { @PathParam("databagName") String databagName, @PathParam("databagItemId") @ParamParser(DatabagItemId.class) @BinderParam(BindToJsonPayload.class) DatabagItem item); - /** - * determines if a databag item exists - * - * @throws AuthorizationException - *

- * "401 Unauthorized" if you are not a recognized user. - *

- * "403 Forbidden" if you do not have view rights on the databag. - */ - @Named("databag:itemexists") - @HEAD - @Path("/data/{databagName}/{databagItemId}") - @Fallback(FalseOnNotFoundOr404.class) - boolean databagItemExists(@PathParam("databagName") String databagName, - @PathParam("databagItemId") String databagItemId); - /** * gets an existing databag item. * @@ -853,6 +779,7 @@ public interface ChefApi extends Closeable { @Named("content:get") @GET @Fallback(NullOnNotFoundOr404.class) + @SkipEncoding({'+', ' ', '/', '=', ':', ';'}) InputStream getResourceContents(@EndpointParam(parser = UriForResource.class) Resource resource); /** diff --git a/apis/chef/src/main/java/org/jclouds/chef/config/ChefParserModule.java b/apis/chef/src/main/java/org/jclouds/chef/config/ChefParserModule.java index 7a92064d96..f7457fee98 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/config/ChefParserModule.java +++ b/apis/chef/src/main/java/org/jclouds/chef/config/ChefParserModule.java @@ -16,6 +16,8 @@ */ package org.jclouds.chef.config; +import static com.google.common.base.Objects.equal; +import static com.google.common.base.Objects.toStringHelper; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; @@ -45,13 +47,16 @@ import org.jclouds.crypto.Pems; import org.jclouds.http.HttpResponse; import org.jclouds.json.config.GsonModule.DateAdapter; import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; +import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MapTypeAdapterFactory; import org.jclouds.json.internal.NullHackJsonLiteralAdapter; import org.jclouds.rest.annotations.ApiVersion; import com.google.common.base.Charsets; import com.google.common.base.Function; +import com.google.common.base.Objects; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.google.common.io.ByteStreams; import com.google.gson.Gson; import com.google.gson.JsonDeserializationContext; @@ -59,6 +64,10 @@ import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.JsonSyntaxException; +import com.google.gson.TypeAdapter; +import com.google.gson.internal.JsonReaderInternalAccess; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; import com.google.inject.AbstractModule; import com.google.inject.ImplementedBy; import com.google.inject.Provides; @@ -211,6 +220,82 @@ public class ChefParserModule extends AbstractModule { private String id; } + // The NullFilteringTypeAdapterFactories.MapTypeAdapter class is final. Do + // the same logic here + private static final class KeepLastRepeatedKeyMapTypeAdapter extends TypeAdapter> { + + protected final TypeAdapter keyAdapter; + protected final TypeAdapter valueAdapter; + + protected KeepLastRepeatedKeyMapTypeAdapter(TypeAdapter keyAdapter, TypeAdapter valueAdapter) { + this.keyAdapter = keyAdapter; + this.valueAdapter = valueAdapter; + nullSafe(); + } + + public void write(JsonWriter out, Map value) throws IOException { + if (value == null) { + out.nullValue(); + return; + } + out.beginObject(); + for (Map.Entry element : value.entrySet()) { + out.name(String.valueOf(element.getKey())); + valueAdapter.write(out, element.getValue()); + } + out.endObject(); + } + + public Map read(JsonReader in) throws IOException { + Map result = Maps.newHashMap(); + in.beginObject(); + while (in.hasNext()) { + JsonReaderInternalAccess.INSTANCE.promoteNameToValue(in); + K name = keyAdapter.read(in); + V value = valueAdapter.read(in); + if (value != null) { + // If there are repeated keys, overwrite them to only keep the last one + result.put(name, value); + } + } + in.endObject(); + return ImmutableMap.copyOf(result); + } + + @Override + public int hashCode() { + return Objects.hashCode(keyAdapter, valueAdapter); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + KeepLastRepeatedKeyMapTypeAdapter that = KeepLastRepeatedKeyMapTypeAdapter.class.cast(obj); + return equal(this.keyAdapter, that.keyAdapter) && equal(this.valueAdapter, that.valueAdapter); + } + + @Override + public String toString() { + return toStringHelper(this).add("keyAdapter", keyAdapter).add("valueAdapter", valueAdapter).toString(); + } + } + + public static class KeepLastRepeatedKeyMapTypeAdapterFactory extends MapTypeAdapterFactory { + + public KeepLastRepeatedKeyMapTypeAdapterFactory() { + super(Map.class); + } + + @SuppressWarnings("unchecked") + @Override + protected TypeAdapter newAdapter(TypeAdapter keyAdapter, TypeAdapter valueAdapter) { + return (TypeAdapter) new KeepLastRepeatedKeyMapTypeAdapter(keyAdapter, valueAdapter); + } + } + @Provides @Singleton public Map provideCustomAdapterBindings(DataBagItemAdapter adapter, PrivateKeyAdapter privateAdapter, @@ -252,5 +337,6 @@ public class ChefParserModule extends AbstractModule { @Override protected void configure() { bind(DateAdapter.class).to(Iso8601DateAdapter.class); + bind(MapTypeAdapterFactory.class).to(KeepLastRepeatedKeyMapTypeAdapterFactory.class); } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/Attribute.java b/apis/chef/src/main/java/org/jclouds/chef/domain/Attribute.java index 38d10c6fc3..a5fb25d398 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/Attribute.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/Attribute.java @@ -16,46 +16,120 @@ */ package org.jclouds.chef.domain; +import static org.jclouds.chef.util.CollectionUtils.*; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.beans.ConstructorProperties; import java.util.List; import java.util.Set; import org.jclouds.domain.JsonBall; +import org.jclouds.javax.annotation.Nullable; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.gson.annotations.SerializedName; /** - * Cookbook object. + * An attribute in a cookbook metadata. * * @author Adrian Cole + * @author Ignasi Barrera */ public class Attribute { - - private String required; - private boolean calculated; - private List choice = Lists.newArrayList(); - @SerializedName("default") - private JsonBall defaultValue; - private String type; - private List recipes = Lists.newArrayList(); - @SerializedName("display_name") - private String displayName; - private String description; - - public Attribute(String required, boolean calculated, Set choice, JsonBall defaultValue, String type, - List recipes, String displayName, String description) { - this.required = required; - this.calculated = calculated; - Iterables.addAll(this.choice, choice); - this.defaultValue = defaultValue; - this.type = type; - Iterables.addAll(this.recipes, recipes); - this.displayName = displayName; - this.description = description; + public static Builder builder() { + return new Builder(); } - public Attribute() { + public static class Builder { + private String required; + private boolean calculated; + private ImmutableSet.Builder choice = ImmutableSet.builder(); + private JsonBall defaultValue; + private String type; + private ImmutableList.Builder recipes = ImmutableList.builder(); + private String displayName; + private String description; + + public Builder required(String required) { + this.required = checkNotNull(required, "required"); + return this; + } + + public Builder calculated(boolean calculated) { + this.calculated = calculated; + return this; + } + + public Builder choice(String choice) { + this.choice.add(checkNotNull(choice, "choice")); + return this; + } + + public Builder choices(Iterable choices) { + this.choice.addAll(checkNotNull(choices, "choices")); + return this; + } + + public Builder defaultValue(JsonBall defaultValue) { + this.defaultValue = checkNotNull(defaultValue, "defaultValue"); + return this; + } + + public Builder type(String type) { + this.type = checkNotNull(type, "type"); + return this; + } + + public Builder recipe(String recipe) { + this.recipes.add(checkNotNull(recipe, "recipe")); + return this; + } + + public Builder recipes(Iterable recipes) { + this.recipes.addAll(checkNotNull(recipes, "recipes")); + return this; + } + + public Builder displayName(String displayName) { + this.displayName = checkNotNull(displayName, "displayName"); + return this; + } + + public Builder description(String description) { + this.description = checkNotNull(description, "description"); + return this; + } + + public Attribute build() { + return new Attribute(required, calculated, choice.build(), defaultValue, type, recipes.build(), displayName, + description); + } + } + + private final String required; + private final boolean calculated; + private final Set choice; + @SerializedName("default") + private final JsonBall defaultValue; + private final String type; + private final List recipes; + @SerializedName("display_name") + private final String displayName; + private final String description; + + @ConstructorProperties({ "required", "calculated", "choice", "default", "type", "recipes", "display_name", + "description" }) + protected Attribute(String required, boolean calculated, @Nullable Set choice, JsonBall defaultValue, + String type, @Nullable List recipes, String displayName, String description) { + this.required = required; + this.calculated = calculated; + this.choice = copyOfOrEmpty(choice); + this.defaultValue = defaultValue; + this.type = type; + this.recipes = copyOfOrEmpty(recipes); + this.displayName = displayName; + this.description = description; } public String getRequired() { @@ -66,7 +140,7 @@ public class Attribute { return calculated; } - public List getChoice() { + public Set getChoice() { return choice; } @@ -162,4 +236,3 @@ public class Attribute { } } - diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java b/apis/chef/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java index 2c16514052..22d8f36426 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/BootstrapConfig.java @@ -17,14 +17,13 @@ package org.jclouds.chef.domain; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.addAll; import java.util.List; import org.jclouds.domain.JsonBall; import com.google.common.base.Optional; -import com.google.common.collect.Lists; +import com.google.common.collect.ImmutableList; /** * Configures how the nodes in a group will bootstrap. @@ -33,13 +32,12 @@ import com.google.common.collect.Lists; * @since 1.7 */ public class BootstrapConfig { - public static Builder builder() { return new Builder(); } public static class Builder { - private List runList = Lists.newArrayList(); + private ImmutableList.Builder runList = ImmutableList.builder(); private String environment; private JsonBall attribtues; @@ -47,7 +45,7 @@ public class BootstrapConfig { * Sets the run list that will be executed in the nodes of the group. */ public Builder runList(Iterable runList) { - addAll(this.runList, checkNotNull(runList, "runList")); + this.runList.addAll(checkNotNull(runList, "runList")); return this; } @@ -68,13 +66,14 @@ public class BootstrapConfig { } public BootstrapConfig build() { - return new BootstrapConfig(runList, Optional.fromNullable(environment), Optional.fromNullable(attribtues)); + return new BootstrapConfig(runList.build(), Optional.fromNullable(environment), + Optional.fromNullable(attribtues)); } } - private List runList = Lists.newArrayList(); - private Optional environment; - private Optional attribtues; + private final List runList; + private final Optional environment; + private final Optional attribtues; protected BootstrapConfig(List runList, Optional environment, Optional attribtues) { this.runList = checkNotNull(runList, "runList"); diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/ChecksumStatus.java b/apis/chef/src/main/java/org/jclouds/chef/domain/ChecksumStatus.java index ffe7e64915..e1c77e9014 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/ChecksumStatus.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/ChecksumStatus.java @@ -16,26 +16,50 @@ */ package org.jclouds.chef.domain; +import static com.google.common.base.Preconditions.*; +import java.beans.ConstructorProperties; import java.net.URI; import com.google.gson.annotations.SerializedName; /** + * The checksum of an uploaded resource. * * @author Adrian Cole + * @author Ignasi Barrera */ public class ChecksumStatus { - private URI url; - @SerializedName("needs_upload") - private boolean needsUpload; - - public ChecksumStatus(URI url, boolean needsUpload) { - this.url = url; - this.needsUpload = needsUpload; + public static Builder builder() { + return new Builder(); } - public ChecksumStatus() { + public static class Builder { + private URI url; + private boolean needsUpload; + public Builder url(URI url) { + this.url = checkNotNull(url, "url"); + return this; + } + + public Builder needsUpload(boolean needsUpload) { + this.needsUpload = needsUpload; + return this; + } + + public ChecksumStatus build() { + return new ChecksumStatus(url, needsUpload); + } + } + + private final URI url; + @SerializedName("needs_upload") + private final boolean needsUpload; + + @ConstructorProperties({ "url", "needs_upload" }) + protected ChecksumStatus(URI url, boolean needsUpload) { + this.url = url; + this.needsUpload = needsUpload; } public URI getUrl() { @@ -46,11 +70,6 @@ public class ChecksumStatus { return needsUpload; } - @Override - public String toString() { - return "ChecksumStatus [needsUpload=" + needsUpload + ", url=" + url + "]"; - } - @Override public int hashCode() { final int prime = 31; @@ -78,5 +97,9 @@ public class ChecksumStatus { return false; return true; } -} + @Override + public String toString() { + return "ChecksumStatus [needsUpload=" + needsUpload + ", url=" + url + "]"; + } +} diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/Client.java b/apis/chef/src/main/java/org/jclouds/chef/domain/Client.java index 47dc4e04b6..101638cb6a 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/Client.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/Client.java @@ -16,6 +16,9 @@ */ package org.jclouds.chef.domain; +import static com.google.common.base.Preconditions.*; + +import java.beans.ConstructorProperties; import java.security.PrivateKey; import java.security.cert.X509Certificate; @@ -27,19 +30,73 @@ import com.google.gson.annotations.SerializedName; * Client object. * * @author Adrian Cole + * @author Ignasi Barrera */ public class Client { - private X509Certificate certificate; + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private X509Certificate certificate; + private PrivateKey privateKey; + private String orgname; + private String clientname; + private String name; + private boolean validator; + + public Builder certificate(X509Certificate certificate) { + this.certificate = checkNotNull(certificate, "certificate"); + return this; + } + + public Builder privateKey(PrivateKey privateKey) { + this.privateKey = checkNotNull(privateKey, "privateKey"); + return this; + } + + public Builder orgname(String orgname) { + this.orgname = checkNotNull(orgname, "orgname"); + return this; + } + + public Builder clientname(String clientname) { + this.clientname = checkNotNull(clientname, "clientname"); + return this; + } + + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + public Builder isValidator(boolean validator) { + this.validator = validator; + return this; + } + + public Client build() { + return new Client(certificate, orgname, clientname, name, validator, privateKey); + } + } + + private final X509Certificate certificate; @SerializedName("private_key") - private PrivateKey privateKey; - private String orgname; - private String clientname; - private String name; - private boolean validator; - - // only for deserialization - Client() { + private final PrivateKey privateKey; + private final String orgname; + private final String clientname; + private final String name; + private final boolean validator; + @ConstructorProperties({ "certificate", "orgname", "clientname", "name", "validator", "private_key" }) + protected Client(X509Certificate certificate, String orgname, String clientname, String name, boolean validator, + @Nullable PrivateKey privateKey) { + this.certificate = certificate; + this.orgname = orgname; + this.clientname = clientname; + this.name = name; + this.validator = validator; + this.privateKey = privateKey; } public PrivateKey getPrivateKey() { @@ -66,12 +123,6 @@ public class Client { return validator; } - @Override - public String toString() { - return "[name=" + name + ", clientname=" + clientname + ", orgname=" + orgname + ", isValidator=" + validator - + ", certificate=" + certificate + ", privateKey=" + (privateKey != null) + "]"; - } - @Override public int hashCode() { final int prime = 31; @@ -124,14 +175,11 @@ public class Client { return true; } - public Client(X509Certificate certificate, String orgname, String clientname, String name, boolean isValidator, - @Nullable PrivateKey privateKey) { - this.certificate = certificate; - this.orgname = orgname; - this.clientname = clientname; - this.name = name; - this.validator = isValidator; - this.privateKey = privateKey; + @Override + public String toString() { + return "Client [name=" + name + ", clientname=" + clientname + ", orgname=" + orgname + ", isValidator=" + + validator + ", certificate=" + certificate + ", privateKey=" + (privateKey == null ? "not " : "") + + "present]"; } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/CookbookDefinition.java b/apis/chef/src/main/java/org/jclouds/chef/domain/CookbookDefinition.java index 7b0dea2ecf..6531f036e4 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/CookbookDefinition.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/CookbookDefinition.java @@ -16,10 +16,16 @@ */ package org.jclouds.chef.domain; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty; + +import java.beans.ConstructorProperties; import java.net.URI; import java.util.Set; -import com.google.common.collect.Sets; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.collect.ImmutableSet; /** * Cookbook definition as returned by the Chef server >= 0.10.8. @@ -27,18 +33,41 @@ import com.google.common.collect.Sets; * @author Ignasi Barrera */ public class CookbookDefinition { - - private URI url; - private Set versions = Sets.newLinkedHashSet(); - - // only for deserialization - CookbookDefinition() { - + public static Builder builder() { + return new Builder(); } - public CookbookDefinition(URI url, Set versions) { + public static class Builder { + private URI url; + private ImmutableSet.Builder versions = ImmutableSet.builder(); + + public Builder url(URI url) { + this.url = checkNotNull(url, "url"); + return this; + } + + public Builder version(Version version) { + this.versions.add(checkNotNull(version, "version")); + return this; + } + + public Builder versions(Iterable versions) { + this.versions.addAll(checkNotNull(versions, "versions")); + return this; + } + + public CookbookDefinition build() { + return new CookbookDefinition(url, versions.build()); + } + } + + private final URI url; + private final Set versions; + + @ConstructorProperties({ "url", "versions" }) + protected CookbookDefinition(URI url, @Nullable Set versions) { this.url = url; - this.versions = versions; + this.versions = copyOfOrEmpty(versions); } public URI getUrl() { @@ -86,15 +115,34 @@ public class CookbookDefinition { } public static class Version { - private URI url; - private String version; - - // only for deserialization - Version() { - + public static Builder builder() { + return new Builder(); } - public Version(URI url, String version) { + public static class Builder { + private URI url; + private String version; + + public Builder url(URI url) { + this.url = checkNotNull(url, "url"); + return this; + } + + public Builder version(String version) { + this.version = checkNotNull(version, "version"); + return this; + } + + public Version build() { + return new Version(url, version); + } + } + + private final URI url; + private final String version; + + @ConstructorProperties({ "url", "version" }) + protected Version(URI url, String version) { this.url = url; this.version = version; } diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/CookbookVersion.java b/apis/chef/src/main/java/org/jclouds/chef/domain/CookbookVersion.java index 9251bd13fb..5af929e554 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/CookbookVersion.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/CookbookVersion.java @@ -16,34 +16,174 @@ */ package org.jclouds.chef.domain; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty; + +import java.beans.ConstructorProperties; import java.util.Set; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.collect.ImmutableSet; import com.google.gson.annotations.SerializedName; /** * Cookbook object. * * @author Adrian Cole + * @author Ignasi Barrera */ public class CookbookVersion { + public static Builder builder(String name, String version) { + return new Builder(name, version); + } - private String name; - private Set definitions = Sets.newLinkedHashSet(); - private Set attributes = Sets.newLinkedHashSet(); - private Set files = Sets.newLinkedHashSet(); - private Metadata metadata = new Metadata(); - private Set providers = Sets.newLinkedHashSet(); + public static class Builder { + private String cookbookName; + private ImmutableSet.Builder definitions = ImmutableSet.builder(); + private ImmutableSet.Builder attributes = ImmutableSet.builder(); + private ImmutableSet.Builder files = ImmutableSet.builder(); + private Metadata metadata = Metadata.builder().build(); + private ImmutableSet.Builder providers = ImmutableSet.builder(); + private ImmutableSet.Builder resources = ImmutableSet.builder(); + private ImmutableSet.Builder templates = ImmutableSet.builder(); + private ImmutableSet.Builder libraries = ImmutableSet.builder(); + private String version; + private ImmutableSet.Builder recipes = ImmutableSet.builder(); + private ImmutableSet.Builder rootFiles = ImmutableSet.builder(); + + public Builder(String name, String version) { + this.cookbookName = checkNotNull(name, "name"); + this.version = checkNotNull(version, "version"); + } + + public Builder cookbookName(String cookbookName) { + this.cookbookName = checkNotNull(cookbookName, "cookbookName"); + return this; + } + + public Builder definition(Resource definition) { + this.definitions.add(checkNotNull(definition, "definition")); + return this; + } + + public Builder definitions(Iterable definitions) { + this.definitions.addAll(checkNotNull(definitions, "definitions")); + return this; + } + + public Builder attribute(Attribute attribute) { + this.attributes.add(checkNotNull(attribute, "attribute")); + return this; + } + + public Builder attributes(Iterable attributes) { + this.attributes.addAll(checkNotNull(attributes, "attributes")); + return this; + } + + public Builder file(Resource file) { + this.files.add(checkNotNull(file, "file")); + return this; + } + + public Builder files(Iterable files) { + this.files.addAll(checkNotNull(files, "files")); + return this; + } + + public Builder metadata(Metadata metadata) { + this.metadata = checkNotNull(metadata, "metadata"); + return this; + } + + public Builder provider(Resource provider) { + this.providers.add(checkNotNull(provider, "provider")); + return this; + } + + public Builder providers(Iterable providers) { + this.providers.addAll(checkNotNull(providers, "providers")); + return this; + } + + public Builder resource(Resource resource) { + this.resources.add(checkNotNull(resource, "resource")); + return this; + } + + public Builder resources(Iterable resources) { + this.resources.addAll(checkNotNull(resources, "resources")); + return this; + } + + public Builder template(Resource template) { + this.templates.add(checkNotNull(template, "template")); + return this; + } + + public Builder templates(Iterable templates) { + this.templates.addAll(checkNotNull(templates, "templates")); + return this; + } + + public Builder library(Resource library) { + this.libraries.add(checkNotNull(library, "library")); + return this; + } + + public Builder libraries(Iterable libraries) { + this.libraries.addAll(checkNotNull(libraries, "libraries")); + return this; + } + + public Builder version(String version) { + this.version = checkNotNull(version, "version"); + return this; + } + + public Builder recipe(Resource recipe) { + this.recipes.add(checkNotNull(recipe, "recipe")); + return this; + } + + public Builder recipes(Iterable recipes) { + this.recipes.addAll(checkNotNull(recipes, "recipes")); + return this; + } + + public Builder rootFile(Resource rootFile) { + this.rootFiles.add(checkNotNull(rootFile, "rootFile")); + return this; + } + + public Builder rootFiles(Iterable rootFiles) { + this.rootFiles.addAll(checkNotNull(rootFiles, "rootFiles")); + return this; + } + + public CookbookVersion build() { + return new CookbookVersion(checkNotNull(cookbookName, "name") + "-" + checkNotNull(version, "version"), + definitions.build(), attributes.build(), files.build(), metadata, providers.build(), cookbookName, + resources.build(), templates.build(), libraries.build(), version, recipes.build(), rootFiles.build()); + } + } + + private final String name; + private final Set definitions; + private final Set attributes; + private final Set files; + private final Metadata metadata; + private final Set providers; @SerializedName("cookbook_name") - private String cookbookName; - private Set resources = Sets.newLinkedHashSet(); - private Set templates = Sets.newLinkedHashSet(); - private Set libraries = Sets.newLinkedHashSet(); - private String version; - private Set recipes = Sets.newLinkedHashSet(); + private final String cookbookName; + private final Set resources; + private final Set templates; + private final Set libraries; + private final String version; + private final Set recipes; @SerializedName("root_files") - private Set rootFiles = Sets.newLinkedHashSet(); + private final Set rootFiles; // internal @SerializedName("json_class") @@ -51,34 +191,25 @@ public class CookbookVersion { @SerializedName("chef_type") private String _chefType = "cookbook_version"; - public CookbookVersion(String cookbookName, String version) { - this.cookbookName = cookbookName; - this.version = version; - this.name = cookbookName + "-" + version; - } - - public CookbookVersion(String name, Set definitions, Set attributes, Set files, - Metadata metadata, Set providers, String cookbookName, Set resources, - Set templates, Set libraries, String version, Set recipes, - Set rootFiles) { + @ConstructorProperties({ "name", "definitions", "attributes", "files", "metadata", "providers", "cookbook_name", + "resources", "templates", "libraries", "version", "recipes", "root_files" }) + protected CookbookVersion(String name, @Nullable Set definitions, @Nullable Set attributes, + @Nullable Set files, Metadata metadata, @Nullable Set providers, String cookbookName, + @Nullable Set resources, @Nullable Set templates, @Nullable Set libraries, + String version, @Nullable Set recipes, @Nullable Set rootFiles) { this.name = name; - Iterables.addAll(this.definitions, definitions); - Iterables.addAll(this.attributes, attributes); - Iterables.addAll(this.files, files); + this.definitions = copyOfOrEmpty(definitions); + this.attributes = copyOfOrEmpty(attributes); + this.files = copyOfOrEmpty(files); this.metadata = metadata; - Iterables.addAll(this.providers, providers); + this.providers = copyOfOrEmpty(providers); this.cookbookName = cookbookName; - Iterables.addAll(this.resources, resources); - Iterables.addAll(this.templates, templates); - Iterables.addAll(this.libraries, libraries); + this.resources = copyOfOrEmpty(resources); + this.templates = copyOfOrEmpty(templates); + this.libraries = copyOfOrEmpty(libraries); this.version = version; - Iterables.addAll(this.recipes, recipes); - Iterables.addAll(this.rootFiles, rootFiles); - } - - // hidden but needs to be here for json deserialization to work - CookbookVersion() { - + this.recipes = copyOfOrEmpty(recipes); + this.rootFiles = copyOfOrEmpty(rootFiles); } public String getName() { diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/DatabagItem.java b/apis/chef/src/main/java/org/jclouds/chef/domain/DatabagItem.java index 8d253a5e4e..9138b9ff8e 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/DatabagItem.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/DatabagItem.java @@ -21,8 +21,10 @@ import static com.google.common.base.Preconditions.checkNotNull; import org.jclouds.domain.JsonBall; /** + * An item in a data bag. * * @author Adrian Cole + * @author Ignasi Barrera */ public class DatabagItem extends JsonBall { @@ -62,4 +64,3 @@ public class DatabagItem extends JsonBall { return id; } } - diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/Environment.java b/apis/chef/src/main/java/org/jclouds/chef/domain/Environment.java index d96caa7863..f54208e5c4 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/Environment.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/Environment.java @@ -16,48 +16,105 @@ */ package org.jclouds.chef.domain; -import com.google.common.collect.Maps; -import com.google.gson.annotations.SerializedName; -import org.jclouds.domain.JsonBall; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty; +import java.beans.ConstructorProperties; import java.util.Map; -public class Environment { +import org.jclouds.domain.JsonBall; +import org.jclouds.javax.annotation.Nullable; - private String name; - @SerializedName("default_attributes") - private Map attributes = Maps.newLinkedHashMap(); +import com.google.common.collect.ImmutableMap; +import com.google.gson.annotations.SerializedName; + +/** + * An environment. + * + * @author Ignasi Barrera + */ +public class Environment { + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String name; + private ImmutableMap.Builder attributes = ImmutableMap.builder(); + private ImmutableMap.Builder overrideAttributes = ImmutableMap.builder(); + private String description = ""; + private ImmutableMap.Builder cookbookVersions = ImmutableMap.builder(); + + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + public Builder attribute(String key, JsonBall value) { + this.attributes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder attributes(Map attributes) { + this.attributes.putAll(checkNotNull(attributes, "attributes")); + return this; + } + + public Builder overrideAttribute(String key, JsonBall value) { + this.overrideAttributes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder overrideAttributes(Map overrideAttributes) { + this.overrideAttributes.putAll(checkNotNull(overrideAttributes, "overrideAttributes")); + return this; + } + + public Builder cookbookVersion(String key, String version) { + this.cookbookVersions.put(checkNotNull(key, "key"), checkNotNull(version, "version")); + return this; + } + + public Builder cookbookVersions(Map cookbookVersions) { + this.cookbookVersions.putAll(checkNotNull(cookbookVersions, "cookbookVersions")); + return this; + } + + public Builder description(String description) { + this.description = checkNotNull(description, "description"); + return this; + } + + public Environment build() { + return new Environment(name, attributes.build(), overrideAttributes.build(), description, + cookbookVersions.build()); + } + } + + private final String name; + @SerializedName("default_attributes") + private final Map attributes; @SerializedName("override_attributes") - private Map overrideAttributes = Maps.newLinkedHashMap(); - private String description = ""; + private final Map overrideAttributes; + private final String description; @SerializedName("cookbook_versions") - private Map cookbookVersions = Maps.newLinkedHashMap(); + private final Map cookbookVersions; + // internal @SerializedName("json_class") - private String _jsonClass = "Chef::Environment"; + private final String _jsonClass = "Chef::Environment"; @SerializedName("chef_type") - private String _chefType = "environment"; + private final String _chefType = "environment"; - public Environment(String name, Map attributes, Map overrideAttributes, - String description, Map cookbookVersions) { + @ConstructorProperties({ "name", "default_attributes", "override_attributes", "description", "cookbook_versions" }) + protected Environment(String name, @Nullable Map attributes, + @Nullable Map overrideAttributes, String description, + @Nullable Map cookbookVersions) { this.name = name; - this.attributes.putAll(attributes); - this.overrideAttributes.putAll(overrideAttributes); + this.attributes = copyOfOrEmpty(attributes); + this.overrideAttributes = copyOfOrEmpty(overrideAttributes); this.description = description; - this.cookbookVersions.putAll(cookbookVersions); - } - - public Environment(String name, String description) { - this.name = name; - this.description = description; - } - - public Environment(String name) { - this(name, null); - } - - // hidden but needs to be here for json deserialization to work - Environment() { + this.cookbookVersions = copyOfOrEmpty(cookbookVersions); } public String getName() { @@ -82,17 +139,23 @@ public class Environment { @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; Environment that = (Environment) o; - if (attributes != null ? !attributes.equals(that.attributes) : that.attributes != null) return false; + if (attributes != null ? !attributes.equals(that.attributes) : that.attributes != null) + return false; if (cookbookVersions != null ? !cookbookVersions.equals(that.cookbookVersions) : that.cookbookVersions != null) return false; - if (description != null ? !description.equals(that.description) : that.description != null) return false; - if (!name.equals(that.name)) return false; - if (overrideAttributes != null ? !overrideAttributes.equals(that.overrideAttributes) : that.overrideAttributes != null) + if (description != null ? !description.equals(that.description) : that.description != null) + return false; + if (!name.equals(that.name)) + return false; + if (overrideAttributes != null ? !overrideAttributes.equals(that.overrideAttributes) + : that.overrideAttributes != null) return false; return true; @@ -110,12 +173,8 @@ public class Environment { @Override public String toString() { - return "[" + - "name='" + name + '\'' + - ", attributes=" + attributes + - ", overrideAttributes=" + overrideAttributes + - ", description='" + description + '\'' + - ", cookbookVersions=" + cookbookVersions + - ']'; + return "Environment [" + "name='" + name + '\'' + ", attributes=" + attributes + ", overrideAttributes=" + + overrideAttributes + ", description='" + description + '\'' + ", cookbookVersions=" + cookbookVersions + + ']'; } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/Metadata.java b/apis/chef/src/main/java/org/jclouds/chef/domain/Metadata.java index 2bc104493c..0cfb66fbdf 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/Metadata.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/Metadata.java @@ -16,63 +16,236 @@ */ package org.jclouds.chef.domain; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty; + +import java.beans.ConstructorProperties; import java.util.Map; -import com.google.common.collect.Maps; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.collect.ImmutableMap; import com.google.gson.annotations.SerializedName; /** - * Cookbook object. + * A metadata object. * * @author Adrian Cole + * @author Ignasi Barrera */ public class Metadata { - - private String license; - private String maintainer; - private Map suggestions = Maps.newLinkedHashMap(); - private Map dependencies = Maps.newLinkedHashMap(); - @SerializedName("maintainer_email") - private String maintainerEmail; - private Map conflicting = Maps.newLinkedHashMap(); - private String description; - private Map providing = Maps.newLinkedHashMap(); - private Map platforms = Maps.newLinkedHashMap(); - private String version; - private Map recipes = Maps.newLinkedHashMap(); - private Map replacing = Maps.newLinkedHashMap(); - private String name; - private Map groupings = Maps.newLinkedHashMap(); - @SerializedName("long_description") - private String longDescription; - private Map attributes = Maps.newLinkedHashMap(); - private Map recommendations = Maps.newLinkedHashMap(); - - public Metadata(String license, String maintainer, Map suggestions, - Map dependencies, String maintainerEmail, Map conflicting, String description, - Map providing, Map platforms, String version, Map recipes, - Map replacing, String name, Map groupings, String longDescription, - Map attributes, Map recommendations) { - this.license = license; - this.maintainer = maintainer; - this.suggestions.putAll(suggestions); - this.dependencies.putAll(dependencies); - this.maintainerEmail = maintainerEmail; - this.conflicting.putAll(conflicting); - this.description = description; - this.providing.putAll(providing); - this.platforms.putAll(platforms); - this.version = version; - this.recipes.putAll(recipes); - this.replacing.putAll(replacing); - this.name = name; - this.groupings.putAll(groupings); - this.longDescription = longDescription; - this.attributes.putAll(attributes); - this.recommendations.putAll(recommendations); + public static Builder builder() { + return new Builder(); } - public Metadata() { + public static class Builder { + private String license; + private String maintainer; + private ImmutableMap.Builder suggestions = ImmutableMap.builder(); + private ImmutableMap.Builder dependencies = ImmutableMap.builder(); + private String maintainerEmail; + private ImmutableMap.Builder conflicting = ImmutableMap.builder(); + private String description; + private ImmutableMap.Builder providing = ImmutableMap.builder(); + private ImmutableMap.Builder platforms = ImmutableMap.builder(); + private String version; + private ImmutableMap.Builder recipes = ImmutableMap.builder(); + private ImmutableMap.Builder replacing = ImmutableMap.builder(); + private String name; + private ImmutableMap.Builder groupings = ImmutableMap.builder(); + private String longDescription; + private ImmutableMap.Builder attributes = ImmutableMap.builder(); + private ImmutableMap.Builder recommendations = ImmutableMap.builder(); + + public Builder license(String license) { + this.license = checkNotNull(license, "license"); + return this; + } + + public Builder maintainer(String maintainer) { + this.maintainer = checkNotNull(maintainer, "maintainer"); + return this; + } + + public Builder suggestion(String key, String value) { + this.suggestions.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder suggestions(Map suggestions) { + this.suggestions.putAll(checkNotNull(suggestions, "suggestions")); + return this; + } + + public Builder dependency(String key, String value) { + this.dependencies.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder dependencies(Map dependencies) { + this.dependencies.putAll(checkNotNull(dependencies, "dependencies")); + return this; + } + + public Builder maintainerEmail(String maintainerEmail) { + this.maintainerEmail = checkNotNull(maintainerEmail, "maintainerEmail"); + return this; + } + + public Builder conflicting(String key, String value) { + this.conflicting.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder conflicting(Map conflicting) { + this.conflicting.putAll(checkNotNull(conflicting, "conflicting")); + return this; + } + + public Builder description(String description) { + this.description = checkNotNull(description, "description"); + return this; + } + + public Builder providing(String key, String value) { + this.providing.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder providing(Map providing) { + this.providing.putAll(checkNotNull(providing, "providing")); + return this; + } + + public Builder platform(String key, String value) { + this.platforms.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder platforms(Map platforms) { + this.platforms.putAll(checkNotNull(platforms, "platforms")); + return this; + } + + public Builder version(String version) { + this.version = checkNotNull(version, "version"); + return this; + } + + public Builder recipe(String key, String value) { + this.recipes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder recipes(Map recipes) { + this.recipes.putAll(checkNotNull(recipes, "recipes")); + return this; + } + + public Builder replacing(String key, String value) { + this.replacing.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder replacing(Map replacing) { + this.replacing.putAll(checkNotNull(replacing, "replacing")); + return this; + } + + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + public Builder grouping(String key, String value) { + this.groupings.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder grouping(Map groupings) { + this.groupings.putAll(checkNotNull(groupings, "groupings")); + return this; + } + + public Builder longDescription(String longDescription) { + this.longDescription = checkNotNull(longDescription, "longDescription"); + return this; + } + + public Builder attribute(String key, Attribute value) { + this.attributes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder attributes(Map attributes) { + this.attributes.putAll(checkNotNull(attributes, "attributes")); + return this; + } + + public Builder recommendation(String key, String value) { + this.recommendations.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder recommendations(Map recommendations) { + this.recommendations.putAll(checkNotNull(recommendations, "recommendations")); + return this; + } + + public Metadata build() { + return new Metadata(license, maintainer, suggestions.build(), dependencies.build(), maintainerEmail, + conflicting.build(), description, providing.build(), platforms.build(), version, recipes.build(), + replacing.build(), name, groupings.build(), longDescription, attributes.build(), recommendations.build()); + } + + } + + private final String license; + private final String maintainer; + private final Map suggestions; + private final Map dependencies; + @SerializedName("maintainer_email") + private final String maintainerEmail; + private final Map conflicting; + private final String description; + private final Map providing; + private final Map platforms; + private final String version; + private final Map recipes; + private final Map replacing; + private final String name; + private final Map groupings; + @SerializedName("long_description") + private final String longDescription; + private final Map attributes; + private final Map recommendations; + + @ConstructorProperties({ "license", "maintainer", "suggestions", "dependencies", "maintainer_email", "conflicting", + "description", "providing", "platforms", "version", "recipes", "replacing", "name", "groupings", + "long_description", "attributes", "recommendations" }) + protected Metadata(String license, String maintainer, @Nullable Map suggestions, + @Nullable Map dependencies, String maintainerEmail, @Nullable Map conflicting, + String description, @Nullable Map providing, @Nullable Map platforms, + String version, @Nullable Map recipes, @Nullable Map replacing, String name, + @Nullable Map groupings, String longDescription, @Nullable Map attributes, + @Nullable Map recommendations) { + this.license = license; + this.maintainer = maintainer; + this.suggestions = copyOfOrEmpty(suggestions); + this.dependencies = copyOfOrEmpty(dependencies); + this.maintainerEmail = maintainerEmail; + this.conflicting = copyOfOrEmpty(conflicting); + this.description = description; + this.providing = copyOfOrEmpty(providing); + this.platforms = copyOfOrEmpty(platforms); + this.version = version; + this.recipes = copyOfOrEmpty(recipes); + this.replacing = copyOfOrEmpty(replacing); + this.name = name; + this.groupings = copyOfOrEmpty(groupings); + this.longDescription = longDescription; + this.attributes = copyOfOrEmpty(attributes); + this.recommendations = copyOfOrEmpty(recommendations); } public String getLicense() { @@ -275,4 +448,3 @@ public class Metadata { } } - diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/Node.java b/apis/chef/src/main/java/org/jclouds/chef/domain/Node.java index 83cd5a8727..4d4fa0f505 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/Node.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/Node.java @@ -16,109 +16,160 @@ */ package org.jclouds.chef.domain; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.gson.annotations.SerializedName; -import org.jclouds.domain.JsonBall; -import org.jclouds.javax.annotation.Nullable; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty; +import java.beans.ConstructorProperties; import java.util.List; import java.util.Map; +import org.jclouds.domain.JsonBall; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.gson.annotations.SerializedName; + /** - * Sandbox object. + * Node object. * * @author Adrian Cole + * @author Ignasi Barrera */ public class Node { + public static Builder builder() { + return new Builder(); + } - private String name; - private Map normal = Maps.newLinkedHashMap(); - private Map override = Maps.newLinkedHashMap(); + public static class Builder { + private String name; + private ImmutableMap.Builder normalAttributes = ImmutableMap.builder(); + private ImmutableMap.Builder overrideAttributes = ImmutableMap.builder(); + private ImmutableMap.Builder defaultAttributes = ImmutableMap.builder(); + private ImmutableMap.Builder automaticAttributes = ImmutableMap.builder(); + private ImmutableList.Builder runList = ImmutableList.builder(); + private String environment; + + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + public Builder normalAttribute(String key, JsonBall value) { + this.normalAttributes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder normalAttributes(Map normalAttributes) { + this.normalAttributes.putAll(checkNotNull(normalAttributes, "normalAttributes")); + return this; + } + + public Builder overrideAttribute(String key, JsonBall value) { + this.overrideAttributes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder overrideAttributes(Map overrideAttributes) { + this.overrideAttributes.putAll(checkNotNull(overrideAttributes, "overrideAttributes")); + return this; + } + + public Builder defaultAttribute(String key, JsonBall value) { + this.defaultAttributes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder defaultAttributes(Map defaultAttributes) { + this.defaultAttributes.putAll(checkNotNull(defaultAttributes, "defaultAttributes")); + return this; + } + + public Builder automaticAttribute(String key, JsonBall value) { + this.automaticAttributes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder automaticAttributes(Map automaticAttribute) { + this.automaticAttributes.putAll(checkNotNull(automaticAttribute, "automaticAttribute")); + return this; + } + + public Builder runListElement(String element) { + this.runList.add(checkNotNull(element, "element")); + return this; + } + + public Builder runList(Iterable runList) { + this.runList.addAll(checkNotNull(runList, "runList")); + return this; + } + + /** + * @since Chef 0.10 + */ + public Builder environment(String environment) { + this.environment = checkNotNull(environment, "environment"); + return this; + } + + public Node build() { + return new Node(name, normalAttributes.build(), overrideAttributes.build(), defaultAttributes.build(), + automaticAttributes.build(), runList.build(), environment); + } + } + + private final String name; + @SerializedName("normal") + private final Map normalAttributes; + @SerializedName("override") + private final Map overrideAttributes; @SerializedName("default") - private Map defaultA = Maps.newLinkedHashMap(); - private Map automatic = Maps.newLinkedHashMap(); + private final Map defaultAttributes; + @SerializedName("automatic") + private final Map automaticAttributes; @SerializedName("run_list") - private List runList = Lists.newArrayList(); - - /** - * @since chef 0.10 - */ + private final List runList; @SerializedName("chef_environment") - @Nullable - private String chefEnvironment; + private final String environment; // internal @SerializedName("json_class") - private String _jsonClass = "Chef::Node"; + private final String _jsonClass = "Chef::Node"; + @SerializedName("chef_type") + private final String _chefType = "node"; - - @SerializedName("chef_type") - private String _chefType = "node"; - - public Node(String name, Map normal, Map override, - Map defaultA, Map automatic, Iterable runList) { - this(name, normal, override, defaultA, automatic, runList, null); - } - - /** - * @since chef 0.10 - */ - public Node(String name, Map normal, Map override, - Map defaultA, Map automatic, Iterable runList, - String chefEnvironment) { + @ConstructorProperties({ "name", "normal", "override", "default", "automatic", "run_list", "chef_environment" }) + protected Node(String name, @Nullable Map normalAttributes, + @Nullable Map overrideAttributes, @Nullable Map defaultAttributes, + @Nullable Map automaticAttributes, List runList, @Nullable String environment) { this.name = name; - this.chefEnvironment = chefEnvironment; - this.normal.putAll(normal); - this.override.putAll(override); - this.defaultA.putAll(defaultA); - this.automatic.putAll(automatic); - Iterables.addAll(this.runList, runList); - } - - @Override - public String toString() { - return "Node [name=" + name + ", runList=" + runList + ", normal=" + normal + ", default=" + defaultA - + ", override=" + override + ", chefEnvironment=" + chefEnvironment + ", automatic=" + automatic + "]"; - } - - public Node(String name, Iterable runList) { - this(name, runList, "_default"); - } - - /** - * @since chef 0.10 - */ - public Node(String name, Iterable runList, String chefEnvironment) { - this.name = name; - this.chefEnvironment = chefEnvironment; - Iterables.addAll(this.runList, runList); - } - - // hidden but needs to be here for json deserialization to work - Node() { - + this.environment = environment; + this.normalAttributes = copyOfOrEmpty(normalAttributes); + this.overrideAttributes = copyOfOrEmpty(overrideAttributes); + this.defaultAttributes = copyOfOrEmpty(defaultAttributes); + this.automaticAttributes = copyOfOrEmpty(automaticAttributes); + this.runList = copyOfOrEmpty(runList); } public String getName() { return name; } - public Map getNormal() { - return normal; + public Map getNormalAttributes() { + return normalAttributes; } - public Map getOverride() { - return override; + public Map getOverrideAttributes() { + return overrideAttributes; } - public Map getDefault() { - return defaultA; + public Map getDefaultAttributes() { + return defaultAttributes; } - public Map getAutomatic() { - return automatic; + public Map getAutomaticAttributes() { + return automaticAttributes; } public List getRunList() { @@ -126,10 +177,10 @@ public class Node { } /** - * @since chef 0.10 + * @since Chef 0.10 */ - public String getChefEnvironment() { - return chefEnvironment; + public String getEnvironment() { + return environment; } @Override @@ -138,13 +189,13 @@ public class Node { int result = 1; result = prime * result + ((_chefType == null) ? 0 : _chefType.hashCode()); result = prime * result + ((_jsonClass == null) ? 0 : _jsonClass.hashCode()); - result = prime * result + ((automatic == null) ? 0 : automatic.hashCode()); - result = prime * result + ((defaultA == null) ? 0 : defaultA.hashCode()); + result = prime * result + ((automaticAttributes == null) ? 0 : automaticAttributes.hashCode()); + result = prime * result + ((defaultAttributes == null) ? 0 : defaultAttributes.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((normal == null) ? 0 : normal.hashCode()); - result = prime * result + ((override == null) ? 0 : override.hashCode()); + result = prime * result + ((normalAttributes == null) ? 0 : normalAttributes.hashCode()); + result = prime * result + ((overrideAttributes == null) ? 0 : overrideAttributes.hashCode()); result = prime * result + ((runList == null) ? 0 : runList.hashCode()); - result = prime * result + ((chefEnvironment == null) ? 0 : chefEnvironment.hashCode()); + result = prime * result + ((environment == null) ? 0 : environment.hashCode()); return result; } @@ -167,42 +218,49 @@ public class Node { return false; } else if (!_jsonClass.equals(other._jsonClass)) return false; - if (automatic == null) { - if (other.automatic != null) + if (automaticAttributes == null) { + if (other.automaticAttributes != null) return false; - } else if (!automatic.equals(other.automatic)) + } else if (!automaticAttributes.equals(other.automaticAttributes)) return false; - if (defaultA == null) { - if (other.defaultA != null) + if (defaultAttributes == null) { + if (other.defaultAttributes != null) return false; - } else if (!defaultA.equals(other.defaultA)) + } else if (!defaultAttributes.equals(other.defaultAttributes)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; - if (normal == null) { - if (other.normal != null) + if (normalAttributes == null) { + if (other.normalAttributes != null) return false; - } else if (!normal.equals(other.normal)) + } else if (!normalAttributes.equals(other.normalAttributes)) return false; - if (override == null) { - if (other.override != null) + if (overrideAttributes == null) { + if (other.overrideAttributes != null) return false; - } else if (!override.equals(other.override)) + } else if (!overrideAttributes.equals(other.overrideAttributes)) return false; if (runList == null) { if (other.runList != null) return false; } else if (!runList.equals(other.runList)) return false; - if (chefEnvironment == null) { - if (other.chefEnvironment != null) + if (environment == null) { + if (other.environment != null) return false; - } else if (!chefEnvironment.equals(other.chefEnvironment)) + } else if (!environment.equals(other.environment)) return false; return true; } + @Override + public String toString() { + return "Node [name=" + name + ", runList=" + runList + ", normalAttributes=" + normalAttributes + + ", defaultAttributes=" + defaultAttributes + ", overrideAttributes=" + overrideAttributes + + ", chefEnvironment=" + environment + ", automaticAttributes=" + automaticAttributes + "]"; + } + } diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/Resource.java b/apis/chef/src/main/java/org/jclouds/chef/domain/Resource.java index 687a468a9f..15ac613604 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/Resource.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/Resource.java @@ -16,6 +16,9 @@ */ package org.jclouds.chef.domain; +import static com.google.common.base.Preconditions.*; + +import java.beans.ConstructorProperties; import java.net.URI; import java.util.Arrays; @@ -24,28 +27,69 @@ import org.jclouds.io.payloads.FilePayload; import com.google.common.primitives.Bytes; /** - * Cookbook object. + * Resource object. * * @author Adrian Cole + * @author Ignasi Barrera */ public class Resource { - - private String name; - private URI url; - private byte[] checksum; - private String path; - private String specificity; - - public Resource(FilePayload payload) { - this(payload.getRawContent().getName(), null, payload.getContentMetadata().getContentMD5(), payload - .getRawContent().getPath(), "default"); + public static Builder builder() { + return new Builder(); } - public Resource(String name, byte[] checksum, String path) { - this(name, null, checksum, path, "default"); + public static class Builder { + private String name; + private URI url; + private byte[] checksum; + private String path; + private String specificity = "default"; + + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + public Builder url(URI url) { + this.url = checkNotNull(url, "url"); + return this; + } + + public Builder checksum(byte[] checksum) { + this.checksum = checkNotNull(checksum, "checksum"); + return this; + } + + public Builder path(String path) { + this.path = checkNotNull(path, "path"); + return this; + } + + public Builder specificity(String specificity) { + this.specificity = checkNotNull(specificity, "specificity"); + return this; + } + + public Builder fromPayload(FilePayload payload) { + checkNotNull(payload, "payload"); + this.name(payload.getRawContent().getName()); + this.checksum(payload.getContentMetadata().getContentMD5()); + this.path(payload.getRawContent().getPath()); + return this; + } + + public Resource build() { + return new Resource(name, url, checksum, path, specificity); + } } - public Resource(String name, URI url, byte[] checksum, String path, String specificity) { + private final String name; + private final URI url; + private final byte[] checksum; + private final String path; + private final String specificity; + + @ConstructorProperties({ "name", "url", "checksum", "path", "specificity" }) + protected Resource(String name, URI url, byte[] checksum, String path, String specificity) { this.name = name; this.url = url; this.checksum = checksum; @@ -53,10 +97,6 @@ public class Resource { this.specificity = specificity; } - // hidden but needs to be here for json deserialization to work - Resource() { - } - public String getName() { return name; } @@ -130,4 +170,3 @@ public class Resource { } } - diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/Role.java b/apis/chef/src/main/java/org/jclouds/chef/domain/Role.java index 95d91f1c64..1b73609026 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/Role.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/Role.java @@ -16,55 +16,106 @@ */ package org.jclouds.chef.domain; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty; + +import java.beans.ConstructorProperties; import java.util.List; import java.util.Map; import org.jclouds.domain.JsonBall; +import org.jclouds.javax.annotation.Nullable; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.gson.annotations.SerializedName; /** - * Sandbox object. + * Role object. * * @author Adrian Cole + * @author Ignasi Barrera */ public class Role { + public static Builder builder() { + return new Builder(); + } - private String name; - private String description; + public static class Builder { + private String name; + private String description; + private ImmutableMap.Builder overrideAttributes = ImmutableMap.builder(); + private ImmutableMap.Builder defaultAttributes = ImmutableMap.builder(); + private ImmutableList.Builder runList = ImmutableList.builder(); + + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + public Builder description(String description) { + this.description = checkNotNull(description, "description"); + return this; + } + + public Builder overrideAttribute(String key, JsonBall value) { + this.overrideAttributes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder overrideAttributes(Map overrideAttributes) { + this.overrideAttributes.putAll(checkNotNull(overrideAttributes, "overrideAttributes")); + return this; + } + + public Builder defaultAttribute(String key, JsonBall value) { + this.defaultAttributes.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder defaultAttributes(Map defaultAttributes) { + this.defaultAttributes.putAll(checkNotNull(defaultAttributes, "defaultAttributes")); + return this; + } + + public Builder runListElement(String element) { + this.runList.add(checkNotNull(element, "element")); + return this; + } + + public Builder runList(Iterable runList) { + this.runList.addAll(checkNotNull(runList, "runList")); + return this; + } + + public Role build() { + return new Role(name, description, defaultAttributes.build(), runList.build(), overrideAttributes.build()); + } + } + + private final String name; + private final String description; @SerializedName("override_attributes") - private Map override = Maps.newLinkedHashMap(); + private final Map overrideAttributes; @SerializedName("default_attributes") - private Map defaultA = Maps.newLinkedHashMap(); + private final Map defaultAttributes; @SerializedName("run_list") - private List runList = Lists.newArrayList(); + private final List runList; // internal @SerializedName("json_class") - private String _jsonClass = "Chef::Role"; + private final String _jsonClass = "Chef::Role"; @SerializedName("chef_type") - private String _chefType = "role"; + private final String _chefType = "role"; - public Role(String name, String description, Map defaultA, List runList, - Map override) { + @ConstructorProperties({ "name", "description", "default_attributes", "run_list", "override_attributes" }) + protected Role(String name, String description, @Nullable Map defaultAttributes, + @Nullable List runList, @Nullable Map overrideAttributes) { this.name = name; this.description = description; - this.defaultA = defaultA; - this.runList = runList; - this.override = override; - } - - public Role(String name, Iterable runList) { - this.name = name; - Iterables.addAll(this.runList, runList); - } - - // hidden but needs to be here for json deserialization to work - Role() { - + this.defaultAttributes = copyOfOrEmpty(defaultAttributes); + this.runList = copyOfOrEmpty(runList); + this.overrideAttributes = copyOfOrEmpty(overrideAttributes); } public String getName() { @@ -75,12 +126,12 @@ public class Role { return description; } - public Map getOverride() { - return override; + public Map getOverrideAttributes() { + return overrideAttributes; } - public Map getDefault() { - return defaultA; + public Map getDefaultAttributes() { + return defaultAttributes; } public List getRunList() { @@ -93,10 +144,10 @@ public class Role { int result = 1; result = prime * result + ((_chefType == null) ? 0 : _chefType.hashCode()); result = prime * result + ((_jsonClass == null) ? 0 : _jsonClass.hashCode()); - result = prime * result + ((defaultA == null) ? 0 : defaultA.hashCode()); + result = prime * result + ((defaultAttributes == null) ? 0 : defaultAttributes.hashCode()); result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((override == null) ? 0 : override.hashCode()); + result = prime * result + ((overrideAttributes == null) ? 0 : overrideAttributes.hashCode()); result = prime * result + ((runList == null) ? 0 : runList.hashCode()); return result; } @@ -120,10 +171,10 @@ public class Role { return false; } else if (!_jsonClass.equals(other._jsonClass)) return false; - if (defaultA == null) { - if (other.defaultA != null) + if (defaultAttributes == null) { + if (other.defaultAttributes != null) return false; - } else if (!defaultA.equals(other.defaultA)) + } else if (!defaultAttributes.equals(other.defaultAttributes)) return false; if (description == null) { if (other.description != null) @@ -135,10 +186,10 @@ public class Role { return false; } else if (!name.equals(other.name)) return false; - if (override == null) { - if (other.override != null) + if (overrideAttributes == null) { + if (other.overrideAttributes != null) return false; - } else if (!override.equals(other.override)) + } else if (!overrideAttributes.equals(other.overrideAttributes)) return false; if (runList == null) { if (other.runList != null) @@ -150,8 +201,8 @@ public class Role { @Override public String toString() { - return "[name=" + name + ", description=" + description + ", defaultA=" + defaultA + ", override=" + override - + ", runList=" + runList + "]"; + return "Role [name=" + name + ", description=" + description + ", defaultAttributes=" + defaultAttributes + + ", overrideAttributes=" + overrideAttributes + ", runList=" + runList + "]"; } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/Sandbox.java b/apis/chef/src/main/java/org/jclouds/chef/domain/Sandbox.java index 98c8c96e71..774aa4a4dd 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/Sandbox.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/Sandbox.java @@ -16,49 +16,104 @@ */ package org.jclouds.chef.domain; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty; + +import java.beans.ConstructorProperties; import java.util.Date; import java.util.Set; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.collect.ImmutableSet; import com.google.gson.annotations.SerializedName; /** * Sandbox object. * * @author Adrian Cole + * @author Ignasi Barrera */ public class Sandbox { + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String rev; + private boolean isCompleted; + private Date createTime; + private ImmutableSet.Builder checksums = ImmutableSet.builder(); + private String name; + private String guid; + + public Builder rev(String rev) { + this.rev = checkNotNull(rev, "rev"); + return this; + } + + public Builder isCompleted(boolean isCompleted) { + this.isCompleted = isCompleted; + return this; + } + + public Builder createTime(Date createTime) { + this.createTime = createTime; + return this; + } + + public Builder checksum(String checksum) { + this.checksums.add(checkNotNull(checksum, "checksum")); + return this; + } + + public Builder checksums(Iterable checksums) { + this.checksums.addAll(checkNotNull(checksums, "checksums")); + return this; + } + + public Builder name(String name) { + this.name = checkNotNull(name, "name"); + return this; + } + + public Builder guid(String guid) { + this.guid = checkNotNull(guid, "guid"); + return this; + } + + public Sandbox build() { + return new Sandbox(rev, isCompleted, createTime, checksums.build(), name, guid); + } + } @SerializedName("_rev") - private String rev; + private final String rev; @SerializedName("is_completed") - private boolean isCompleted; + private final boolean isCompleted; @SerializedName("create_time") - private Date createTime; - private Set checksums = Sets.newLinkedHashSet(); - private String name; - private String guid; + private final Date createTime; + private final Set checksums; + private final String name; + private final String guid; // internal @SerializedName("json_class") - private String _jsonClass = "Chef::Sandbox"; + private final String _jsonClass = "Chef::Sandbox"; @SerializedName("chef_type") - private String _chefType = "sandbox"; + private final String _chefType = "sandbox"; - public Sandbox(String rev, boolean isCompleted, Date createTime, Iterable checksums, String name, String guid) { + @ConstructorProperties({ "_rev", "is_completed", "create_time", "checksums", "name", "guid" }) + protected Sandbox(String rev, boolean isCompleted, Date createTime, @Nullable Set checksums, String name, + String guid) { this.rev = rev; this.isCompleted = isCompleted; this.createTime = createTime; - Iterables.addAll(this.checksums, checksums); + this.checksums = copyOfOrEmpty(checksums); this.name = name; this.guid = guid; } - public Sandbox() { - - } - public String getRev() { return rev; } @@ -141,4 +196,3 @@ public class Sandbox { + isCompleted + ", name=" + name + ", rev=" + rev + "]"; } } - diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/SearchResult.java b/apis/chef/src/main/java/org/jclouds/chef/domain/SearchResult.java index 91222a2b35..1e2cced85a 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/SearchResult.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/SearchResult.java @@ -21,11 +21,13 @@ import java.util.LinkedHashSet; import com.google.common.collect.Iterables; /** + * A result of a search. * * @author Adrian Cole - * + * @author Ignasi Barrera */ public class SearchResult extends LinkedHashSet { + private static final long serialVersionUID = 4000610660948065287L; private long start; SearchResult() { @@ -36,8 +38,6 @@ public class SearchResult extends LinkedHashSet { Iterables.addAll(this, results); } - private static final long serialVersionUID = 4000610660948065287L; - /** * * @return the result position this started from from @@ -47,4 +47,3 @@ public class SearchResult extends LinkedHashSet { } } - diff --git a/apis/chef/src/main/java/org/jclouds/chef/domain/UploadSandbox.java b/apis/chef/src/main/java/org/jclouds/chef/domain/UploadSandbox.java index f9bd6f1e9c..868c147dea 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/domain/UploadSandbox.java +++ b/apis/chef/src/main/java/org/jclouds/chef/domain/UploadSandbox.java @@ -16,31 +16,70 @@ */ package org.jclouds.chef.domain; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.chef.util.CollectionUtils.copyOfOrEmpty; + +import java.beans.ConstructorProperties; import java.net.URI; import java.util.List; import java.util.Map; -import com.google.common.collect.Maps; +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.collect.ImmutableMap; import com.google.gson.annotations.SerializedName; /** + * An upload sandbox. * * @author Adrian Cole + * @author Ignasi Barrera */ public class UploadSandbox { - private URI uri; - private Map, ChecksumStatus> checksums = Maps.newLinkedHashMap(); - @SerializedName("sandbox_id") - private String sandboxId; - - public UploadSandbox(URI uri, Map, ChecksumStatus> checksums, String sandboxId) { - this.uri = uri; - this.checksums.putAll(checksums); - this.sandboxId = sandboxId; + public static Builder builder() { + return new Builder(); } - public UploadSandbox() { + public static class Builder { + private URI uri; + private ImmutableMap.Builder, ChecksumStatus> checksums = ImmutableMap.builder(); + private String sandboxId; + public Builder uri(URI uri) { + this.uri = checkNotNull(uri, "uri"); + return this; + } + + public Builder checksum(List key, ChecksumStatus value) { + this.checksums.put(checkNotNull(key, "key"), checkNotNull(value, "value")); + return this; + } + + public Builder checksums(Map, ChecksumStatus> checksums) { + this.checksums.putAll(checkNotNull(checksums, "checksums")); + return this; + } + + public Builder sandboxId(String sandboxId) { + this.sandboxId = checkNotNull(sandboxId, "sandboxId"); + return this; + } + + public UploadSandbox build() { + return new UploadSandbox(uri, checksums.build(), sandboxId); + } + } + + private final URI uri; + private final Map, ChecksumStatus> checksums; + @SerializedName("sandbox_id") + private final String sandboxId; + + @ConstructorProperties({ "uri", "checksums", "sandbox_id" }) + protected UploadSandbox(URI uri, @Nullable Map, ChecksumStatus> checksums, String sandboxId) { + this.uri = uri; + this.checksums = copyOfOrEmpty(checksums); + this.sandboxId = sandboxId; } public URI getUri() { @@ -94,8 +133,7 @@ public class UploadSandbox { @Override public String toString() { - return "UploadSite [checksums=" + checksums + ", id=" + sandboxId + ", uri=" + uri + "]"; + return "UploadSandbox [checksums=" + checksums + ", id=" + sandboxId + ", uri=" + uri + "]"; } } - diff --git a/apis/chef/src/main/java/org/jclouds/chef/functions/ClientForGroup.java b/apis/chef/src/main/java/org/jclouds/chef/functions/ClientForGroup.java index f51b7a21da..a9c1c33ed7 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/functions/ClientForGroup.java +++ b/apis/chef/src/main/java/org/jclouds/chef/functions/ClientForGroup.java @@ -49,7 +49,12 @@ public class ClientForGroup implements Function { String clientName = findNextClientName(chefApi.listClients(), from + "-client-%02d"); Client client = chefApi.createClient(clientName); // response from create only includes the key - return new Client(null, null, clientName, clientName, false, client.getPrivateKey()); + return Client.builder() // + .clientname(clientName) // + .name(clientName) // + .isValidator(false) // + .privateKey(client.getPrivateKey()) // + .build(); } private static String findNextClientName(Set clients, String pattern) { diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java index 28d4e1bcdb..a3ef7c25bc 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java @@ -82,7 +82,7 @@ public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClie }), and(notNull(), new Predicate() { @Override public boolean apply(Node input) { - JsonBall dateLong = input.getAutomatic().get("ohai_time"); + JsonBall dateLong = input.getAutomaticAttributes().get("ohai_time"); if (dateLong == null) return true; Calendar nodeUpdate = Calendar.getInstance(); diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java index 54de5e71a2..d6336b2b79 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java @@ -61,14 +61,25 @@ public class CreateNodeAndPopulateAutomaticAttributesImpl implements CreateNodeA @Override public Node execute(Node node) { logger.trace("creating node %s", node.getName()); - node.getAutomatic().putAll(automaticSupplier.get()); - chef.createNode(node); - logger.debug("created node %s", node.getName()); + Node withAutomatic = Node.builder() // + .name(node.getName()) // + .normalAttributes(node.getNormalAttributes()) // + .overrideAttributes(node.getOverrideAttributes()) // + .defaultAttributes(node.getDefaultAttributes()) // + .automaticAttributes(node.getAutomaticAttributes()) // + .automaticAttributes(automaticSupplier.get()) // + .runList(node.getRunList()) // + .environment(node.getEnvironment()) // + .build(); + + + chef.createNode(withAutomatic); + logger.debug("created node %s", withAutomatic.getName()); return node; } @Override public Node execute(String nodeName, Iterable runList) { - return execute(new Node(nodeName, runList, "_default")); + return execute(Node.builder().name(nodeName).runList(runList).environment("_default").build()); } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java index e1af5970a2..4d9bea4644 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java @@ -61,9 +61,17 @@ public class UpdateAutomaticAttributesOnNodeImpl implements UpdateAutomaticAttri public void execute(String nodeName) { logger.trace("updating node %s", nodeName); Node node = chef.getNode(nodeName); - Node mutable = new Node(node.getName(), node.getNormal(), node.getOverride(), node.getDefault(), - automaticSupplier.get(), node.getRunList(), node.getChefEnvironment()); - chef.updateNode(mutable); + Node updated = Node.builder() // + .name(node.getName()) // + .normalAttributes(node.getNormalAttributes()) // + .overrideAttributes(node.getOverrideAttributes()) // + .defaultAttributes(node.getDefaultAttributes()) // + .automaticAttributes(automaticSupplier.get()) // + .runList(node.getRunList()) // + .environment(node.getEnvironment()) // + .build(); + + chef.updateNode(updated); logger.debug("updated node %s", nodeName); } } diff --git a/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApi.java b/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApi.java index 70a17d91d6..908ae2fcd5 100644 --- a/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApi.java +++ b/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApi.java @@ -103,11 +103,6 @@ public class TransientChefApi implements ChefApi { this.closer = checkNotNull(closer, "closer"); } - @Override - public boolean clientExists(String clientname) { - throw new UnsupportedOperationException(); - } - @Override public Sandbox commitSandbox(String id, boolean isCompleted) { throw new UnsupportedOperationException(); @@ -145,16 +140,6 @@ public class TransientChefApi implements ChefApi { throw new UnsupportedOperationException(); } - @Override - public boolean databagExists(String databagName) { - return databags.containerExists(databagName); - } - - @Override - public boolean databagItemExists(String databagName, String databagItemId) { - return databags.blobExists(databagName, databagItemId); - } - @Override public Client deleteClient(String clientname) { throw new UnsupportedOperationException(); @@ -262,16 +247,6 @@ public class TransientChefApi implements ChefApi { throw new UnsupportedOperationException(); } - @Override - public boolean nodeExists(String nodename) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean roleExists(String rolename) { - throw new UnsupportedOperationException(); - } - @Override public SearchResult searchClients() { throw new UnsupportedOperationException(); diff --git a/apis/chef/src/main/java/org/jclouds/chef/util/CollectionUtils.java b/apis/chef/src/main/java/org/jclouds/chef/util/CollectionUtils.java new file mode 100644 index 0000000000..0e62804323 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/util/CollectionUtils.java @@ -0,0 +1,71 @@ +/* + * 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.util; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +/** + * Utility methods to work with collections. + * + * @author Ignasi Barrera + */ +public class CollectionUtils { + + /** + * Creates an immutable list with the elements of the given list. If the + * input list is null, it returns an empty list. + * + * @param input + * The list used to build the immutable one. + * @return An immutable list with the elements of the given list. + */ + public static ImmutableList copyOfOrEmpty(@Nullable List input) { + return input == null ? ImmutableList. of() : ImmutableList.copyOf(input); + } + + /** + * Creates an immutable set with the elements of the given set. If the input + * set is null, it returns an empty set. + * + * @param input + * The set used to build the immutable one. + * @return An immutable set with the elements of the given set. + */ + public static ImmutableSet copyOfOrEmpty(@Nullable Set input) { + return input == null ? ImmutableSet. of() : ImmutableSet.copyOf(input); + } + + /** + * Creates an immutable map with the elements of the given map. If the input + * map is null, it returns an empty map. + * + * @param input + * The map used to build the immutable one. + * @return An immutable map with the elements of the given map. + */ + public static ImmutableMap copyOfOrEmpty(@Nullable Map input) { + return input == null ? ImmutableMap. of() : ImmutableMap.copyOf(input); + } +} diff --git a/apis/chef/src/test/java/org/jclouds/chef/ChefApiTest.java b/apis/chef/src/test/java/org/jclouds/chef/ChefApiTest.java index bdb059a2f0..33d6a98a28 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/ChefApiTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/ChefApiTest.java @@ -28,7 +28,6 @@ import java.util.Set; import org.jclouds.Constants; import org.jclouds.Fallbacks.EmptySetOnNotFoundOr404; -import org.jclouds.Fallbacks.FalseOnNotFoundOr404; import org.jclouds.Fallbacks.NullOnNotFoundOr404; import org.jclouds.Fallbacks.VoidOnNotFoundOr404; import org.jclouds.apis.ApiMetadata; @@ -55,7 +54,6 @@ import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseJson; import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReturnInputStream; -import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.io.Payload; import org.jclouds.io.payloads.StringPayload; import org.jclouds.reflect.Invocation; @@ -172,7 +170,7 @@ public class ChefApiTest extends BaseAsyncApiTest { Invokable method = method(ChefApi.class, "updateCookbook", String.class, String.class, CookbookVersion.class); GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, - ImmutableList. of("cookbook", "1.0.1", new CookbookVersion("cookbook", "1.0.1")))); + ImmutableList. of("cookbook", "1.0.1", CookbookVersion.builder("cookbook", "1.0.1").build()))); assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/cookbooks/cookbook/1.0.1 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION @@ -229,22 +227,6 @@ public class ChefApiTest extends BaseAsyncApiTest { } - public void testApiExists() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(ChefApi.class, "clientExists", String.class); - GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList. of("api"))); - assertRequestLineEquals(httpRequest, "HEAD http://localhost:4000/clients/api HTTP/1.1"); - assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION - + "-test\n"); - assertPayloadEquals(httpRequest, null, null, false); - - assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertFallbackClassEquals(method, FalseOnNotFoundOr404.class); - - checkFilters(httpRequest); - - } - public void testDeleteClient() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "deleteClient", String.class); GeneratedHttpRequest httpRequest = processor @@ -331,21 +313,6 @@ public class ChefApiTest extends BaseAsyncApiTest { } - public void testNodeExists() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(ChefApi.class, "nodeExists", String.class); - GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList. of("node"))); - assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION - + "-test\n"); - assertPayloadEquals(httpRequest, null, null, false); - - assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertFallbackClassEquals(method, FalseOnNotFoundOr404.class); - - checkFilters(httpRequest); - - } - public void testDeleteNode() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "deleteNode", String.class); GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList. of("node"))); @@ -364,8 +331,10 @@ public class ChefApiTest extends BaseAsyncApiTest { public void testCreateNode() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "createNode", Node.class); - GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, - ImmutableList. of(new Node("testnode", ImmutableSet.of("recipe[java]"), "_default")))); + GeneratedHttpRequest httpRequest = processor.apply(Invocation.create( + method, + ImmutableList. of(Node.builder().name("testnode").runListElement("recipe[java]") + .environment("_default").build()))); assertRequestLineEquals(httpRequest, "POST http://localhost:4000/nodes HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION @@ -385,8 +354,10 @@ public class ChefApiTest extends BaseAsyncApiTest { public void testUpdateNode() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "updateNode", Node.class); - GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, - ImmutableList. of(new Node("testnode", ImmutableSet.of("recipe[java]"), "_default")))); + GeneratedHttpRequest httpRequest = processor.apply(Invocation.create( + method, + ImmutableList. of(Node.builder().name("testnode").runListElement("recipe[java]") + .environment("_default").build()))); assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/nodes/testnode HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION @@ -421,22 +392,6 @@ public class ChefApiTest extends BaseAsyncApiTest { } - public void testRoleExists() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(ChefApi.class, "roleExists", String.class); - GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList. of("role"))); - assertRequestLineEquals(httpRequest, "HEAD http://localhost:4000/roles/role HTTP/1.1"); - assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION - + "-test\n"); - assertPayloadEquals(httpRequest, null, null, false); - - assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertFallbackClassEquals(method, FalseOnNotFoundOr404.class); - - checkFilters(httpRequest); - - } - public void testDeleteRole() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "deleteRole", String.class); GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, ImmutableList. of("role"))); @@ -456,7 +411,7 @@ public class ChefApiTest extends BaseAsyncApiTest { public void testCreateRole() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "createRole", Role.class); GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, - ImmutableList. of(new Role("testrole", ImmutableSet.of("recipe[java]"))))); + ImmutableList. of(Role.builder().name("testrole").runListElement("recipe[java]").build()))); assertRequestLineEquals(httpRequest, "POST http://localhost:4000/roles HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION @@ -476,7 +431,7 @@ public class ChefApiTest extends BaseAsyncApiTest { public void testUpdateRole() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "updateRole", Role.class); GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, - ImmutableList. of(new Role("testrole", ImmutableSet.of("recipe[java]"))))); + ImmutableList. of(Role.builder().name("testrole").runListElement("recipe[java]").build()))); assertRequestLineEquals(httpRequest, "PUT http://localhost:4000/roles/testrole HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION @@ -510,23 +465,6 @@ public class ChefApiTest extends BaseAsyncApiTest { } - public void testDatabagExists() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(ChefApi.class, "databagExists", String.class); - GeneratedHttpRequest httpRequest = processor - .apply(Invocation.create(method, ImmutableList. of("databag"))); - assertRequestLineEquals(httpRequest, "HEAD http://localhost:4000/data/databag HTTP/1.1"); - assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION - + "-test\n"); - assertPayloadEquals(httpRequest, null, null, false); - - assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertFallbackClassEquals(method, FalseOnNotFoundOr404.class); - - checkFilters(httpRequest); - - } - public void testDeleteDatabag() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "deleteDatabag", String.class); GeneratedHttpRequest httpRequest = processor @@ -578,23 +516,6 @@ public class ChefApiTest extends BaseAsyncApiTest { } - public void testDatabagItemExists() throws SecurityException, NoSuchMethodException, IOException { - Invokable method = method(ChefApi.class, "databagItemExists", String.class, String.class); - GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, - ImmutableList. of("name", "databagItem"))); - assertRequestLineEquals(httpRequest, "HEAD http://localhost:4000/data/name/databagItem HTTP/1.1"); - assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION - + "-test\n"); - assertPayloadEquals(httpRequest, null, null, false); - - assertResponseParserClassEquals(method, httpRequest, ReturnTrueIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertFallbackClassEquals(method, FalseOnNotFoundOr404.class); - - checkFilters(httpRequest); - - } - public void testDeleteDatabagItem() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "deleteDatabagItem", String.class, String.class); GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, @@ -891,7 +812,7 @@ public class ChefApiTest extends BaseAsyncApiTest { public void testGetResourceContents() throws SecurityException, NoSuchMethodException, IOException { Invokable method = method(ChefApi.class, "getResourceContents", Resource.class); GeneratedHttpRequest httpRequest = processor.apply(Invocation.create(method, - ImmutableList. of(new Resource("test", URI.create("http://foo/bar"), new byte[] {}, null, null)))); + ImmutableList. of(Resource.builder().name("test").url(URI.create("http://foo/bar")).build()))); assertRequestLineEquals(httpRequest, "GET http://foo/bar HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nX-Chef-Version: " + ChefApi.VERSION diff --git a/apis/chef/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java b/apis/chef/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java index c703090462..282e68e4a8 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/binders/BindHexEncodedMD5sToJsonPayloadTest.java @@ -17,6 +17,7 @@ package org.jclouds.chef.binders; import static com.google.common.io.BaseEncoding.base16; +import static com.google.common.primitives.Bytes.asList; import static org.testng.Assert.assertEquals; import java.io.File; @@ -56,11 +57,10 @@ public class BindHexEncodedMD5sToJsonPayloadTest { binder.bindToRequest(request, new File("foo")); } - @Test(enabled = false) public void testCorrect() { HttpRequest request = HttpRequest.builder().method(HttpMethod.POST).endpoint("http://localhost").build(); binder.bindToRequest(request, - ImmutableSet.of(base16().lowerCase().decode("abddef"), base16().lowerCase().decode("1234"))); + ImmutableSet.of(asList(base16().lowerCase().decode("abddef")), asList(base16().lowerCase().decode("1234")))); assertEquals(request.getPayload().getRawContent(), "{\"checksums\":{\"abddef\":null,\"1234\":null}}"); } diff --git a/apis/chef/src/test/java/org/jclouds/chef/config/ChefParserModuleTest.java b/apis/chef/src/test/java/org/jclouds/chef/config/ChefParserModuleTest.java new file mode 100644 index 0000000000..76db79144b --- /dev/null +++ b/apis/chef/src/test/java/org/jclouds/chef/config/ChefParserModuleTest.java @@ -0,0 +1,95 @@ +/* + * 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.config; + +import static com.google.common.base.Objects.equal; +import static org.testng.Assert.assertEquals; + +import java.lang.reflect.Type; +import java.util.Map; + +import org.jclouds.chef.config.ChefParserModule.KeepLastRepeatedKeyMapTypeAdapterFactory; +import org.testng.annotations.Test; + +import com.google.common.base.Objects; +import com.google.common.collect.ImmutableMap; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +/** + * Unit tests for the {@link ChefParserModule} class. + * + * @author Ignasi Barrera + */ +@Test(groups = "unit", testName = "ChefParserModuleTest") +public class ChefParserModuleTest { + + private static class KeyValue { + private final String key; + private final String value; + + private KeyValue(String key, String value) { + this.key = key; + this.value = value; + } + + @Override + public int hashCode() { + return Objects.hashCode(key, value); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + KeyValue that = KeyValue.class.cast(obj); + return equal(this.key, that.key) && equal(this.value, that.value); + } + } + + private Gson map = new GsonBuilder().registerTypeAdapterFactory(new KeepLastRepeatedKeyMapTypeAdapterFactory()) + .create(); + private Type mapType = new TypeToken>() { + private static final long serialVersionUID = 1L; + }.getType(); + private Type mapkeyValueType = new TypeToken>() { + private static final long serialVersionUID = 1L; + }.getType(); + + public void testKeepLastRepeatedKeyMapTypeAdapter() { + Map noNulls = map.fromJson("{\"value\":\"a test string!\"}", mapType); + assertEquals(noNulls, ImmutableMap.of("value", "a test string!")); + Map withNull = map.fromJson("{\"value\":null}", mapType); + assertEquals(withNull, ImmutableMap.of()); + Map withEmpty = map.fromJson("{\"value\":\"\"}", mapType); + assertEquals(withEmpty, ImmutableMap.of("value", "")); + Map keyValues = map.fromJson( + "{\"i-foo\":{\"key\":\"i-foo\",\"value\":\"foo\"},\"i-bar\":{\"key\":\"i-bar\",\"value\":\"bar\"}}", + mapkeyValueType); + assertEquals(keyValues, + ImmutableMap.of("i-foo", new KeyValue("i-foo", "foo"), "i-bar", new KeyValue("i-bar", "bar"))); + Map duplicates = map + .fromJson( + "{\"i-foo\":{\"key\":\"i-foo\",\"value\":\"foo\", \"value\":\"foo2\"},\"i-bar\":{\"key\":\"i-bar\",\"value\":\"bar\",\"value\":\"bar2\"}}", + mapkeyValueType); + assertEquals(duplicates, + ImmutableMap.of("i-foo", new KeyValue("i-foo", "foo2"), "i-bar", new KeyValue("i-bar", "bar2"))); + } +} diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java index 6fd744969a..355d9a4907 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseClientFromJsonTest.java @@ -79,8 +79,8 @@ public class ParseClientFromJsonTest { public void test() throws IOException { - Client user = new Client(certificate, "jclouds", "adriancole-jcloudstest", "adriancole-jcloudstest", false, - privateKey); + Client user = Client.builder().certificate(certificate).orgname("jclouds").clientname("adriancole-jcloudstest") + .name("adriancole-jcloudstest").isValidator(false).privateKey(privateKey).build(); byte[] encrypted = ByteStreams.toByteArray(new RSAEncryptingPayload(Payloads.newPayload("fooya"), user .getCertificate().getPublicKey())); diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionFromJsonv10Test.java b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionFromJsonv10Test.java index e806fa2c6a..987e45ac17 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionFromJsonv10Test.java +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionFromJsonv10Test.java @@ -31,12 +31,11 @@ import org.jclouds.rest.annotations.ApiVersion; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; -@Test(groups = {"unit"}, singleThreaded = true) +@Test(groups = { "unit" }, singleThreaded = true) public class ParseCookbookDefinitionFromJsonv10Test { private ParseCookbookDefinitionFromJsonv10 handler; @@ -54,6 +53,13 @@ public class ParseCookbookDefinitionFromJsonv10Test { } public void testCookbokDefinitionParsing() throws URISyntaxException { + CookbookDefinition.Version v510 = CookbookDefinition.Version.builder() + .url(new URI("http://localhost:4000/cookbooks/apache2/5.1.0")).version("5.1.0").build(); + CookbookDefinition.Version v420 = CookbookDefinition.Version.builder() + .url(new URI("http://localhost:4000/cookbooks/apache2/4.2.0")).version("4.2.0").build(); + CookbookDefinition definition = CookbookDefinition.builder() + .url(new URI("http://localhost:4000/cookbooks/apache2")).version(v510).version(v420).build(); + assertEquals(handler.apply(HttpResponse .builder() .statusCode(200) @@ -63,9 +69,6 @@ public class ParseCookbookDefinitionFromJsonv10Test { + "\"versions\" => [" + "{\"url\" => \"http://localhost:4000/cookbooks/apache2/5.1.0\"," + "\"version\" => \"5.1.0\"}," + "{\"url\" => \"http://localhost:4000/cookbooks/apache2/4.2.0\"," - + "\"version\" => \"4.2.0\"}" + "]" + "}" + "}").build()), - new CookbookDefinition(new URI("http://localhost:4000/cookbooks/apache2"), - ImmutableSet.of(new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/apache2/5.1.0"), "5.1.0"), - new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/apache2/4.2.0"), "4.2.0")))); + + "\"version\" => \"4.2.0\"}" + "]" + "}" + "}").build()), definition); } } diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10Test.java b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10Test.java index 95b26ea2b9..d2cc882edf 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10Test.java +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookDefinitionListFromJsonv10Test.java @@ -54,6 +54,20 @@ public class ParseCookbookDefinitionListFromJsonv10Test { } public void testCookbokDefinitionListParsing() throws URISyntaxException { + CookbookDefinition.Version v510 = CookbookDefinition.Version.builder() + .url(new URI("http://localhost:4000/cookbooks/apache2/5.1.0")).version("5.1.0").build(); + CookbookDefinition.Version v420 = CookbookDefinition.Version.builder() + .url(new URI("http://localhost:4000/cookbooks/apache2/4.2.0")).version("4.2.0").build(); + CookbookDefinition apache2 = CookbookDefinition.builder() + .url(new URI("http://localhost:4000/cookbooks/apache2")).version(v510).version(v420).build(); + + CookbookDefinition.Version v100 = CookbookDefinition.Version.builder() + .url(new URI("http://localhost:4000/cookbooks/nginx/1.0.0")).version("1.0.0").build(); + CookbookDefinition.Version v130 = CookbookDefinition.Version.builder() + .url(new URI("http://localhost:4000/cookbooks/nginx/0.3.0")).version("0.3.0").build(); + CookbookDefinition nginx = CookbookDefinition.builder() + .url(new URI("http://localhost:4000/cookbooks/nginx")).version(v100).version(v130).build(); + assertEquals(handler.apply(HttpResponse .builder() .statusCode(200) @@ -73,11 +87,6 @@ public class ParseCookbookDefinitionListFromJsonv10Test { + "\"version\" => \"0.3.0\"}" + "]}" + "}").build()), - ImmutableSet.of(new CookbookDefinition(new URI("http://localhost:4000/cookbooks/apache2"), - ImmutableSet.of(new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/apache2/5.1.0"), "5.1.0"), - new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/apache2/4.2.0"), "4.2.0"))), - new CookbookDefinition(new URI("http://localhost:4000/cookbooks/nginx"), - ImmutableSet.of(new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/nginx/1.0.0"), "1.0.0"), - new CookbookDefinition.Version(new URI("http://localhost:4000/cookbooks/nginx/0.3.0"), "0.3.0"))))); + ImmutableSet.of(apache2, nginx)); } } diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java index f5d0f1ff77..c1f21dec47 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseCookbookVersionFromJsonTest.java @@ -24,7 +24,6 @@ import java.net.URI; import org.jclouds.chef.ChefApi; import org.jclouds.chef.config.ChefParserModule; -import org.jclouds.chef.domain.Attribute; import org.jclouds.chef.domain.CookbookVersion; import org.jclouds.chef.domain.Metadata; import org.jclouds.chef.domain.Resource; @@ -36,8 +35,6 @@ import org.jclouds.rest.annotations.ApiVersion; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -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.Injector; @@ -48,6 +45,7 @@ import com.google.inject.TypeLiteral; * Tests behavior of {@code ParseCookbookVersionFromJson} * * @author Adrian Cole + * @author Ignasi Barrera */ @Test(groups = { "unit" }, singleThreaded = true) public class ParseCookbookVersionFromJsonTest { @@ -70,7 +68,6 @@ public class ParseCookbookVersionFromJsonTest { })); } - @Test(enabled = false) public void testBrew() throws IOException { CookbookVersion cookbook = handler.apply(HttpResponse.builder().statusCode(200).message("ok") .payload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/brew-cookbook.json")).build()); @@ -79,7 +76,6 @@ public class ParseCookbookVersionFromJsonTest { handler.apply(HttpResponse.builder().statusCode(200).message("ok").payload(json.toJson(cookbook)).build())); } - @Test(enabled = false) public void testTomcat() { CookbookVersion cookbook = handler.apply(HttpResponse.builder().statusCode(200).message("ok") .payload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/tomcat-cookbook.json")).build()); @@ -88,7 +84,6 @@ public class ParseCookbookVersionFromJsonTest { handler.apply(HttpResponse.builder().statusCode(200).message("ok").payload(json.toJson(cookbook)).build())); } - @Test(enabled = false) public void testMysql() throws IOException { CookbookVersion cookbook = handler.apply(HttpResponse.builder().statusCode(200).message("ok") .payload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/mysql-cookbook.json")).build()); @@ -97,44 +92,41 @@ public class ParseCookbookVersionFromJsonTest { handler.apply(HttpResponse.builder().statusCode(200).message("ok").payload(json.toJson(cookbook)).build())); } - @Test(enabled = false) public void testApache() { + CookbookVersion fromJson = handler.apply(HttpResponse.builder().statusCode(200).message("ok") + .payload(ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/apache-chef-demo-cookbook.json")) + .build()); - assertEquals( - handler.apply(HttpResponse - .builder() - .statusCode(200) - .message("ok") - .payload( - ParseCookbookVersionFromJsonTest.class.getResourceAsStream("/apache-chef-demo-cookbook.json")) - .build()), - new CookbookVersion( - "apache-chef-demo-0.0.0", - ImmutableSet. of(), - ImmutableSet. of(), - ImmutableSet. of(), - new Metadata("Apache v2.0", "Your Name", ImmutableMap. of(), ImmutableMap - . of(), "youremail@example.com", ImmutableMap. of(), - "A fabulous new cookbook", ImmutableMap. of(), ImmutableMap - . of(), "0.0.0", ImmutableMap. of(), ImmutableMap - . of(), "apache-chef-demo", ImmutableMap. of(), "", - ImmutableMap. of(), ImmutableMap. of()), - ImmutableSet. of(), - "apache-chef-demo", - ImmutableSet. of(), - ImmutableSet. of(), - ImmutableSet. of(), - "0.0.0", - ImmutableSet. of(), - ImmutableSet. of( - new Resource( - "README", - URI.create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-11637f98942eafbf49c71b7f2f048b78?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=zgpNl6wSxjTNovqZu2nJq0JztU8%3D"), - base16().lowerCase().decode("11637f98942eafbf49c71b7f2f048b78"), "README", "default"), - new Resource( - "Rakefile", - URI.create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-ebcf925a1651b4e04b9cd8aac2bc54eb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=EFzzDSKKytTl7b%2FxrCeNLh05zj4%3D"), - base16().lowerCase().decode("ebcf925a1651b4e04b9cd8aac2bc54eb"), "Rakefile", "default")))); + CookbookVersion expected = CookbookVersion + .builder("apache-chef-demo", "0.0.0") + .metadata(Metadata.builder() // + .license("Apache v2.0") // + .maintainer("Your Name") // + .maintainerEmail("youremail@example.com") // + .description("A fabulous new cookbook") // + .version("0.0.0").name("apache-chef-demo") // + .longDescription("") // + .build()) + .rootFile( + Resource + .builder() + .name("README") + .path("README") + .checksum(base16().lowerCase().decode("11637f98942eafbf49c71b7f2f048b78")) + .url(URI + .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-11637f98942eafbf49c71b7f2f048b78?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=zgpNl6wSxjTNovqZu2nJq0JztU8%3D")) // + .build()) + .rootFile( + Resource + .builder() + .name("Rakefile") + .path("Rakefile") + .checksum(base16().lowerCase().decode("ebcf925a1651b4e04b9cd8aac2bc54eb")) + .url(URI + .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-ebcf925a1651b4e04b9cd8aac2bc54eb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277766181&Signature=EFzzDSKKytTl7b%2FxrCeNLh05zj4%3D")) + .build()) // + .build(); + assertEquals(fromJson, expected); } } diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java index d0d9070986..5f825dd0cc 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseNodeFromJsonTest.java @@ -19,7 +19,6 @@ package org.jclouds.chef.functions; import static org.testng.Assert.assertEquals; import java.io.IOException; -import java.util.Collections; import org.jclouds.chef.ChefApi; import org.jclouds.chef.config.ChefParserModule; @@ -32,7 +31,6 @@ import org.jclouds.rest.annotations.ApiVersion; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; @@ -63,10 +61,12 @@ public class ParseNodeFromJsonTest { } public void test() { - - Node node = new Node("adrian-jcloudstest", ImmutableMap. of("tomcat6", new JsonBall( - "{\"ssl_port\":8433}")), ImmutableMap. of(), ImmutableMap. of(), - ImmutableMap. of(), Collections.singleton("recipe[java]"), "prod"); + Node node = Node.builder() // + .name("adrian-jcloudstest") // + .normalAttribute("tomcat6", new JsonBall("{\"ssl_port\":8433}")) // + .runListElement("recipe[java]") // + .environment("prod") // + .build(); assertEquals( handler.apply(HttpResponse.builder().statusCode(200).message("ok") diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseSandboxFromJsonTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseSandboxFromJsonTest.java index 76edffd56d..13843eead4 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseSandboxFromJsonTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseSandboxFromJsonTest.java @@ -31,7 +31,6 @@ import org.jclouds.rest.annotations.ApiVersion; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; @@ -67,8 +66,8 @@ public class ParseSandboxFromJsonTest { assertEquals( handler.apply(HttpResponse.builder().statusCode(200).message("ok") .payload(ParseSandboxFromJsonTest.class.getResourceAsStream("/sandbox.json")).build()), - new Sandbox("1-8c27b0ea4c2b7aaedbb44cfbdfcc11b2", false, dateService - .iso8601SecondsDateParse("2010-07-07T03:36:00+00:00"), ImmutableSet. of(), - "f9d6d9b72bae465890aae87969f98a9c", "f9d6d9b72bae465890aae87969f98a9c")); + Sandbox.builder().rev("1-8c27b0ea4c2b7aaedbb44cfbdfcc11b2").isCompleted(false) + .createTime(dateService.iso8601SecondsDateParse("2010-07-07T03:36:00+00:00")) + .name("f9d6d9b72bae465890aae87969f98a9c").guid("f9d6d9b72bae465890aae87969f98a9c").build()); } } diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java index e992e79fbf..03e61caacd 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/ParseUploadSandboxFromJsonTest.java @@ -22,7 +22,6 @@ import static org.testng.Assert.assertEquals; import java.io.IOException; import java.net.URI; -import java.util.List; import org.jclouds.chef.ChefApi; import org.jclouds.chef.config.ChefParserModule; @@ -35,7 +34,6 @@ import org.jclouds.rest.annotations.ApiVersion; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; @@ -70,14 +68,22 @@ public class ParseUploadSandboxFromJsonTest { assertEquals( handler.apply(HttpResponse.builder().statusCode(200).message("ok") .payload(ParseUploadSandboxFromJsonTest.class.getResourceAsStream("/upload-site.json")).build()), - new UploadSandbox( - URI.create("https://api.opscode.com/organizations/jclouds/sandboxes/d454f71e2a5f400c808d0c5d04c2c88c"), - ImmutableMap., ChecksumStatus> of( + UploadSandbox + .builder() + .uri(URI + .create("https://api.opscode.com/organizations/jclouds/sandboxes/d454f71e2a5f400c808d0c5d04c2c88c")) + .checksum( asList(base16().lowerCase().decode("0c5ecd7788cf4f6c7de2a57193897a6c")), - new ChecksumStatus( - URI.create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/sandbox-d454f71e2a5f400c808d0c5d04c2c88c/checksum-0c5ecd7788cf4f6c7de2a57193897a6c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277344702&Signature=FtKyqvYEjhhEKmRY%2B0M8aGPMM7g%3D"), - true), asList(base16().lowerCase().decode("0189e76ccc476701d6b374e5a1a27347")), - new ChecksumStatus(), asList(base16().lowerCase().decode("1dda05ed139664f1f89b9dec482b77c0")), - new ChecksumStatus()), "d454f71e2a5f400c808d0c5d04c2c88c")); + ChecksumStatus + .builder() + .url(URI + .create("https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/sandbox-d454f71e2a5f400c808d0c5d04c2c88c/checksum-0c5ecd7788cf4f6c7de2a57193897a6c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277344702&Signature=FtKyqvYEjhhEKmRY%2B0M8aGPMM7g%3D")) + .needsUpload(true).build()) + .checksum(asList(base16().lowerCase().decode("0189e76ccc476701d6b374e5a1a27347")), + ChecksumStatus.builder().build()) + .checksum(asList(base16().lowerCase().decode("1dda05ed139664f1f89b9dec482b77c0")), + ChecksumStatus.builder().build()).sandboxId("d454f71e2a5f400c808d0c5d04c2c88c").build() + + ); } } diff --git a/apis/chef/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java b/apis/chef/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java index 2504b53440..98c7d07112 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/functions/UriForResourceTest.java @@ -48,7 +48,7 @@ public class UriForResourceTest { @Test public void testWithValidResource() { Function function = new UriForResource(); - Resource res = new Resource("test", URI.create("http://foo/bar"), null, null, null); + Resource res = Resource.builder().name("test").url(URI.create("http://foo/bar")).build(); URI result = function.apply(res); assertEquals(res.getUrl().toString(), result.toString()); } diff --git a/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java index adf11cf1fb..529df6843b 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/internal/BaseChefApiLiveTest.java @@ -17,6 +17,7 @@ package org.jclouds.chef.internal; import static com.google.common.base.Throwables.propagate; +import static com.google.common.collect.Iterables.isEmpty; import static com.google.common.hash.Hashing.md5; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.jclouds.io.ByteSources.asByteSource; @@ -25,6 +26,7 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; import java.io.File; import java.io.IOException; @@ -40,6 +42,7 @@ import org.jclouds.chef.domain.Client; import org.jclouds.chef.domain.CookbookVersion; import org.jclouds.chef.domain.DatabagItem; import org.jclouds.chef.domain.Environment; +import org.jclouds.chef.domain.Metadata; import org.jclouds.chef.domain.Node; import org.jclouds.chef.domain.Resource; import org.jclouds.chef.domain.Role; @@ -78,71 +81,88 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv protected DatabagItem databagItem; public void testCreateNewCookbook() throws Exception { - - // define the file you want in the cookbook + // Define the file you want in the cookbook FilePayload content = Payloads.newFilePayload(new File(System.getProperty("user.dir"), "pom.xml")); content.getContentMetadata().setContentType("application/x-binary"); - // get an md5 so that you can see if the server already has it or not + // 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. + // byte arrays, so let's convert to a list of bytes. List md5 = Bytes.asList(content.getContentMetadata().getContentMD5()); - // request an upload site for this file + // Request an upload site for this file UploadSandbox site = api.getUploadSandboxForChecksums(ImmutableSet.of(md5)); + assertTrue(site.getChecksums().containsKey(md5), md5 + " not in " + site.getChecksums()); try { - assert site.getChecksums().containsKey(md5) : md5 + " not in " + site.getChecksums(); - + // Upload the file contents, if still not uploaded ChecksumStatus status = site.getChecksums().get(md5); if (status.needsUpload()) { - // context.utils().http().put(status.getUrl(), content); api.uploadContent(status.getUrl(), content); } - api.commitSandbox(site.getSandboxId(), true); - } catch (RuntimeException e) { api.commitSandbox(site.getSandboxId(), false); + fail("Could not upload content"); } - // create a new cookbook - CookbookVersion cookbook = new CookbookVersion(PREFIX, "0.0.0"); - cookbook.getRootFiles().add(new Resource(content)); + // Create the metadata of the cookbook + Metadata metadata = Metadata.builder() // + .name(PREFIX) // + .version("0.0.0") // + .description("Jclouds test uploaded cookbook") // + .maintainer("jclouds") // + .maintainerEmail("someone@jclouds.org") // + .license("Apache 2.0") // + .build(); + + // Create a new cookbook + CookbookVersion cookbook = CookbookVersion.builder(PREFIX, "0.0.0") // + .metadata(metadata) // + .rootFile(Resource.builder().fromPayload(content).build()) // + .build(); // upload the cookbook to the remote server api.updateCookbook(PREFIX, "0.0.0", cookbook); } - @Test(dependsOnMethods = "testCreateClient") - public void testGenerateKeyForClient() throws Exception { - String credential = Pems.pem(api.generateKeyForClient(PREFIX).getPrivateKey()); - assertClientCreated(PREFIX, credential); - } - - @Test public void testListCookbooks() throws Exception { Set cookbookNames = api.listCookbooks(); - assertFalse(cookbookNames.isEmpty()); + assertFalse(cookbookNames.isEmpty(), "No cookbooks were found"); - for (String cookbook : cookbookNames) { - for (String version : api.getVersionsOfCookbook(cookbook)) { - CookbookVersion cookbookO = api.getCookbook(cookbook, version); - for (Resource resource : ImmutableList. builder().addAll(cookbookO.getDefinitions()) - .addAll(cookbookO.getFiles()).addAll(cookbookO.getLibraries()).addAll(cookbookO.getSuppliers()) - .addAll(cookbookO.getRecipes()).addAll(cookbookO.getResources()).addAll(cookbookO.getRootFiles()) - .addAll(cookbookO.getTemplates()).build()) { - try { - InputStream stream = api.getResourceContents(resource); - byte[] md5 = asByteSource(stream).hash(md5()).asBytes(); - assertEquals(md5, resource.getChecksum()); - } catch (NullPointerException e) { - assert false : "resource not found: " + resource; - } - } + for (String cookbookName : cookbookNames) { + Set versions = api.getVersionsOfCookbook(cookbookName); + assertFalse(versions.isEmpty(), "There are no versions of the cookbook: " + cookbookName); + + for (String version : api.getVersionsOfCookbook(cookbookName)) { + CookbookVersion cookbook = api.getCookbook(cookbookName, version); + assertNotNull(cookbook, "Could not get cookbook: " + cookbookName); + } + } + } + + @Test(dependsOnMethods = "testListCookbooks") + public void testListCookbookVersionsWithChefService() throws Exception { + Iterable cookbooks = chefService.listCookbookVersions(); + assertFalse(isEmpty(cookbooks), "No cookbooks were found"); + } + + @Test(dependsOnMethods = "testListCookbookVersionsWithChefService") + public void testDownloadCookbooks() throws Exception { + Iterable cookbooks = chefService.listCookbookVersions(); + for (CookbookVersion cookbook : cookbooks) { + for (Resource resource : ImmutableList. builder().addAll(cookbook.getDefinitions()) + .addAll(cookbook.getFiles()).addAll(cookbook.getLibraries()).addAll(cookbook.getSuppliers()) + .addAll(cookbook.getRecipes()).addAll(cookbook.getResources()).addAll(cookbook.getRootFiles()) + .addAll(cookbook.getTemplates()).build()) { + + InputStream stream = api.getResourceContents(resource); + assertNotNull(stream, "Resource contents are null for resource: " + resource.getName()); + + byte[] md5 = asByteSource(stream).hash(md5()).asBytes(); + assertEquals(md5, resource.getChecksum()); } } } @@ -150,12 +170,13 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv @Test(dependsOnMethods = "testCreateNewCookbook") public void testUpdateCookbook() throws Exception { CookbookVersion cookbook = api.getCookbook(PREFIX, "0.0.0"); - assertNotNull(api.updateCookbook(PREFIX, "0.0.0", cookbook)); + assertNotNull(cookbook, "Cookbook not found: " + PREFIX); + assertNotNull(api.updateCookbook(PREFIX, "0.0.0", cookbook), "Updated cookbook was null"); } @Test(dependsOnMethods = { "testCreateNewCookbook", "testUpdateCookbook" }) public void testDeleteCookbook() throws Exception { - assertNotNull(api.deleteCookbook(PREFIX, "0.0.0")); + assertNotNull(api.deleteCookbook(PREFIX, "0.0.0"), "Deleted cookbook was null"); } @Test @@ -172,34 +193,30 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv assertClientCreated(ADMIN_PREFIX, credential); } - @Test - public void testClientExists() throws Exception { - assertNotNull(api.clientExists(identity)); + @Test(dependsOnMethods = "testCreateClient") + public void testGenerateKeyForClient() throws Exception { + String credential = Pems.pem(api.generateKeyForClient(PREFIX).getPrivateKey()); + assertClientCreated(PREFIX, credential); } @Test public void testListNodes() throws Exception { Set nodes = api.listNodes(); - assertNotNull(nodes); + assertNotNull(nodes, "No nodes were found"); } @Test(dependsOnMethods = "testCreateRole") public void testCreateNode() throws Exception { api.deleteNode(PREFIX); - api.createNode(new Node(PREFIX, Collections.singleton("role[" + PREFIX + "]"), "_default")); + api.createNode(Node.builder().name(PREFIX).runListElement("role[" + PREFIX + "]").environment("_default").build()); node = api.getNode(PREFIX); // TODO check recipes - assertNotNull(node); + assertNotNull(node, "Created node should not be null"); Set nodes = api.listNodes(); - assert nodes.contains(PREFIX) : String.format("node %s not in %s", PREFIX, nodes); + assertTrue(nodes.contains(PREFIX), String.format("node %s not in %s", PREFIX, nodes)); } @Test(dependsOnMethods = "testCreateNode") - public void testNodeExists() throws Exception { - assertNotNull(api.nodeExists(PREFIX)); - } - - @Test(dependsOnMethods = "testNodeExists") public void testUpdateNode() throws Exception { for (String nodename : api.listNodes()) { Node node = api.getNode(nodename); @@ -210,25 +227,20 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv @Test public void testListRoles() throws Exception { Set roles = api.listRoles(); - assertNotNull(roles); + assertNotNull(roles, "Role list was null"); } @Test public void testCreateRole() throws Exception { api.deleteRole(PREFIX); - api.createRole(new Role(PREFIX, Collections.singleton("recipe[java]"))); + api.createRole(Role.builder().name(PREFIX).runListElement("recipe[java]").build()); role = api.getRole(PREFIX); - assertNotNull(role); + assertNotNull(role, "Created role should not be null"); assertEquals(role.getName(), PREFIX); assertEquals(role.getRunList(), Collections.singleton("recipe[java]")); } @Test(dependsOnMethods = "testCreateRole") - public void testRoleExists() throws Exception { - assertNotNull(api.roleExists(PREFIX)); - } - - @Test(dependsOnMethods = "testRoleExists") public void testUpdateRole() throws Exception { for (String rolename : api.listRoles()) { Role role = api.getRole(rolename); @@ -239,7 +251,7 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv @Test public void testListDatabags() throws Exception { Set databags = api.listDatabags(); - assertNotNull(databags); + assertNotNull(databags, "Data bag list was null"); } @Test @@ -248,15 +260,10 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv api.createDatabag(PREFIX); } - @Test(dependsOnMethods = "testCreateDatabag") - public void testDatabagExists() throws Exception { - assertNotNull(api.databagExists(PREFIX)); - } - @Test(dependsOnMethods = "testCreateDatabagItem") public void testListDatabagItems() throws Exception { Set databagItems = api.listDatabagItems(PREFIX); - assertNotNull(databagItems); + assertNotNull(databagItems, "Data bag item list was null"); } @Test(dependsOnMethods = "testCreateDatabag") @@ -265,7 +272,7 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv config.setProperty("foo", "bar"); api.deleteDatabagItem(PREFIX, PREFIX); databagItem = api.createDatabagItem(PREFIX, new DatabagItem("config", json.toJson(config))); - assertNotNull(databagItem); + assertNotNull(databagItem, "Created data bag item should not be null"); assertEquals(databagItem.getId(), "config"); // The databagItem json contains extra keys: (the name and the type if the @@ -278,11 +285,6 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv } @Test(dependsOnMethods = "testCreateDatabagItem") - public void testDatabagItemExists() throws Exception { - assertNotNull(api.databagItemExists(PREFIX, PREFIX)); - } - - @Test(dependsOnMethods = "testDatabagItemExists") public void testUpdateDatabagItem() throws Exception { for (String databagItemId : api.listDatabagItems(PREFIX)) { DatabagItem databagItem = api.getDatabagItem(PREFIX, databagItemId); @@ -293,16 +295,16 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv @Test public void testListSearchIndexes() throws Exception { Set indexes = api.listSearchIndexes(); - assertNotNull(indexes); - assert indexes.contains("node") : indexes; - assert indexes.contains("client") : indexes; - assert indexes.contains("role") : indexes; + assertNotNull(indexes, "The index list should not be null"); + assertTrue(indexes.contains("node")); + assertTrue(indexes.contains("client")); + assertTrue(indexes.contains("role")); } @Test public void testSearchNodes() throws Exception { SearchResult results = api.searchNodes(); - assertNotNull(results); + assertNotNull(results, "Node result list should not be null"); } @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateNode" }) @@ -330,7 +332,7 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv @Test public void testSearchClients() throws Exception { SearchResult results = api.searchClients(); - assertNotNull(results); + assertNotNull(results, "Client result list should not be null"); } @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateClient" }) @@ -358,7 +360,7 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv @Test public void testSearchRoles() throws Exception { SearchResult results = api.searchRoles(); - assertNotNull(results); + assertNotNull(results, "Role result list should not be null"); } @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateRole" }) @@ -383,13 +385,13 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv assertTrue(waitForIndex.apply(options)); } - @Test(dependsOnMethods = { "testListSearchIndexes", "testDatabagItemExists" }) + @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" }) public void testSearchDatabag() throws Exception { SearchResult results = api.searchDatabag(PREFIX); - assertNotNull(results); + assertNotNull(results, "Data bag item result list should not be null"); } - @Test(dependsOnMethods = { "testListSearchIndexes", "testDatabagItemExists" }) + @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateDatabagItem" }) public void testSearchDatabagWithOptions() throws Exception { Predicate waitForIndex = retry(new Predicate() { @Override @@ -414,15 +416,15 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv @Test(expectedExceptions = ResourceNotFoundException.class, dependsOnMethods = "testListSearchIndexes") public void testSearchDatabagNotFound() throws Exception { SearchResult results = api.searchDatabag("whoopie"); - assertNotNull(results); + assertNotNull(results, "Data bag item result list should not be null"); } @Test public void testCreateEnvironment() { api.deleteEnvironment(PREFIX); - api.createEnvironment(new Environment(PREFIX, PREFIX)); + api.createEnvironment(Environment.builder().name(PREFIX).description(PREFIX).build()); Environment env = api.getEnvironment(PREFIX); - assertNotNull(env); + assertNotNull(env, "Created environment should not be null"); assertEquals(env.getName(), PREFIX); assertEquals(env.getDescription(), PREFIX); } @@ -430,14 +432,14 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv @Test(dependsOnMethods = "testCreateEnvironment") public void testListEnvironment() { Set envList = api.listEnvironments(); - assertNotNull(envList); + assertNotNull(envList, "Environment list was null"); assertTrue(envList.contains(PREFIX)); } @Test(dependsOnMethods = "testCreateEnvironment") public void testSearchEnvironments() throws Exception { SearchResult results = api.searchEnvironments(); - assertNotNull(results); + assertNotNull(results, "Environment result list was null"); } @Test(dependsOnMethods = { "testListSearchIndexes", "testCreateEnvironment" }) @@ -462,12 +464,6 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv assertTrue(waitForIndex.apply(options)); } - @Test - public void testListCookbookVersionsWithChefService() throws Exception { - Iterable cookbooks = chefService.listCookbookVersions(); - assertNotNull(cookbooks); - } - @AfterClass(groups = { "live", "integration" }) @Override public void tearDown() { @@ -489,7 +485,7 @@ public abstract class BaseChefApiLiveTest extends BaseChefLiv try { Client client = clientApi.getClient(identity); - assertNotNull(client); + assertNotNull(client, "Client not found: " + identity); } finally { try { Closeables.close(clientApi, true); diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java index a9045691f9..4b55efd94e 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java @@ -55,7 +55,7 @@ public class CreateNodeAndPopulateAutomaticAttributesImplLiveTest extends BaseCh Node node = api.getNode(prefix); assertEquals(node.getName(), prefix); assertEquals(node.getRunList(), runList); - assertEquals(node.getAutomatic().get("current_user").toString(), currentUserProvider.get().toString()); + assertEquals(node.getAutomaticAttributes().get("current_user").toString(), currentUserProvider.get().toString()); } finally { api.deleteNode(prefix); } diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java index 776247f3ea..ace63e1083 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java @@ -44,17 +44,11 @@ public class CreateNodeAndPopulateAutomaticAttributesImplTest { public void testWithNoRunlist() { ChefApi chef = createMock(ChefApi.class); - Map automatic = ImmutableMap. of(); + Supplier> automaticSupplier = Suppliers.> ofInstance(ImmutableMap. of()); - Node node = new Node("name", ImmutableSet. of(), "_default"); + Node nodeWithAutomatic = Node.builder().name("name").environment("_default") + .automaticAttributes(automaticSupplier.get()).build(); - Supplier> automaticSupplier = Suppliers.> ofInstance(automatic); - - Node nodeWithAutomatic = new Node("name", ImmutableMap. of(), - ImmutableMap. of(), ImmutableMap. of(), automatic, - ImmutableSet. of(), "_default"); - - node.getAutomatic().putAll(automaticSupplier.get()); chef.createNode(nodeWithAutomatic); replay(chef); diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java index 755576ce04..e8681d2be4 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java @@ -50,12 +50,12 @@ public class UpdateAutomaticAttributesOnNodeImplLiveTest extends BaseChefLiveTes public void testExecute() { Set runList = ImmutableSet.of("role[" + prefix + "]"); try { - api.createNode(new Node(prefix, runList, "_default")); + api.createNode(Node.builder().name(prefix).runList(runList).environment("_default").build()); strategy.execute(prefix); Node node = api.getNode(prefix); assertEquals(node.getName(), prefix); assertEquals(node.getRunList(), runList); - assertEquals(node.getAutomatic().get("current_user").toString(), currentUserProvider.get().toString()); + assertEquals(node.getAutomaticAttributes().get("current_user").toString(), currentUserProvider.get().toString()); } finally { api.deleteNode(prefix); } diff --git a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java index bf4a0e443f..792e3916ee 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java @@ -16,10 +16,10 @@ */ package org.jclouds.chef.strategy.internal; +import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; -import static org.easymock.classextension.EasyMock.createMock; -import static org.easymock.classextension.EasyMock.replay; -import static org.easymock.classextension.EasyMock.verify; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; import java.util.Map; @@ -31,7 +31,6 @@ import org.testng.annotations.Test; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; /** * Tests behavior of {@code UpdateAutomaticAttributesOnNodeImpl} @@ -46,17 +45,13 @@ public class UpdateAutomaticAttributesOnNodeImplTest { ChefApi chef = createMock(ChefApi.class); Map automatic = ImmutableMap. of(); - - Node node = new Node("name", ImmutableSet. of(), "_default"); - Supplier> automaticSupplier = Suppliers.> ofInstance(automatic); - Node nodeWithAutomatic = new Node("name", ImmutableMap. of(), - ImmutableMap. of(), ImmutableMap. of(), automatic, - ImmutableSet. of(), "_default"); + Node node = Node.builder().name("name").environment("_default").build(); + Node nodeWithAutomatic = Node.builder().name("name").environment("_default").automaticAttributes(automatic) + .build(); expect(chef.getNode("name")).andReturn(node); - node.getAutomatic().putAll(automaticSupplier.get()); expect(chef.updateNode(nodeWithAutomatic)).andReturn(null); replay(chef); diff --git a/apis/chef/src/test/java/org/jclouds/chef/test/TransientChefApiIntegrationTest.java b/apis/chef/src/test/java/org/jclouds/chef/test/TransientChefApiIntegrationTest.java index d11b1cffa5..13c002eb1b 100644 --- a/apis/chef/src/test/java/org/jclouds/chef/test/TransientChefApiIntegrationTest.java +++ b/apis/chef/src/test/java/org/jclouds/chef/test/TransientChefApiIntegrationTest.java @@ -50,12 +50,7 @@ public class TransientChefApiIntegrationTest extends BaseChefLiveTest { api.createDatabag(PREFIX); } - @Test(dependsOnMethods = "testCreateDatabag") - public void testDatabagExists() { - assertNotNull(api.databagExists(PREFIX)); - } - - @Test(dependsOnMethods = { "testDatabagExists" }) + @Test(dependsOnMethods = { "testCreateDatabag" }) public void testCreateDatabagItem() { Properties config = new Properties(); config.setProperty("foo", "bar"); @@ -66,11 +61,6 @@ public class TransientChefApiIntegrationTest extends BaseChefLiveTest { } @Test(dependsOnMethods = "testCreateDatabagItem") - public void testDatabagItemExists() { - assertNotNull(api.databagItemExists(PREFIX, PREFIX)); - } - - @Test(dependsOnMethods = "testDatabagItemExists") public void testUpdateDatabagItem() { for (String databagItemId : api.listDatabagItems(PREFIX)) { DatabagItem databagItem = api.getDatabagItem(PREFIX, databagItemId); diff --git a/apis/chef/src/test/resources/apache-chef-demo-cookbook.json b/apis/chef/src/test/resources/apache-chef-demo-cookbook.json index 0a3e384039..228a3c06d4 100644 --- a/apis/chef/src/test/resources/apache-chef-demo-cookbook.json +++ b/apis/chef/src/test/resources/apache-chef-demo-cookbook.json @@ -6,14 +6,23 @@ "json_class": "Chef::CookbookVersion", "providers": [], "metadata": { - "dependencies": {}, "name": "apache-chef-demo", + "dependencies": {}, + "name": "apache-chef-demo", "maintainer_email": "youremail@example.com", - "attributes": {}, "license": "Apache v2.0", + "attributes": {}, + "license": "Apache v2.0", "maintainer": "Your Name", - "suggestions": {}, "platforms": {}, "long_description": "", - "recommendations": {}, "version": "0.0.0", - "groupings": {}, "recipes": {}, "conflicting": {}, "description": "A fabulous new cookbook", - "replacing": {}, "providing": {} + "suggestions": {}, + "platforms": {}, + "long_description": "", + "recommendations": {}, + "version": "0.0.0", + "groupings": {}, + "recipes": {}, + "conflicting": {}, + "description": "A fabulous new cookbook", + "replacing": {}, + "providing": {} }, "libraries": [], "resources": [], "templates": [], diff --git a/apis/chef/src/test/resources/brew-cookbook.json b/apis/chef/src/test/resources/brew-cookbook.json index f0b09ede2a..dcf7acaec7 100644 --- a/apis/chef/src/test/resources/brew-cookbook.json +++ b/apis/chef/src/test/resources/brew-cookbook.json @@ -1 +1,48 @@ -{"name":"brew-0.0.0","definitions":[],"json_class":"Chef::CookbookVersion","attributes":[],"files":[],"metadata":{"dependencies":{},"name":"brew","maintainer_email":"youremail@example.com","license":"Apache v2.0","attributes":{},"maintainer":"Your Name","suggestions":{},"platforms":{},"long_description":"","version":"0.0.0","recommendations":{},"conflicting":{},"recipes":{"brew":""},"groupings":{},"description":"A fabulous new cookbook","replacing":{},"providing":{"brew":[]}},"providers":[{"name":"brew.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-0c5ecd7788cf4f6c7de2a57193897a6c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774465&Signature=brTA3YkBF7iDnjPGCCHxgm7AHko%3D","checksum":"0c5ecd7788cf4f6c7de2a57193897a6c","path":"providers/brew.rb","specificity":"default"}],"cookbook_name":"brew","resources":[{"name":"brew.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-0189e76ccc476701d6b374e5a1a27347?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774465&Signature=ufrI1k6pKJ1%2FBRMAaIGr6icJlpc%3D","checksum":"0189e76ccc476701d6b374e5a1a27347","path":"resources/brew.rb","specificity":"default"}],"templates":[],"libraries":[],"version":"0.0.0","recipes":[{"name":"default.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-1dda05ed139664f1f89b9dec482b77c0?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774465&Signature=dOzPk64at92zOfZlxt1suDpGuPs%3D","checksum":"1dda05ed139664f1f89b9dec482b77c0","path":"recipes/default.rb","specificity":"default"}],"root_files":[],"chef_type":"cookbook_version"} \ No newline at end of file +{ "attributes" : [ ], + "chef_type" : "cookbook_version", + "cookbook_name" : "brew", + "definitions" : [ ], + "files" : [ ], + "json_class" : "Chef::CookbookVersion", + "libraries" : [ ], + "metadata" : { "attributes" : { }, + "conflicting" : { }, + "dependencies" : { }, + "description" : "A fabulous new cookbook", + "groupings" : { }, + "license" : "Apache v2.0", + "long_description" : "", + "maintainer" : "Your Name", + "maintainer_email" : "youremail@example.com", + "name" : "brew", + "platforms" : { }, + "providing" : { "brew" : "0.0.0" }, + "recipes" : { "brew" : "" }, + "recommendations" : { }, + "replacing" : { }, + "suggestions" : { }, + "version" : "0.0.0" + }, + "name" : "brew-0.0.0", + "providers" : [ { "checksum" : "0c5ecd7788cf4f6c7de2a57193897a6c", + "name" : "brew.rb", + "path" : "providers/brew.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-0c5ecd7788cf4f6c7de2a57193897a6c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774465&Signature=brTA3YkBF7iDnjPGCCHxgm7AHko%3D" + } ], + "recipes" : [ { "checksum" : "1dda05ed139664f1f89b9dec482b77c0", + "name" : "default.rb", + "path" : "recipes/default.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-1dda05ed139664f1f89b9dec482b77c0?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774465&Signature=dOzPk64at92zOfZlxt1suDpGuPs%3D" + } ], + "resources" : [ { "checksum" : "0189e76ccc476701d6b374e5a1a27347", + "name" : "brew.rb", + "path" : "resources/brew.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-0189e76ccc476701d6b374e5a1a27347?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774465&Signature=ufrI1k6pKJ1%2FBRMAaIGr6icJlpc%3D" + } ], + "root_files" : [ ], + "templates" : [ ], + "version" : "0.0.0" +} \ No newline at end of file diff --git a/apis/chef/src/test/resources/client.json b/apis/chef/src/test/resources/client.json index 15ff8d06a7..eef7c71574 100644 --- a/apis/chef/src/test/resources/client.json +++ b/apis/chef/src/test/resources/client.json @@ -1 +1,8 @@ -{"orgname":"jclouds","certificate":"-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n","uri":"https://api.opscode.com/organizations/jclouds/clients/adriancole-jcloudstest","private_key":"-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vEuYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n","clientname":"adriancole-jcloudstest","name":"adriancole-jcloudstest","validator":false} \ No newline at end of file +{ "certificate" : "-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDczMDIwNDEzMFoXDTIwMDcyNzIwNDEzMFowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBAMm9mSSahptCikfvJ30CTbEnfhfbVzTFewnznFuo\n7KrPBGYIlUdPYQ9SGDo+GKjNKiTjZYMoOMUVnsHUhu0Ez49ZSaVQInWvbF8tvpM8\nmoGQNQJtDmXG6m+YaHiA4HF/ng2u/bNLtA6Jo3HzvRCobxywc/szPt0Kj0ZD1fJ2\nE237Ph41c8zlOg9QdF0d/iD2WZdgJ1rNndKoZ0rR3A1L50VUND+PNmMDfVYHHjmb\naT89AwihCeU8eUk7m/JNP87f1QDB0Gny0rkDC3drOGS7jmabTf/7gLE5sYq3qnd+\n8/vGU3QWyfCxKSfogl7kn5uWlIe4sOqMb06GNgC+d/oytlECAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQBftzSZxstWw60GqRTDNN/F2GnrdtnKBoXzHww3r6jtGEylYq20\n5KfKpEx+sPX0gyZuYJiXC2CkEjImAluWKcdN9ZF6VD541sheAjbiaU7q7ZsztTxF\nWUH2tCvHeDXYKPKek3QzL7bYpUhLnCN/XxEv6ibeMDwtI7f5qpk2Aspzcw==\n-----END CERTIFICATE-----\n", + "clientname" : "adriancole-jcloudstest", + "name" : "adriancole-jcloudstest", + "orgname" : "jclouds", + "private_key" : "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vEuYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n", + "uri" : "https://api.opscode.com/organizations/jclouds/clients/adriancole-jcloudstest", + "validator" : false +} \ No newline at end of file diff --git a/apis/chef/src/test/resources/client.txt b/apis/chef/src/test/resources/client.txt deleted file mode 100644 index 5023370477..0000000000 --- a/apis/chef/src/test/resources/client.txt +++ /dev/null @@ -1,7 +0,0 @@ -{ - "certificate": "-----BEGIN CERTIFICATE-----\ndXQ==\n-----END CERTIFICATE-----\n", - "orgname": "jclouds", - "clientname": "adrian-jcloudstest", - "name": "adrian-jcloudstest", - "validator": false -} \ No newline at end of file diff --git a/apis/chef/src/test/resources/logback.xml b/apis/chef/src/test/resources/logback.xml index 50b810a91e..f9c023fac2 100644 --- a/apis/chef/src/test/resources/logback.xml +++ b/apis/chef/src/test/resources/logback.xml @@ -2,15 +2,12 @@ target/test-data/jclouds.log - %d %-5p [%c] [%thread] %m%n - target/test-data/jclouds-wire.log - %d %-5p [%c] [%thread] %m%n @@ -24,12 +21,10 @@ - - diff --git a/apis/chef/src/test/resources/mysql-cookbook.json b/apis/chef/src/test/resources/mysql-cookbook.json index b0f8bc4ee6..b0450aee3e 100644 --- a/apis/chef/src/test/resources/mysql-cookbook.json +++ b/apis/chef/src/test/resources/mysql-cookbook.json @@ -1 +1,268 @@ -{"definitions":[],"name":"mysql-0.21.2","attributes":[{"name":"server.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-548fa4bc548b8b59ac98fffee8e81f4a?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=MsgggSKS0T1q1Lc72nJpHORBQX0%3D","checksum":"548fa4bc548b8b59ac98fffee8e81f4a","path":"attributes/server.rb","specificity":"default"}],"files":[],"json_class":"Chef::CookbookVersion","providers":[{"name":"database.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-b994881a2aba60e32c4b6408ffba993d?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=2XMRbryCmEqirCWLCvrXoenYubw%3D","checksum":"b994881a2aba60e32c4b6408ffba993d","path":"providers/database.rb","specificity":"default"}],"metadata":{"dependencies":{"openssl":[]},"name":"mysql","maintainer_email":"cookbooks@opscode.com","attributes":{"mysql/server_root_password":{"required":"optional","calculated":false,"default":"randomly generated","choice":[],"type":"string","recipes":[],"display_name":"MySQL Server Root Password","description":"Randomly generated password for the mysqld root user"},"mysql/tunable/max_heap_table_size":{"required":"optional","calculated":false,"default":"32M","choice":[],"type":"string","recipes":[],"display_name":"MySQL Tunable Max Heap Table Size"},"mysql/bind_address":{"required":"optional","calculated":false,"default":"ipaddress","choice":[],"type":"string","recipes":[],"display_name":"MySQL Bind Address","description":"Address that mysqld should listen on"},"mysql/datadir":{"required":"optional","calculated":false,"default":"/var/lib/mysql","choice":[],"type":"string","recipes":[],"display_name":"MySQL Data Directory","description":"Location of mysql databases"},"mysql/tunable/wait_timeout":{"required":"optional","calculated":false,"default":"180","choice":[],"type":"string","recipes":[],"display_name":"MySQL Tunable Wait Timeout"},"mysql/tunable/back_log":{"required":"optional","calculated":false,"default":"128","choice":[],"type":"string","recipes":[],"display_name":"MySQL Tunable Back Log"},"mysql/tunable/net_read_timeout":{"required":"optional","calculated":false,"default":"30","choice":[],"type":"string","recipes":[],"display_name":"MySQL Tunable Net Read Timeout"},"mysql/tunable/max_connections":{"required":"optional","calculated":false,"default":"800","choice":[],"type":"string","recipes":[],"display_name":"MySQL Tunable Max Connections"},"mysql/tunable":{"required":"optional","calculated":false,"choice":[],"type":"hash","recipes":[],"display_name":"MySQL Tunables","description":"Hash of MySQL tunable attributes"},"mysql/tunable/table_cache":{"required":"optional","calculated":false,"default":"128","choice":[],"type":"string","recipes":[],"display_name":"MySQL Tunable Table Cache"},"mysql/ec2_path":{"required":"optional","calculated":false,"default":"/mnt/mysql","choice":[],"type":"string","recipes":[],"display_name":"MySQL EC2 Path","description":"Location of mysql directory on EC2 instance EBS volumes"},"mysql/tunable/key_buffer":{"required":"optional","calculated":false,"default":"250M","choice":[],"type":"string","recipes":[],"display_name":"MySQL Tuntable Key Buffer"},"mysql/tunable/net_write_timeout":{"required":"optional","calculated":false,"default":"30","choice":[],"type":"string","recipes":[],"display_name":"MySQL Tunable Net Write Timeout"}},"license":"Apache 2.0","maintainer":"Opscode, Inc.","suggestions":{},"platforms":{"debian":[],"ubuntu":[]},"long_description":"= DESCRIPTION:\n\nInstalls and configures MySQL client or server.\n\n= REQUIREMENTS:\n\n== Platform:\n\nBest tested on Ubuntu 9.04,9.10. On EC2, requires platform that supports -o bind option for the 'mount' command.\n\n== Cookbooks:\n\nRequires Opscode's openssl cookbook for secure password generation.\n\n= ATTRIBUTES: \n\n* mysql[:server_root_password] - Set the server's root password with this, default is a randomly generated password with OpenSSL::Random.random_bytes.\n* mysql[:server_repl_password] - Set the replication user 'repl' password with this, default is a randomly generated password with OpenSSL::Random.random_bytes.\n* mysql[:server_debian_password] - Set the debian-sys-maint user password with this, default is a randomly generated password with OpenSSL::Random.random_bytes.\n* mysql[:bind_address] - Listen address for MySQLd, default is node's ipaddress.\n* mysql[:datadir] - Location for mysql data directory, default is \"/var/lib/mysql\" \n* mysql[:ec2_path] - location of mysql datadir on EC2 nodes, default \"/mnt/mysql\" \n\nPerformance tuning attributes, each corresponds to the same-named parameter in my.cnf; default values listed\n\n* mysql[:tunable][:key_buffer] = \"250M\"\n* mysql[:tunable][:max_connections] = \"800\" \n* mysql[:tunable][:wait_timeout] = \"180\" \n* mysql[:tunable][:net_write_timeout] = \"30\" \n* mysql[:tunable][:net_write_timeout] = \"30\" \n* mysql[:tunable][:back_log] = \"128\" \n* mysql[:tunable][:table_cache] = \"128\" \n* mysql[:tunable][:max_heap_table_size] = \"32M\" \n\n= USAGE:\n\nOn client nodes,\n\n include_recipe \"mysql::client\"\n \nAs the common use case is on systems with Ruby, we also install the MySQL RubyGem. Because we may want to be able to use the gem within another Chef recipe, we make sure the mysql development package and gem are installed first. The key is this:\n\n r = package ... do\n action :nothing\n end\n \n r.run_action(:install)\n \nThis creates a resource object for the package and does the installation before other recipes are parsed. You'll need to have the C compiler and such (ie, build-essential on Ubuntu) before running the recipes, but we already do that when installing Chef :-). If you want to be able to access a MySQL database via Ruby within another recipe, you could do so, like so:\n\n Gem.clear_paths # needed for Chef to find the gem...\n require 'mysql' # requires the mysql gem\n\n execute \"create #{node[:railsapp][:db][:database]} database\" do\n command \"/usr/bin/mysqladmin -u root -p#{node[:mysql][:server_root_password]} create #{node[:railsapp][:db][:database]}\"\n not_if do\n m = Mysql.new(\"localhost\", \"root\", @node[:mysql][:server_root_password])\n m.list_dbs.include?(@node[:railsapp][:db][:database])\n end\n end\n\nOn server nodes, \n\n include_recipe \"mysql::server\"\n \nOn Debian/Ubuntu this will preseed the MySQL package with the randomly generated root password. You can of course change the password afterward, but this makes sure that there's a good password set. You can view it in the node data in the Chef Server webui. Sets a new password for debian-sys-maint user as well.\n\nAlso sets up 'repl' user grants for replication slaves.\n\nOn EC2 nodes,\n\n include_recipe \"mysql::server_ec2\"\n \nWhen the ec2_path doesn't exist we look for a mounted filesystem (eg, EBS) and move the datadir there.\n\nThe client recipe is already included by server and 'default' recipes.\n\n= LICENSE and AUTHOR:\n \nAuthor:: Joshua Timberman ()\nAuthor:: AJ Christensen ()\n\nCopyright:: 2009, Opscode, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","recommendations":{},"version":"0.21.2","groupings":{},"recipes":{"mysql::client":"Installs packages required for mysql clients using run_action magic","mysql::server_ec2":"Performs EC2-specific mountpoint manipulation","mysql::server":"Installs packages required for mysql servers w/o manual intervention"},"conflicting":{},"description":"Installs and configures mysql for client or server","replacing":{},"providing":{}},"libraries":[{"name":"database.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-b2eb0760c07734be9c637dcffc86175a?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=CvVbxzrA%2Fuxc59ZjLR5BsMozfxk%3D","checksum":"b2eb0760c07734be9c637dcffc86175a","path":"libraries/database.rb","specificity":"default"}],"resources":[{"name":"database.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-8aa8e2cafe54c2932c7aa65d62ec2695?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=6URS94f1HpRibHC%2FhBkr7Eg3dVA%3D","checksum":"8aa8e2cafe54c2932c7aa65d62ec2695","path":"resources/database.rb","specificity":"default"}],"templates":[{"name":"my.cnf.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-689c1b6fbb242b6c508384e56646341d?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=2ugp0XVvvUktYdBxfC9bCZBjOs4%3D","checksum":"689c1b6fbb242b6c508384e56646341d","path":"templates/ubuntu-9.10/my.cnf.erb","specificity":"ubuntu-9.10"},{"name":"mysql-server.seed.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-16b036a0bb31957a77e9b825cf616cc5?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=50bRvt6GQqFEcfYtaIsq1d4a4c8%3D","checksum":"16b036a0bb31957a77e9b825cf616cc5","path":"templates/default/mysql-server.seed.erb","specificity":"default"},{"name":"grants.sql.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-932b51ddddcbd24ee10a76ecae33b8ba?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=RHR0obLFcsN1M9tL28IH4Tcur5g%3D","checksum":"932b51ddddcbd24ee10a76ecae33b8ba","path":"templates/default/grants.sql.erb","specificity":"default"},{"name":"my.cnf.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-7746560b37ac8d4a0cf68befbecbd8a3?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=W7Nqkvhw2TBrlDvcM2rlA4Oj5%2Bk%3D","checksum":"7746560b37ac8d4a0cf68befbecbd8a3","path":"templates/default/my.cnf.erb","specificity":"default"},{"name":"my.cnf.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-63bd67fae6d297e8f658e9c0ad01a411?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=oFcRya56f%2F4oJBGrIvk4XcWQFm4%3D","checksum":"63bd67fae6d297e8f658e9c0ad01a411","path":"templates/centos/my.cnf.erb","specificity":"centos"},{"name":"my.cnf.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-689c1b6fbb242b6c508384e56646341d?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=2ugp0XVvvUktYdBxfC9bCZBjOs4%3D","checksum":"689c1b6fbb242b6c508384e56646341d","path":"templates/ubuntu-10.04/my.cnf.erb","specificity":"ubuntu-10.04"},{"name":"my.cnf.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-63bd67fae6d297e8f658e9c0ad01a411?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=oFcRya56f%2F4oJBGrIvk4XcWQFm4%3D","checksum":"63bd67fae6d297e8f658e9c0ad01a411","path":"templates/redhat/my.cnf.erb","specificity":"redhat"},{"name":"port_mysql.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-d2244150a145b3f658cd37c13269fafc?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=23iHcjwpNOvlNf%2BlrKcV2pkU7uo%3D","checksum":"d2244150a145b3f658cd37c13269fafc","path":"templates/default/port_mysql.erb","specificity":"default"},{"name":"debian.cnf.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-2e08553db526f5f80c28b343f6a616cb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=VdcFYxnLUkj1tS3k8DovrzZEA7E%3D","checksum":"2e08553db526f5f80c28b343f6a616cb","path":"templates/default/debian.cnf.erb","specificity":"default"},{"name":"my.cnf.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-1e5068eec65b51f5a327580fb0af4677?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=D5lPeu1UQvA9pEXZm5nVOwj3WIo%3D","checksum":"1e5068eec65b51f5a327580fb0af4677","path":"templates/ubuntu-8.04/my.cnf.erb","specificity":"ubuntu-8.04"}],"cookbook_name":"mysql","version":"0.21.2","recipes":[{"name":"server_ec2.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-f51bd8122b7dccc9f4656319fef3252a?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=BUR2mosCvmoOKq4Mkh3JUG0MY38%3D","checksum":"f51bd8122b7dccc9f4656319fef3252a","path":"recipes/server_ec2.rb","specificity":"default"},{"name":"server.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-80daa897597560372d017c58c4df0e3c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=bU3j9Nw%2BnuIroXKrlJZe7tjaugA%3D","checksum":"80daa897597560372d017c58c4df0e3c","path":"recipes/server.rb","specificity":"default"},{"name":"default.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-bd3ba2d05dea6a8cf0dc2a45f540cc32?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=7haumT5EtEM2h8l32efqV%2Fik%2BdY%3D","checksum":"bd3ba2d05dea6a8cf0dc2a45f540cc32","path":"recipes/default.rb","specificity":"default"},{"name":"client.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-a1d679c7480267cd9b69e3194c7e45ab?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=ZhfTiwv1aXC7HZMnW8A7i4vkMCM%3D","checksum":"a1d679c7480267cd9b69e3194c7e45ab","path":"recipes/client.rb","specificity":"default"}],"root_files":[{"name":"README.rdoc","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-e9278fc99fd668bdce33d72dc71fade9?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=KPgAGqShEO5SGzz8oRdwIInPUOc%3D","checksum":"e9278fc99fd668bdce33d72dc71fade9","path":"README.rdoc","specificity":"default"},{"name":"metadata.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-8d2f9635f4817ff905a4124e09ec6c59?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=fPF2iY7tNrq%2FuNrCjRLImP9vRbA%3D","checksum":"8d2f9635f4817ff905a4124e09ec6c59","path":"metadata.rb","specificity":"default"},{"name":"metadata.json","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-e6804b8f3e6dfdbbece9d319537ffea1?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=EVsALLreeAA41%2BiPAfPt%2FxFEIYI%3D","checksum":"e6804b8f3e6dfdbbece9d319537ffea1","path":"metadata.json","specificity":"default"}],"chef_type":"cookbook_version"} \ No newline at end of file +{ "attributes" : [ { "checksum" : "548fa4bc548b8b59ac98fffee8e81f4a", + "name" : "server.rb", + "path" : "attributes/server.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-548fa4bc548b8b59ac98fffee8e81f4a?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=MsgggSKS0T1q1Lc72nJpHORBQX0%3D" + } ], + "chef_type" : "cookbook_version", + "cookbook_name" : "mysql", + "definitions" : [ ], + "files" : [ ], + "json_class" : "Chef::CookbookVersion", + "libraries" : [ { "checksum" : "b2eb0760c07734be9c637dcffc86175a", + "name" : "database.rb", + "path" : "libraries/database.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-b2eb0760c07734be9c637dcffc86175a?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=CvVbxzrA%2Fuxc59ZjLR5BsMozfxk%3D" + } ], + "metadata" : { "attributes" : { "mysql/bind_address" : { "calculated" : false, + "choice" : [ ], + "default" : "ipaddress", + "description" : "Address that mysqld should listen on", + "display_name" : "MySQL Bind Address", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/datadir" : { "calculated" : false, + "choice" : [ ], + "default" : "/var/lib/mysql", + "description" : "Location of mysql databases", + "display_name" : "MySQL Data Directory", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/ec2_path" : { "calculated" : false, + "choice" : [ ], + "default" : "/mnt/mysql", + "description" : "Location of mysql directory on EC2 instance EBS volumes", + "display_name" : "MySQL EC2 Path", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/server_root_password" : { "calculated" : false, + "choice" : [ ], + "default" : "randomly generated", + "description" : "Randomly generated password for the mysqld root user", + "display_name" : "MySQL Server Root Password", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/tunable" : { "calculated" : false, + "choice" : [ ], + "description" : "Hash of MySQL tunable attributes", + "display_name" : "MySQL Tunables", + "recipes" : [ ], + "required" : "optional", + "type" : "hash" + }, + "mysql/tunable/back_log" : { "calculated" : false, + "choice" : [ ], + "default" : "128", + "display_name" : "MySQL Tunable Back Log", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/tunable/key_buffer" : { "calculated" : false, + "choice" : [ ], + "default" : "250M", + "display_name" : "MySQL Tuntable Key Buffer", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/tunable/max_connections" : { "calculated" : false, + "choice" : [ ], + "default" : "800", + "display_name" : "MySQL Tunable Max Connections", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/tunable/max_heap_table_size" : { "calculated" : false, + "choice" : [ ], + "default" : "32M", + "display_name" : "MySQL Tunable Max Heap Table Size", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/tunable/net_read_timeout" : { "calculated" : false, + "choice" : [ ], + "default" : "30", + "display_name" : "MySQL Tunable Net Read Timeout", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/tunable/net_write_timeout" : { "calculated" : false, + "choice" : [ ], + "default" : "30", + "display_name" : "MySQL Tunable Net Write Timeout", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/tunable/table_cache" : { "calculated" : false, + "choice" : [ ], + "default" : "128", + "display_name" : "MySQL Tunable Table Cache", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + }, + "mysql/tunable/wait_timeout" : { "calculated" : false, + "choice" : [ ], + "default" : "180", + "display_name" : "MySQL Tunable Wait Timeout", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + } + }, + "conflicting" : { }, + "dependencies" : { "openssl" : "" }, + "description" : "Installs and configures mysql for client or server", + "groupings" : { }, + "license" : "Apache 2.0", + "long_description" : "= DESCRIPTION:\n\nInstalls and configures MySQL client or server.\n\n= REQUIREMENTS:\n\n== Platform:\n\nBest tested on Ubuntu 9.04,9.10. On EC2, requires platform that supports -o bind option for the 'mount' command.\n\n== Cookbooks:\n\nRequires Opscode's openssl cookbook for secure password generation.\n\n= ATTRIBUTES: \n\n* mysql[:server_root_password] - Set the server's root password with this, default is a randomly generated password with OpenSSL::Random.random_bytes.\n* mysql[:server_repl_password] - Set the replication user 'repl' password with this, default is a randomly generated password with OpenSSL::Random.random_bytes.\n* mysql[:server_debian_password] - Set the debian-sys-maint user password with this, default is a randomly generated password with OpenSSL::Random.random_bytes.\n* mysql[:bind_address] - Listen address for MySQLd, default is node's ipaddress.\n* mysql[:datadir] - Location for mysql data directory, default is \"/var/lib/mysql\" \n* mysql[:ec2_path] - location of mysql datadir on EC2 nodes, default \"/mnt/mysql\" \n\nPerformance tuning attributes, each corresponds to the same-named parameter in my.cnf; default values listed\n\n* mysql[:tunable][:key_buffer] = \"250M\"\n* mysql[:tunable][:max_connections] = \"800\" \n* mysql[:tunable][:wait_timeout] = \"180\" \n* mysql[:tunable][:net_write_timeout] = \"30\" \n* mysql[:tunable][:net_write_timeout] = \"30\" \n* mysql[:tunable][:back_log] = \"128\" \n* mysql[:tunable][:table_cache] = \"128\" \n* mysql[:tunable][:max_heap_table_size] = \"32M\" \n\n= USAGE:\n\nOn client nodes,\n\n include_recipe \"mysql::client\"\n \nAs the common use case is on systems with Ruby, we also install the MySQL RubyGem. Because we may want to be able to use the gem within another Chef recipe, we make sure the mysql development package and gem are installed first. The key is this:\n\n r = package ... do\n action :nothing\n end\n \n r.run_action(:install)\n \nThis creates a resource object for the package and does the installation before other recipes are parsed. You'll need to have the C compiler and such (ie, build-essential on Ubuntu) before running the recipes, but we already do that when installing Chef :-). If you want to be able to access a MySQL database via Ruby within another recipe, you could do so, like so:\n\n Gem.clear_paths # needed for Chef to find the gem...\n require 'mysql' # requires the mysql gem\n\n execute \"create #{node[:railsapp][:db][:database]} database\" do\n command \"/usr/bin/mysqladmin -u root -p#{node[:mysql][:server_root_password]} create #{node[:railsapp][:db][:database]}\"\n not_if do\n m = Mysql.new(\"localhost\", \"root\", @node[:mysql][:server_root_password])\n m.list_dbs.include?(@node[:railsapp][:db][:database])\n end\n end\n\nOn server nodes, \n\n include_recipe \"mysql::server\"\n \nOn Debian/Ubuntu this will preseed the MySQL package with the randomly generated root password. You can of course change the password afterward, but this makes sure that there's a good password set. You can view it in the node data in the Chef Server webui. Sets a new password for debian-sys-maint user as well.\n\nAlso sets up 'repl' user grants for replication slaves.\n\nOn EC2 nodes,\n\n include_recipe \"mysql::server_ec2\"\n \nWhen the ec2_path doesn't exist we look for a mounted filesystem (eg, EBS) and move the datadir there.\n\nThe client recipe is already included by server and 'default' recipes.\n\n= LICENSE and AUTHOR:\n \nAuthor:: Joshua Timberman ()\nAuthor:: AJ Christensen ()\n\nCopyright:: 2009, Opscode, Inc\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n", + "maintainer" : "Opscode, Inc.", + "maintainer_email" : "cookbooks@opscode.com", + "name" : "mysql", + "platforms" : { "debian" : "", + "ubuntu" : "" + }, + "providing" : { }, + "recipes" : { "mysql::client" : "Installs packages required for mysql clients using run_action magic", + "mysql::server" : "Installs packages required for mysql servers w/o manual intervention", + "mysql::server_ec2" : "Performs EC2-specific mountpoint manipulation" + }, + "recommendations" : { }, + "replacing" : { }, + "suggestions" : { }, + "version" : "0.21.2" + }, + "name" : "mysql-0.21.2", + "providers" : [ { "checksum" : "b994881a2aba60e32c4b6408ffba993d", + "name" : "database.rb", + "path" : "providers/database.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-b994881a2aba60e32c4b6408ffba993d?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=2XMRbryCmEqirCWLCvrXoenYubw%3D" + } ], + "recipes" : [ { "checksum" : "f51bd8122b7dccc9f4656319fef3252a", + "name" : "server_ec2.rb", + "path" : "recipes/server_ec2.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-f51bd8122b7dccc9f4656319fef3252a?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=BUR2mosCvmoOKq4Mkh3JUG0MY38%3D" + }, + { "checksum" : "80daa897597560372d017c58c4df0e3c", + "name" : "server.rb", + "path" : "recipes/server.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-80daa897597560372d017c58c4df0e3c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=bU3j9Nw%2BnuIroXKrlJZe7tjaugA%3D" + }, + { "checksum" : "bd3ba2d05dea6a8cf0dc2a45f540cc32", + "name" : "default.rb", + "path" : "recipes/default.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-bd3ba2d05dea6a8cf0dc2a45f540cc32?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=7haumT5EtEM2h8l32efqV%2Fik%2BdY%3D" + }, + { "checksum" : "a1d679c7480267cd9b69e3194c7e45ab", + "name" : "client.rb", + "path" : "recipes/client.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-a1d679c7480267cd9b69e3194c7e45ab?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=ZhfTiwv1aXC7HZMnW8A7i4vkMCM%3D" + } + ], + "resources" : [ { "checksum" : "8aa8e2cafe54c2932c7aa65d62ec2695", + "name" : "database.rb", + "path" : "resources/database.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-8aa8e2cafe54c2932c7aa65d62ec2695?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=6URS94f1HpRibHC%2FhBkr7Eg3dVA%3D" + } ], + "root_files" : [ { "checksum" : "e9278fc99fd668bdce33d72dc71fade9", + "name" : "README.rdoc", + "path" : "README.rdoc", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-e9278fc99fd668bdce33d72dc71fade9?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=KPgAGqShEO5SGzz8oRdwIInPUOc%3D" + }, + { "checksum" : "8d2f9635f4817ff905a4124e09ec6c59", + "name" : "metadata.rb", + "path" : "metadata.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-8d2f9635f4817ff905a4124e09ec6c59?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=fPF2iY7tNrq%2FuNrCjRLImP9vRbA%3D" + }, + { "checksum" : "e6804b8f3e6dfdbbece9d319537ffea1", + "name" : "metadata.json", + "path" : "metadata.json", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-e6804b8f3e6dfdbbece9d319537ffea1?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=EVsALLreeAA41%2BiPAfPt%2FxFEIYI%3D" + } + ], + "templates" : [ { "checksum" : "689c1b6fbb242b6c508384e56646341d", + "name" : "my.cnf.erb", + "path" : "templates/ubuntu-9.10/my.cnf.erb", + "specificity" : "ubuntu-9.10", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-689c1b6fbb242b6c508384e56646341d?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=2ugp0XVvvUktYdBxfC9bCZBjOs4%3D" + }, + { "checksum" : "16b036a0bb31957a77e9b825cf616cc5", + "name" : "mysql-server.seed.erb", + "path" : "templates/default/mysql-server.seed.erb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-16b036a0bb31957a77e9b825cf616cc5?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=50bRvt6GQqFEcfYtaIsq1d4a4c8%3D" + }, + { "checksum" : "932b51ddddcbd24ee10a76ecae33b8ba", + "name" : "grants.sql.erb", + "path" : "templates/default/grants.sql.erb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-932b51ddddcbd24ee10a76ecae33b8ba?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=RHR0obLFcsN1M9tL28IH4Tcur5g%3D" + }, + { "checksum" : "7746560b37ac8d4a0cf68befbecbd8a3", + "name" : "my.cnf.erb", + "path" : "templates/default/my.cnf.erb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-7746560b37ac8d4a0cf68befbecbd8a3?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=W7Nqkvhw2TBrlDvcM2rlA4Oj5%2Bk%3D" + }, + { "checksum" : "63bd67fae6d297e8f658e9c0ad01a411", + "name" : "my.cnf.erb", + "path" : "templates/centos/my.cnf.erb", + "specificity" : "centos", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-63bd67fae6d297e8f658e9c0ad01a411?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=oFcRya56f%2F4oJBGrIvk4XcWQFm4%3D" + }, + { "checksum" : "689c1b6fbb242b6c508384e56646341d", + "name" : "my.cnf.erb", + "path" : "templates/ubuntu-10.04/my.cnf.erb", + "specificity" : "ubuntu-10.04", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-689c1b6fbb242b6c508384e56646341d?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=2ugp0XVvvUktYdBxfC9bCZBjOs4%3D" + }, + { "checksum" : "63bd67fae6d297e8f658e9c0ad01a411", + "name" : "my.cnf.erb", + "path" : "templates/redhat/my.cnf.erb", + "specificity" : "redhat", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-63bd67fae6d297e8f658e9c0ad01a411?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=oFcRya56f%2F4oJBGrIvk4XcWQFm4%3D" + }, + { "checksum" : "d2244150a145b3f658cd37c13269fafc", + "name" : "port_mysql.erb", + "path" : "templates/default/port_mysql.erb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-d2244150a145b3f658cd37c13269fafc?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=23iHcjwpNOvlNf%2BlrKcV2pkU7uo%3D" + }, + { "checksum" : "2e08553db526f5f80c28b343f6a616cb", + "name" : "debian.cnf.erb", + "path" : "templates/default/debian.cnf.erb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-2e08553db526f5f80c28b343f6a616cb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=VdcFYxnLUkj1tS3k8DovrzZEA7E%3D" + }, + { "checksum" : "1e5068eec65b51f5a327580fb0af4677", + "name" : "my.cnf.erb", + "path" : "templates/ubuntu-8.04/my.cnf.erb", + "specificity" : "ubuntu-8.04", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-1e5068eec65b51f5a327580fb0af4677?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277774082&Signature=D5lPeu1UQvA9pEXZm5nVOwj3WIo%3D" + } + ], + "version" : "0.21.2" +} \ No newline at end of file diff --git a/apis/chef/src/test/resources/newclient.txt b/apis/chef/src/test/resources/newclient.txt deleted file mode 100644 index c1e93687b7..0000000000 --- a/apis/chef/src/test/resources/newclient.txt +++ /dev/null @@ -1 +0,0 @@ -{"clientname":"adriancole-jcloudstest","private_key":"-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2\npopCBQwjpOnlgpdd/+C+TESl30ojauvVej9AbgJb30Jl7e7dEX4Brncnj03G+mo+\nG4osf7I2PA/6+9Ol7xamK9GL/cs8nOb17cRTWmhTRW7+3Rrli/s6wzqQXjGjWzgz\nthXv7FOPHA87UjJzrePBFta7+S8BxKCG2QaTxzNGytSAy8KBX8BUrSt5+X22QjEM\nQF3zA4TPtoWp/lcDRzCMdffMYoVPZzKqIeEFSexwvNlJ/qU6hbcyAxab1lYawjKU\nRgvPCflVYTIw6teHNqkyvTPX+lpIAVXigSVQXwIDAQABAoIBAHz81xvTSSjzaYFO\n9Gh13QcnuSdSEi0fo4f/zdLOBY2UVVo3nW9umskX46w0ZAAd4qn0d9gfdMZwjtjR\nfoLRO8i2VnPltnt1n64P/DtoXcb03EVPLQvh4feXGVJcMOpz0TKgYmyax+W3DE6M\ne+Az1JplUELo6crgLCSapA63SK85PEuWAcMUQg9s6MnzB/qXz95yJlzgjVMIJUyb\n9jFdq2s0gefTpK2cKeSYWQAFPd41Ea5v/3j0LN8qs/dImNnzxDXu+hi8+16/4PTK\npl+1bJXwE9YkWPdd39EfjVkk6q/HyFijK3VpHnOy7n3iaJTUKwBJLRsFrQ5Eor3U\nvNKyGXECgYEA3RZdFC6MRBAo76GKd9axbA0G9Bmct9pQT4B+od2AGGOdiYzYRWfF\nlyTgctY9dcfsX5DBQFUHNnYXMHHI0wHQk1m20UpFLa7IV3RWkW5JwYkbQHmeP4pn\np8GtJEXC+4PrT0Pc32acfWozArokUju7nLLazCPCDdfc8t9MPX1W230CgYEA2MbB\ndwdwLZx9zEqZ0MciRxjsOA30b6OYPOqMP1ADVeExPN8fHLCAQjwUExQa86+FMV4H\nOtu+DXlisp+TSTRQzpXMfGppupbK1j5cqz2sU37upKuz/uf0XyeyBLOi0y9/DMl5\njG2StLLIMawRqJRUuq/fyA/6oTzADNwoW6LjCgsCgYBGvCj7lAj8nc77HEwZG2+Y\ninJ3Ftq1V/vp88qQLzYUl4qHv7BSRGlLelj1ZOY1EMnnqYCq/IlaO14f+ceu+x2o\nh0OeooyPmSQwFuC7lvWyHhPCBSdEXRvc6HJk8Iz5u7NFoQjB0SqwVZIMhVGpncLg\n17h5J9emZjIi4p6Z7cgkYQKBgHt+/8in3Cif9qrj9S0TxVtrv2dPy+mt8ZUCqlOH\nad8LI9nh4v+dLfSN9YHI+nHJlL/DKatGdMeIV8obTvVtcHvAq3ZVyVYbggL8FB8a\nS4plzd7SUwDtdDKhkrFLBX/6lw7Z2P0/j0ySbaqetJCtsHeKqpp3P/mLen3ZDsTl\nzyJxAoGBAIxl1SGzu3lO3BQ5+EPaprNw3eN3nzG4WLQvnzZwpeAFS+E5pllMkIfs\nu01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ\nlMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o\n-----END RSA PRIVATE KEY-----\n","uri":"https://api.opscode.com/organizations/jclouds/clients/adriancole-jcloudstest","certificate":"-----BEGIN CERTIFICATE-----\nMIIClzCCAgCgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxFjAUBgNVBAoM\nDU9wc2NvZGUsIEluYy4xHDAaBgNVBAsME0NlcnRpZmljYXRlIFNlcnZpY2UxMjAw\nBgNVBAMMKW9wc2NvZGUuY29tL2VtYWlsQWRkcmVzcz1hdXRoQG9wc2NvZGUuY29t\nMB4XDTEwMDYwNDIzMzM0NloXDTIwMDYwMTIzMzM0NlowADCCASIwDQYJKoZIhvcN\nAQEBBQADggEPADCCAQoCggEBALs2hOms4FMcBEl9awhnSecaXa3NVwt9dWzhmQQh\nPDQPgqRYdqaKQgUMI6Tp5YKXXf/gvkxEpd9KI2rr1Xo/QG4CW99CZe3u3RF+Aa53\nJ49NxvpqPhuKLH+yNjwP+vvTpe8WpivRi/3LPJzm9e3EU1poU0Vu/t0a5Yv7OsM6\nkF4xo1s4M7YV7+xTjxwPO1Iyc63jwRbWu/kvAcSghtkGk8czRsrUgMvCgV/AVK0r\nefl9tkIxDEBd8wOEz7aFqf5XA0cwjHX3zGKFT2cyqiHhBUnscLzZSf6lOoW3MgMW\nm9ZWGsIylEYLzwn5VWEyMOrXhzapMr0z1/paSAFV4oElUF8CAwEAATANBgkqhkiG\n9w0BAQUFAAOBgQCTllbpWNagYjCiaU5UnjIFXn0YyNfZzqCh8SQ0Asj8MtksVbFG\nAErp03+Cb9a7GTdNE7fIyPsLTnGzFhqTwKN+3jIj4wgxhrbYXF73x1+rDRyHjJu7\na7gdTEYZqWiAHdW47vXj69W1dB5e4vNm1F29gOSL/x7BMAyjLFWbdbKw0w==\n-----END CERTIFICATE-----\n","orgname":"jclouds} \ No newline at end of file diff --git a/apis/chef/src/test/resources/node.json b/apis/chef/src/test/resources/node.json index ecdb470009..c8ddaeff0c 100644 --- a/apis/chef/src/test/resources/node.json +++ b/apis/chef/src/test/resources/node.json @@ -1,2 +1,10 @@ -{"normal":{"tomcat6":{"ssl_port":8433}},"name":"adrian-jcloudstest","override":{},"default":{},"json_class":"Chef::Node","automatic":{},"run_list":["recipe[java]"],"chef_type":"node","chef_environment": "prod"} - +{ "automatic" : { }, + "chef_environment" : "prod", + "chef_type" : "node", + "default" : { }, + "json_class" : "Chef::Node", + "name" : "adrian-jcloudstest", + "normal" : { "tomcat6" : { "ssl_port" : 8433 } }, + "override" : { }, + "run_list" : [ "recipe[java]" ] +} \ No newline at end of file diff --git a/apis/chef/src/test/resources/tomcat-cookbook.json b/apis/chef/src/test/resources/tomcat-cookbook.json index 6331b514ac..992f40105c 100644 --- a/apis/chef/src/test/resources/tomcat-cookbook.json +++ b/apis/chef/src/test/resources/tomcat-cookbook.json @@ -1 +1,121 @@ -{"definitions":[],"name":"tomcat6-0.1.0","files":[{"name":"org.apache.tomcat.tomcat6.plist","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-18e534a72652f3d53b197ca4e5027009?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=M3fBL4t7uuYVXVah2PyZ8eL1QCc%3D","checksum":"18e534a72652f3d53b197ca4e5027009","path":"files/default/org.apache.tomcat.tomcat6.plist","specificity":"default"},{"name":"logging.properties","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-6a35ce92050296862ea63b784529d2e0?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=vRlKoye2%2Fwz8mdQI%2F3Ht916sllE%3D","checksum":"6a35ce92050296862ea63b784529d2e0","path":"files/default/logging.properties","specificity":"default"}],"attributes":[{"name":"tomcat6.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-6e3fd0d16a87a55c569da108194ecb29?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=zvYjsgUXIC7Xj3MT8Wd93esDGJM%3D","checksum":"6e3fd0d16a87a55c569da108194ecb29","path":"attributes/tomcat6.rb","specificity":"default"}],"json_class":"Chef::CookbookVersion","providers":[],"metadata":{"dependencies":{},"name":"tomcat6","maintainer_email":"cookbooks@opscode.com","license":"Apache 2.0","attributes":{"tomcat6/with_native":{"required":"optional","calculated":false,"default":"false","choice":[],"type":"string","recipes":[],"display_name":"Tomcat native support","description":"works for centos, install tomcat-native libraries"}},"maintainer":"Opscode, Inc.","suggestions":{},"platforms":{"debian":[],"centos":[],"ubuntu":[],"redhat":[]},"long_description":"= DESCRIPTION:\n\nInstalls Tomcat6\n\n= REQUIREMENTS:\n\n== Platform and Application Environment:\n\nTested on Centos 5.2 8.10. May work on other platforms, esp Redhat.\nNeeds Java at least Java 5\n\n== Cookbooks:\n\nOpscode cookbooks, http://github.com/opscode/cookbooks/tree/master:\n\n* java\n\n= ATTRIBUTES: \n\n= USAGE:\n\n\n= LICENSE and AUTHOR:\n \nAuthor:: Edmund Haselwanter ()\nCopyright:: 2009, Edmund Haselwanter\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","version":"0.1.0","recommendations":{},"conflicting":{},"recipes":{"tomcat6":"Main Tomcat 6 configuration"},"groupings":{},"description":"Installs and configures all aspects of tomcat6 using custom local installation","replacing":{},"providing":{}},"libraries":[{"name":"tomcat_manager.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-2b6f7847142bb36823c570899669c54b?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=zxIoUKcGYWo9ir6qf1tTy3wvKZ4%3D","checksum":"2b6f7847142bb36823c570899669c54b","path":"libraries/tomcat_manager.rb","specificity":"default"},{"name":"tomcat.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-24db7b7dd6f04f8da5fa2b282910ac08?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=c4Gbn5kX0ZaPbWvk5LAcR77sITg%3D","checksum":"24db7b7dd6f04f8da5fa2b282910ac08","path":"libraries/tomcat.rb","specificity":"default"}],"templates":[{"name":"tomcat-users.xml.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-107263b81e4700cf0adad7af2a133bbd?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=QC7MNIauR2ox5MVlohf2i73uM1s%3D","checksum":"107263b81e4700cf0adad7af2a133bbd","path":"templates/default/tomcat-users.xml.erb","specificity":"default"},{"name":"sv-tomcat6-run.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-fa4432b353fa57b9da26a4bff44285f2?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=q2rDeJFeh4oyhfv9ExMifGB0wxo%3D","checksum":"fa4432b353fa57b9da26a4bff44285f2","path":"templates/default/sv-tomcat6-run.erb","specificity":"default"},{"name":"manager.xml.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-33fd6f63133e7ebe28bc62e58773c408?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=rIijEhwLPf5PWTJOg%2BElbOquPBM%3D","checksum":"33fd6f63133e7ebe28bc62e58773c408","path":"templates/default/manager.xml.erb","specificity":"default"},{"name":"sv-tomcat6-log-run.erb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-09f2bf988663175cd1b7973198dfb5eb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=UnfNDP4pDzPM3PoLcLWyTnTa%2FKI%3D","checksum":"09f2bf988663175cd1b7973198dfb5eb","path":"templates/default/sv-tomcat6-log-run.erb","specificity":"default"}],"resources":[],"cookbook_name":"tomcat6","version":"0.1.0","recipes":[{"name":"default.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-d45661e4b50f9677de7b8684af26ff9d?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=r3CvyVe7dcOzB%2F0fNAun5ldGwr8%3D","checksum":"d45661e4b50f9677de7b8684af26ff9d","path":"recipes/default.rb","specificity":"default"}],"root_files":[{"name":"README.rdoc","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-14f6977f68c3674484e8289e361fb5a4?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=VNZxN%2B7CxO7ZbDHJOS%2FaTtpkPaE%3D","checksum":"14f6977f68c3674484e8289e361fb5a4","path":"README.rdoc","specificity":"default"},{"name":"metadata.rb","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-abc416ffba9ea64ca71635191cb87af6?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=pemynt9Q1F%2BxlS26kLaz%2F4NDGO4%3D","checksum":"abc416ffba9ea64ca71635191cb87af6","path":"metadata.rb","specificity":"default"},{"name":"metadata.json","url":"https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-dd8473a8a7f2b446250ecdefb1882a5e?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=sHpayqP%2Fe4Luv20EMa3q%2FaMN4ms%3D","checksum":"dd8473a8a7f2b446250ecdefb1882a5e","path":"metadata.json","specificity":"default"}],"chef_type":"cookbook_version"} \ No newline at end of file +{ "attributes" : [ { "checksum" : "6e3fd0d16a87a55c569da108194ecb29", + "name" : "tomcat6.rb", + "path" : "attributes/tomcat6.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-6e3fd0d16a87a55c569da108194ecb29?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=zvYjsgUXIC7Xj3MT8Wd93esDGJM%3D" + } ], + "chef_type" : "cookbook_version", + "cookbook_name" : "tomcat6", + "definitions" : [ ], + "files" : [ { "checksum" : "18e534a72652f3d53b197ca4e5027009", + "name" : "org.apache.tomcat.tomcat6.plist", + "path" : "files/default/org.apache.tomcat.tomcat6.plist", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-18e534a72652f3d53b197ca4e5027009?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=M3fBL4t7uuYVXVah2PyZ8eL1QCc%3D" + }, + { "checksum" : "6a35ce92050296862ea63b784529d2e0", + "name" : "logging.properties", + "path" : "files/default/logging.properties", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-6a35ce92050296862ea63b784529d2e0?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=vRlKoye2%2Fwz8mdQI%2F3Ht916sllE%3D" + } + ], + "json_class" : "Chef::CookbookVersion", + "libraries" : [ { "checksum" : "2b6f7847142bb36823c570899669c54b", + "name" : "tomcat_manager.rb", + "path" : "libraries/tomcat_manager.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-2b6f7847142bb36823c570899669c54b?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=zxIoUKcGYWo9ir6qf1tTy3wvKZ4%3D" + }, + { "checksum" : "24db7b7dd6f04f8da5fa2b282910ac08", + "name" : "tomcat.rb", + "path" : "libraries/tomcat.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-24db7b7dd6f04f8da5fa2b282910ac08?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=c4Gbn5kX0ZaPbWvk5LAcR77sITg%3D" + } + ], + "metadata" : { "attributes" : { "tomcat6/with_native" : { "calculated" : false, + "choice" : [ ], + "default" : "false", + "description" : "works for centos, install tomcat-native libraries", + "display_name" : "Tomcat native support", + "recipes" : [ ], + "required" : "optional", + "type" : "string" + } }, + "conflicting" : { }, + "dependencies" : { }, + "description" : "Installs and configures all aspects of tomcat6 using custom local installation", + "groupings" : { }, + "license" : "Apache 2.0", + "long_description" : "= DESCRIPTION:\n\nInstalls Tomcat6\n\n= REQUIREMENTS:\n\n== Platform and Application Environment:\n\nTested on Centos 5.2 8.10. May work on other platforms, esp Redhat.\nNeeds Java at least Java 5\n\n== Cookbooks:\n\nOpscode cookbooks, http://github.com/opscode/cookbooks/tree/master:\n\n* java\n\n= ATTRIBUTES: \n\n= USAGE:\n\n\n= LICENSE and AUTHOR:\n \nAuthor:: Edmund Haselwanter ()\nCopyright:: 2009, Edmund Haselwanter\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n", + "maintainer" : "Opscode, Inc.", + "maintainer_email" : "cookbooks@opscode.com", + "name" : "tomcat6", + "platforms" : { "centos" : "", + "debian" : "", + "redhat" : "", + "ubuntu" : "" + }, + "providing" : { }, + "recipes" : { "tomcat6" : "Main Tomcat 6 configuration" }, + "recommendations" : { }, + "replacing" : { }, + "suggestions" : { }, + "version" : "0.1.0" + }, + "name" : "tomcat6-0.1.0", + "providers" : [ ], + "recipes" : [ { "checksum" : "d45661e4b50f9677de7b8684af26ff9d", + "name" : "default.rb", + "path" : "recipes/default.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-d45661e4b50f9677de7b8684af26ff9d?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=r3CvyVe7dcOzB%2F0fNAun5ldGwr8%3D" + } ], + "resources" : [ ], + "root_files" : [ { "checksum" : "14f6977f68c3674484e8289e361fb5a4", + "name" : "README.rdoc", + "path" : "README.rdoc", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-14f6977f68c3674484e8289e361fb5a4?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=VNZxN%2B7CxO7ZbDHJOS%2FaTtpkPaE%3D" + }, + { "checksum" : "abc416ffba9ea64ca71635191cb87af6", + "name" : "metadata.rb", + "path" : "metadata.rb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-abc416ffba9ea64ca71635191cb87af6?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=pemynt9Q1F%2BxlS26kLaz%2F4NDGO4%3D" + }, + { "checksum" : "dd8473a8a7f2b446250ecdefb1882a5e", + "name" : "metadata.json", + "path" : "metadata.json", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-dd8473a8a7f2b446250ecdefb1882a5e?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=sHpayqP%2Fe4Luv20EMa3q%2FaMN4ms%3D" + } + ], + "templates" : [ { "checksum" : "107263b81e4700cf0adad7af2a133bbd", + "name" : "tomcat-users.xml.erb", + "path" : "templates/default/tomcat-users.xml.erb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-107263b81e4700cf0adad7af2a133bbd?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=QC7MNIauR2ox5MVlohf2i73uM1s%3D" + }, + { "checksum" : "fa4432b353fa57b9da26a4bff44285f2", + "name" : "sv-tomcat6-run.erb", + "path" : "templates/default/sv-tomcat6-run.erb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-fa4432b353fa57b9da26a4bff44285f2?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=q2rDeJFeh4oyhfv9ExMifGB0wxo%3D" + }, + { "checksum" : "33fd6f63133e7ebe28bc62e58773c408", + "name" : "manager.xml.erb", + "path" : "templates/default/manager.xml.erb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-33fd6f63133e7ebe28bc62e58773c408?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=rIijEhwLPf5PWTJOg%2BElbOquPBM%3D" + }, + { "checksum" : "09f2bf988663175cd1b7973198dfb5eb", + "name" : "sv-tomcat6-log-run.erb", + "path" : "templates/default/sv-tomcat6-log-run.erb", + "specificity" : "default", + "url" : "https://s3.amazonaws.com/opscode-platform-production-data/organization-486ca3ac66264fea926aa0b4ff74341c/checksum-09f2bf988663175cd1b7973198dfb5eb?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1277771874&Signature=UnfNDP4pDzPM3PoLcLWyTnTa%2FKI%3D" + } + ], + "version" : "0.1.0" +} \ No newline at end of file