mirror of https://github.com/apache/jclouds.git
Issue 191: added in-memory chef-client; use provider: transientchef
This commit is contained in:
parent
420503d32e
commit
4b76982261
|
@ -45,6 +45,7 @@ import java.io.ObjectOutput;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -274,6 +275,13 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
return immediateFuture(null);
|
return immediateFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ListenableFuture<Blob> removeBlobAndReturnOld(String container, String key) {
|
||||||
|
if (getContainerToBlobs().containsKey(container)) {
|
||||||
|
return immediateFuture(getContainerToBlobs().get(container).remove(key));
|
||||||
|
}
|
||||||
|
return immediateFuture(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -346,6 +354,20 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
return immediateFuture(getContainerToBlobs().containsKey(name));
|
return immediateFuture(getContainerToBlobs().containsKey(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* throws IllegalStateException if the container already exists
|
||||||
|
*/
|
||||||
|
public ListenableFuture<Void> createContainerInLocationIfAbsent(final Location location, final String name) {
|
||||||
|
ConcurrentMap<String, Blob> container = getContainerToBlobs().putIfAbsent(name,
|
||||||
|
new ConcurrentHashMap<String, Blob>());
|
||||||
|
if (container == null) {
|
||||||
|
getContainerToLocation().put(name, location != null ? location : defaultLocation);
|
||||||
|
return immediateFuture((Void) null);
|
||||||
|
} else {
|
||||||
|
return Futures.immediateFailedFuture(new IllegalStateException("container " + name + " already exists"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getFirstQueryOrNull(String string, @Nullable HttpRequestOptions options) {
|
public String getFirstQueryOrNull(String string, @Nullable HttpRequestOptions options) {
|
||||||
if (options == null)
|
if (options == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -454,33 +476,54 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<String> putBlob(String containerName, Blob object) {
|
public ListenableFuture<String> putBlob(String containerName, Blob in) {
|
||||||
Map<String, Blob> container = getContainerToBlobs().get(containerName);
|
ConcurrentMap<String, Blob> container = getContainerToBlobs().get(containerName);
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
new RuntimeException("containerName not found: " + containerName);
|
new IllegalStateException("containerName not found: " + containerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteArrayPayload payload = (object.getPayload() instanceof ByteArrayPayload) ? ByteArrayPayload.class.cast(object
|
Blob blob = createUpdatedCopyOfBlob(in);
|
||||||
|
|
||||||
|
container.put(blob.getMetadata().getName(), blob);
|
||||||
|
|
||||||
|
return immediateFuture(Iterables.getOnlyElement(blob.getAllHeaders().get(HttpHeaders.ETAG)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListenableFuture<Blob> putBlobAndReturnOld(String containerName, Blob in) {
|
||||||
|
ConcurrentMap<String, Blob> container = getContainerToBlobs().get(containerName);
|
||||||
|
if (container == null) {
|
||||||
|
new IllegalStateException("containerName not found: " + containerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
Blob blob = createUpdatedCopyOfBlob(in);
|
||||||
|
|
||||||
|
Blob old = container.put(blob.getMetadata().getName(), blob);
|
||||||
|
|
||||||
|
return immediateFuture(old);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Blob createUpdatedCopyOfBlob(Blob in) {
|
||||||
|
ByteArrayPayload payload = (in.getPayload() instanceof ByteArrayPayload) ? ByteArrayPayload.class.cast(in
|
||||||
.getPayload()) : null;
|
.getPayload()) : null;
|
||||||
if (payload == null)
|
if (payload == null)
|
||||||
payload = (object.getPayload() instanceof DelegatingPayload) ? (DelegatingPayload.class.cast(
|
payload = (in.getPayload() instanceof DelegatingPayload) ? (DelegatingPayload.class.cast(in.getPayload())
|
||||||
object.getPayload()).getDelegate() instanceof ByteArrayPayload) ? ByteArrayPayload.class
|
.getDelegate() instanceof ByteArrayPayload) ? ByteArrayPayload.class.cast(DelegatingPayload.class.cast(
|
||||||
.cast(DelegatingPayload.class.cast(object.getPayload()).getDelegate()) : null : null;
|
in.getPayload()).getDelegate()) : null : null;
|
||||||
try {
|
try {
|
||||||
if (payload == null || !(payload instanceof ByteArrayPayload)) {
|
if (payload == null || !(payload instanceof ByteArrayPayload)) {
|
||||||
String oldContentType = object.getPayload().getContentType();
|
String oldContentType = in.getPayload().getContentType();
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
object.getPayload().writeTo(out);
|
in.getPayload().writeTo(out);
|
||||||
payload = (ByteArrayPayload) Payloads.calculateMD5(Payloads.newPayload(out.toByteArray()));
|
payload = (ByteArrayPayload) Payloads.calculateMD5(Payloads.newPayload(out.toByteArray()));
|
||||||
payload.setContentType(oldContentType);
|
payload.setContentType(oldContentType);
|
||||||
} else {
|
} else {
|
||||||
if (payload.getContentMD5() == null)
|
if (payload.getContentMD5() == null)
|
||||||
Payloads.calculateMD5(object, crypto.md5());
|
Payloads.calculateMD5(in, crypto.md5());
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
Blob blob = blobFactory.create(copy(object.getMetadata()));
|
Blob blob = blobFactory.create(copy(in.getMetadata()));
|
||||||
blob.setPayload(payload);
|
blob.setPayload(payload);
|
||||||
blob.getMetadata().setLastModified(new Date());
|
blob.getMetadata().setLastModified(new Date());
|
||||||
blob.getMetadata().setSize(payload.getContentLength());
|
blob.getMetadata().setSize(payload.getContentLength());
|
||||||
|
@ -489,18 +532,17 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore {
|
||||||
|
|
||||||
String eTag = CryptoStreams.hex(payload.getContentMD5());
|
String eTag = CryptoStreams.hex(payload.getContentMD5());
|
||||||
blob.getMetadata().setETag(eTag);
|
blob.getMetadata().setETag(eTag);
|
||||||
container.put(blob.getMetadata().getName(), blob);
|
|
||||||
|
|
||||||
// Set HTTP headers to match metadata
|
// Set HTTP headers to match metadata
|
||||||
blob.getAllHeaders().put(HttpHeaders.LAST_MODIFIED,
|
blob.getAllHeaders().replaceValues(HttpHeaders.LAST_MODIFIED,
|
||||||
dateService.rfc822DateFormat(blob.getMetadata().getLastModified()));
|
Collections.singleton(dateService.rfc822DateFormat(blob.getMetadata().getLastModified())));
|
||||||
blob.getAllHeaders().put(HttpHeaders.ETAG, eTag);
|
blob.getAllHeaders().replaceValues(HttpHeaders.ETAG, Collections.singleton(eTag));
|
||||||
blob.getAllHeaders().put(HttpHeaders.CONTENT_TYPE, payload.getContentType());
|
blob.getAllHeaders().replaceValues(HttpHeaders.CONTENT_TYPE, Collections.singleton(payload.getContentType()));
|
||||||
blob.getAllHeaders().put(HttpHeaders.CONTENT_LENGTH, payload.getContentLength() + "");
|
blob.getAllHeaders().replaceValues(HttpHeaders.CONTENT_LENGTH,
|
||||||
blob.getAllHeaders().put("Content-MD5", CryptoStreams.base64(payload.getContentMD5()));
|
Collections.singleton(payload.getContentLength() + ""));
|
||||||
|
blob.getAllHeaders().replaceValues("Content-MD5",
|
||||||
|
Collections.singleton(CryptoStreams.base64(payload.getContentMD5())));
|
||||||
blob.getAllHeaders().putAll(Multimaps.forMap(blob.getMetadata().getUserMetadata()));
|
blob.getAllHeaders().putAll(Multimaps.forMap(blob.getMetadata().getUserMetadata()));
|
||||||
|
return blob;
|
||||||
return immediateFuture(eTag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!--
|
||||||
$HeadURL$ $Revision$ $Date$ Copyright (C) 2010 Cloud Conscious, LLC
|
Copyright (C) 2010 Cloud Conscious, LLC <info@cloudconscious.com>
|
||||||
<info@cloudconscious.com>
|
|
||||||
|
|
||||||
====================================================================
|
====================================================================
|
||||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
@ -97,5 +96,12 @@
|
||||||
<version>1.1</version>
|
<version>1.1</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- for transient chef provider -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-blobstore</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -30,12 +30,16 @@ which is basically Chef Server as a Service.
|
||||||
;; load the rsa key from ~/.chef/CLIENT_NAME.pem
|
;; load the rsa key from ~/.chef/CLIENT_NAME.pem
|
||||||
(def credential (load-pem client))
|
(def credential (load-pem client))
|
||||||
|
|
||||||
(def chef (chef-service client credential :chef.endpoint \"https://api.opscode.com/organizations/YOUR_ORG\"))
|
;; create a connection to the opscode platform
|
||||||
|
(def chef (chef-service \"chef\" client credential :chef.endpoint \"https://api.opscode.com/organizations/YOUR_ORG\"))
|
||||||
|
|
||||||
(with-chef-service [chef]
|
(with-chef-service [chef]
|
||||||
(create-databag \"cluster-config\")
|
(create-databag \"cluster-config\")
|
||||||
(update-databag-item \"cluster-config\" {:id \"master\" :name \"myhost.com\"}))
|
(update-databag-item \"cluster-config\" {:id \"master\" :name \"myhost.com\"}))
|
||||||
|
|
||||||
|
;; note that you can create your chef connection like this to do in-memory testing
|
||||||
|
(def chef (chef-service \"transientchef\" \"\" \"\"))
|
||||||
|
|
||||||
See http://code.google.com/p/jclouds for details."}
|
See http://code.google.com/p/jclouds for details."}
|
||||||
org.jclouds.chef
|
org.jclouds.chef
|
||||||
(:use [org.jclouds.core])
|
(:use [org.jclouds.core])
|
||||||
|
@ -57,18 +61,26 @@ See http://code.google.com/p/jclouds for details."}
|
||||||
([#^String identity]
|
([#^String identity]
|
||||||
(slurp (str (. System getProperty "user.home") "/.chef/" identity ".pem"))))
|
(slurp (str (. System getProperty "user.home") "/.chef/" identity ".pem"))))
|
||||||
|
|
||||||
|
;; TODO find a way to pass the chef provider by default
|
||||||
|
|
||||||
(defn chef-service
|
(defn chef-service
|
||||||
"Create a logged in context."
|
"Create a logged in context to a chef server.
|
||||||
([#^String identity #^String credential & options]
|
|
||||||
(let [module-keys (set (keys module-lookup))
|
provider \"chef\" is a remote connection, and you can pass the option
|
||||||
ext-modules (filter #(module-keys %) options)
|
:chef.endpoint \"https://url\" to override the endpoint
|
||||||
opts (apply hash-map (filter #(not (module-keys %)) options))]
|
|
||||||
(.. (ChefContextFactory.)
|
provider \"transientchef\" is for in-memory when you are looking to do
|
||||||
(createContext identity credential
|
unit testing"
|
||||||
(apply modules (concat ext-modules (opts :extensions)))
|
([#^String provider #^String identity #^String credential & options]
|
||||||
(reduce #(do (.put %1 (name (first %2)) (second %2)) %1)
|
(let [module-keys (set (keys module-lookup))
|
||||||
(Properties.) (dissoc opts :extensions)))
|
ext-modules (filter #(module-keys %) options)
|
||||||
(getChefService)))))
|
opts (apply hash-map (filter #(not (module-keys %)) options))]
|
||||||
|
(.. (ChefContextFactory.)
|
||||||
|
(createContext provider identity credential
|
||||||
|
(apply modules (concat ext-modules (opts :extensions)))
|
||||||
|
(reduce #(do (.put %1 (name (first %2)) (second %2)) %1)
|
||||||
|
(Properties.) (dissoc opts :extensions)))
|
||||||
|
(getChefService)))))
|
||||||
|
|
||||||
(defn chef-context
|
(defn chef-context
|
||||||
"Returns a chef context from a chef service."
|
"Returns a chef context from a chef service."
|
||||||
|
@ -125,6 +137,13 @@ See http://code.google.com/p/jclouds for details."}
|
||||||
([#^ChefService chef]
|
([#^ChefService chef]
|
||||||
(seq (.listDatabags (as-chef-api chef)))))
|
(seq (.listDatabags (as-chef-api chef)))))
|
||||||
|
|
||||||
|
(defn databag-exists?
|
||||||
|
"Predicate to check presence of a databag"
|
||||||
|
([databag-name]
|
||||||
|
(databag-exists? databag-name *chef*))
|
||||||
|
([databag-name #^ChefService chef]
|
||||||
|
(.databagExists (as-chef-api chef) databag-name)))
|
||||||
|
|
||||||
(defn delete-databag
|
(defn delete-databag
|
||||||
"Delete a data bag, including its items"
|
"Delete a data bag, including its items"
|
||||||
([databag]
|
([databag]
|
||||||
|
@ -146,6 +165,13 @@ See http://code.google.com/p/jclouds for details."}
|
||||||
([databag chef]
|
([databag chef]
|
||||||
(seq (.listDatabagItems (as-chef-api chef) databag))))
|
(seq (.listDatabagItems (as-chef-api chef) databag))))
|
||||||
|
|
||||||
|
(defn databag-item-exists?
|
||||||
|
"Predicate to check presence of a databag item"
|
||||||
|
([databag-name item-id]
|
||||||
|
(databag-item-exists? databag-name item-id *chef*))
|
||||||
|
([databag-name item-id #^ChefService chef]
|
||||||
|
(.databagExists (as-chef-api chef) databag-name item-id)))
|
||||||
|
|
||||||
(defn databag-item
|
(defn databag-item
|
||||||
"Get an item from the data bag"
|
"Get an item from the data bag"
|
||||||
([databag item-id]
|
([databag item-id]
|
||||||
|
|
|
@ -75,50 +75,87 @@ public class ChefContextFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see RestContextFactory#createContextBuilder(String, String)
|
* @see #createContext(String, String, String)
|
||||||
*/
|
*/
|
||||||
public ChefContext createContext(String identity, String credential) {
|
public ChefContext createContext(String identity, String credential) {
|
||||||
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder("chef",
|
return createContext("chef", identity, credential);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see RestContextFactory#createContextBuilder(String, String, String)
|
||||||
|
*/
|
||||||
|
public ChefContext createContext(String provider, String identity, String credential) {
|
||||||
|
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder(provider,
|
||||||
identity, credential));
|
identity, credential));
|
||||||
return buildContextUnwrappingExceptions(builder);
|
return buildContextUnwrappingExceptions(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see RestContextFactory#createContextBuilder(Properties)
|
* @see #createContext(String, Properties)
|
||||||
*/
|
*/
|
||||||
public ChefContext createContext(Properties overrides) {
|
public ChefContext createContext(Properties overrides) {
|
||||||
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder("chef",
|
return createContext("chef", overrides);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see RestContextFactory#createContextBuilder(String, Properties)
|
||||||
|
*/
|
||||||
|
public ChefContext createContext(String provider, Properties overrides) {
|
||||||
|
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder(provider,
|
||||||
overrides));
|
overrides));
|
||||||
return buildContextUnwrappingExceptions(builder);
|
return buildContextUnwrappingExceptions(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see RestContextFactory#createContextBuilder(Iterable)
|
* @see #createContext(String, Iterable, Properties)
|
||||||
*/
|
*/
|
||||||
public ChefContext createContext(Iterable<? extends Module> modules, Properties overrides) {
|
public ChefContext createContext(Iterable<? extends Module> modules, Properties overrides) {
|
||||||
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder("chef",
|
return createContext("chef", modules, overrides);
|
||||||
modules, overrides));
|
|
||||||
return buildContextUnwrappingExceptions(builder);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see RestContextFactory#createContextBuilder(String,String, Iterable)
|
* @see RestContextFactory#createContextBuilder(String, Iterable, Properties)
|
||||||
|
*/
|
||||||
|
public ChefContext createContext(String provider, Iterable<? extends Module> modules, Properties overrides) {
|
||||||
|
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder(provider,
|
||||||
|
modules, overrides));
|
||||||
|
return buildContextUnwrappingExceptions(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #createContext(String,String,String,Iterable)
|
||||||
*/
|
*/
|
||||||
public ChefContext createContext(@Nullable String identity, @Nullable String credential,
|
public ChefContext createContext(@Nullable String identity, @Nullable String credential,
|
||||||
Iterable<? extends Module> modules) {
|
Iterable<? extends Module> modules) {
|
||||||
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder("chef",
|
return createContext("chef", identity, credential, modules);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see RestContextFactory#createContextBuilder(String,String String,
|
||||||
|
* Iterable)
|
||||||
|
*/
|
||||||
|
public ChefContext createContext(String provider, @Nullable String identity, @Nullable String credential,
|
||||||
|
Iterable<? extends Module> modules) {
|
||||||
|
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder(provider,
|
||||||
identity, credential, modules));
|
identity, credential, modules));
|
||||||
return buildContextUnwrappingExceptions(builder);
|
return buildContextUnwrappingExceptions(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see RestContextFactory#createContextBuilder(String,String, Iterable,
|
* @see #createContext(String,String, String, Iterable, Properties)
|
||||||
* Properties)
|
|
||||||
*/
|
*/
|
||||||
public ChefContext createContext(@Nullable String identity, @Nullable String credential,
|
public ChefContext createContext(@Nullable String identity, @Nullable String credential,
|
||||||
Iterable<? extends Module> modules, Properties overrides) {
|
Iterable<? extends Module> modules, Properties overrides) {
|
||||||
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder("chef",
|
return createContext("chef", identity, credential, modules, overrides);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see RestContextFactory#createContextBuilder(String,String,String,
|
||||||
|
* Iterable, Properties)
|
||||||
|
*/
|
||||||
|
public ChefContext createContext(String provider, @Nullable String identity, @Nullable String credential,
|
||||||
|
Iterable<? extends Module> modules, Properties overrides) {
|
||||||
|
RestContextBuilder<?, ?> builder = RestContextBuilder.class.cast(contextFactory.createContextBuilder(provider,
|
||||||
identity, credential, modules, overrides));
|
identity, credential, modules, overrides));
|
||||||
return buildContextUnwrappingExceptions(builder);
|
return buildContextUnwrappingExceptions(builder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,346 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jclouds.chef.test;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Throwables.propagate;
|
||||||
|
import static com.google.common.collect.Iterables.transform;
|
||||||
|
import static com.google.common.collect.Sets.newLinkedHashSet;
|
||||||
|
import static org.jclouds.concurrent.Futures.compose;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.blobstore.TransientAsyncBlobStore;
|
||||||
|
import org.jclouds.blobstore.domain.Blob;
|
||||||
|
import org.jclouds.blobstore.domain.PageSet;
|
||||||
|
import org.jclouds.blobstore.domain.StorageMetadata;
|
||||||
|
import org.jclouds.chef.ChefAsyncClient;
|
||||||
|
import org.jclouds.chef.domain.Client;
|
||||||
|
import org.jclouds.chef.domain.CookbookVersion;
|
||||||
|
import org.jclouds.chef.domain.DatabagItem;
|
||||||
|
import org.jclouds.chef.domain.Node;
|
||||||
|
import org.jclouds.chef.domain.Role;
|
||||||
|
import org.jclouds.chef.domain.Sandbox;
|
||||||
|
import org.jclouds.chef.domain.SearchResult;
|
||||||
|
import org.jclouds.chef.domain.UploadSandbox;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.util.concurrent.Futures;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In-memory chef simulator.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TransientChefAsyncClient implements ChefAsyncClient {
|
||||||
|
@Singleton
|
||||||
|
private static class StorageMetadataToName implements Function<PageSet<? extends StorageMetadata>, Set<String>> {
|
||||||
|
@Override
|
||||||
|
public Set<String> apply(PageSet<? extends StorageMetadata> from) {
|
||||||
|
return newLinkedHashSet(transform(from, new Function<StorageMetadata, String>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(StorageMetadata from) {
|
||||||
|
return from.getName();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
private static class BlobToDatabagItem implements Function<Blob, DatabagItem> {
|
||||||
|
@Override
|
||||||
|
public DatabagItem apply(Blob from) {
|
||||||
|
try {
|
||||||
|
return from == null ? null : new DatabagItem(from.getMetadata().getName(), Utils.toStringAndClose(from
|
||||||
|
.getPayload().getInput()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
propagate(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final TransientAsyncBlobStore databags;
|
||||||
|
private final ExecutorService executor;
|
||||||
|
private final BlobToDatabagItem blobToDatabagItem;
|
||||||
|
private final StorageMetadataToName storageMetadataToName;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TransientChefAsyncClient(@Named("databags") TransientAsyncBlobStore databags,
|
||||||
|
StorageMetadataToName storageMetadataToName, BlobToDatabagItem blobToDatabagItem,
|
||||||
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) {
|
||||||
|
this.databags = checkNotNull(databags, "databags");
|
||||||
|
this.storageMetadataToName = checkNotNull(storageMetadataToName, "storageMetadataToName");
|
||||||
|
this.blobToDatabagItem = checkNotNull(blobToDatabagItem, "blobToDatabagItem");
|
||||||
|
this.executor = checkNotNull(executor, "executor");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Boolean> clientExists(String clientname) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Sandbox> commitSandbox(String id, boolean isCompleted) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Client> createClient(String clientname) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Void> createDatabag(String databagName) {
|
||||||
|
return databags.createContainerInLocationIfAbsent(null, databagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<DatabagItem> createDatabagItem(String databagName, DatabagItem databagItem) {
|
||||||
|
Blob blob = databags.newBlob(databagItem.getId());
|
||||||
|
blob.setPayload(databagItem.toString());
|
||||||
|
databags.putBlobAndReturnOld(databagName, blob);
|
||||||
|
return Futures.immediateFuture(databagItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Void> createNode(Node node) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Void> createRole(Role role) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Boolean> databagExists(String databagName) {
|
||||||
|
return databags.containerExists(databagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Boolean> databagItemExists(String databagName, String databagItemId) {
|
||||||
|
return databags.blobExists(databagName, databagItemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Client> deleteClient(String clientname) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<CookbookVersion> deleteCookbook(String cookbookName, String version) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Void> deleteDatabag(String databagName) {
|
||||||
|
return databags.deleteContainer(databagName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<DatabagItem> deleteDatabagItem(String databagName, String databagItemId) {
|
||||||
|
return compose(databags.removeBlobAndReturnOld(databagName, databagItemId), blobToDatabagItem, executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Node> deleteNode(String nodename) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Role> deleteRole(String rolename) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Client> generateKeyForClient(String clientname) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Client> getClient(String clientname) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<CookbookVersion> getCookbook(String cookbookName, String version) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<DatabagItem> getDatabagItem(String databagName, String databagItemId) {
|
||||||
|
return compose(databags.getBlob(databagName, databagItemId), blobToDatabagItem, executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Node> getNode(String nodename) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Role> getRole(String rolename) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<UploadSandbox> getUploadSandboxForChecksums(Set<List<Byte>> md5s) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Set<String>> getVersionsOfCookbook(String cookbookName) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Set<String>> listClients() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Set<String>> listCookbooks() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Set<String>> listDatabagItems(String databagName) {
|
||||||
|
return compose(databags.list(databagName), storageMetadataToName, executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Set<String>> listDatabags() {
|
||||||
|
return compose(databags.list(), storageMetadataToName, executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Set<String>> listNodes() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Set<String>> listRoles() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Set<String>> listSearchIndexes() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Boolean> nodeExists(String nodename) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Boolean> roleExists(String rolename) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<? extends SearchResult<? extends Client>> searchClients() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<? extends SearchResult<? extends DatabagItem>> searchDatabag(String databagName) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<? extends SearchResult<? extends Node>> searchNodes() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<? extends SearchResult<? extends Role>> searchRoles() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<CookbookVersion> updateCookbook(String cookbookName, String version, CookbookVersion cookbook) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<DatabagItem> updateDatabagItem(String databagName, DatabagItem item) {
|
||||||
|
return createDatabagItem(databagName, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Node> updateNode(Node node) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Role> updateRole(Role role) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Void> uploadContent(Set<List<Byte>> md5s) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jclouds.chef.test;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.chef.ChefAsyncClient;
|
||||||
|
import org.jclouds.chef.ChefClient;
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In-memory chef simulator.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see ChefAsyncClient
|
||||||
|
* @see <a href="TODO: insert URL of Chef documentation" />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Timeout(duration = 30, timeUnit = TimeUnit.MILLISECONDS)
|
||||||
|
public interface TransientChefClient extends ChefClient {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jclouds.chef.test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.chef.ChefContextBuilder;
|
||||||
|
import org.jclouds.chef.test.config.TransientChefClientModule;
|
||||||
|
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class TransientChefContextBuilder extends ChefContextBuilder {
|
||||||
|
|
||||||
|
public TransientChefContextBuilder(Properties props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addClientModule(List<Module> modules) {
|
||||||
|
modules.add(new TransientChefClientModule());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.chef.test.config;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.blobstore.TransientAsyncBlobStore;
|
||||||
|
import org.jclouds.chef.ChefAsyncClient;
|
||||||
|
import org.jclouds.chef.ChefClient;
|
||||||
|
import org.jclouds.chef.config.BaseChefRestClientModule;
|
||||||
|
import org.jclouds.chef.test.TransientChefAsyncClient;
|
||||||
|
import org.jclouds.chef.test.TransientChefClient;
|
||||||
|
import org.jclouds.rest.RestContextFactory;
|
||||||
|
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class TransientChefClientModule extends BaseChefRestClientModule<TransientChefClient, ChefAsyncClient> {
|
||||||
|
|
||||||
|
public TransientChefClientModule() {
|
||||||
|
super(TransientChefClient.class, ChefAsyncClient.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(TransientAsyncBlobStore.class).annotatedWith(Names.named("databags")).toInstance(
|
||||||
|
new RestContextFactory().createContextBuilder("transient", "foo", "bar").buildInjector().getInstance(
|
||||||
|
TransientAsyncBlobStore.class));
|
||||||
|
super.configure();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void bindAsyncClient() {
|
||||||
|
bind(ChefAsyncClient.class).to(TransientChefAsyncClient.class).asEagerSingleton();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
ChefClient provideClient(TransientChefClient in) {
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
;
|
||||||
|
;
|
||||||
|
; Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
;
|
||||||
|
; ====================================================================
|
||||||
|
; Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
; you may not use this file except in compliance with the License.
|
||||||
|
; You may obtain a copy of the License at
|
||||||
|
;
|
||||||
|
; http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
;
|
||||||
|
; Unless required by applicable law or agreed to in writing, software
|
||||||
|
; distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
; See the License for the specific language governing permissions and
|
||||||
|
; limitations under the License.
|
||||||
|
; ====================================================================
|
||||||
|
;
|
||||||
|
|
||||||
|
(ns org.jclouds.chef-test
|
||||||
|
(:use [org.jclouds.chef] :reload-all)
|
||||||
|
(:use [clojure.test]))
|
||||||
|
|
||||||
|
(defn clean-stub-fixture
|
||||||
|
"This should allow basic tests to easily be run with another service."
|
||||||
|
[service account key & options]
|
||||||
|
(fn [f]
|
||||||
|
(with-chef-service [(apply chef-service service account key options)]
|
||||||
|
(doseq [databag (databags)]
|
||||||
|
(delete-databag databag))
|
||||||
|
(f))))
|
||||||
|
|
||||||
|
(use-fixtures :each (clean-stub-fixture "transientchef" "" ""))
|
||||||
|
|
||||||
|
(deftest chef-service?-test
|
||||||
|
(is (chef-service? *chef*)))
|
||||||
|
|
||||||
|
(deftest as-chef-service-test
|
||||||
|
(is (chef-service? (chef-service "transientchef" "" "")))
|
||||||
|
(is (chef-service? (as-chef-service *chef*)))
|
||||||
|
(is (chef-service? (as-chef-service (chef-context *chef*)))))
|
||||||
|
|
||||||
|
(deftest create-existing-databag-test
|
||||||
|
(is (not (databag-exists? "")))
|
||||||
|
(create-databag "fred")
|
||||||
|
(is (databag-exists? "fred")))
|
||||||
|
|
||||||
|
(deftest create-databag-test
|
||||||
|
(create-databag "fred")
|
||||||
|
(is (databag-exists? "fred")))
|
||||||
|
|
||||||
|
(deftest databags-test
|
||||||
|
(is (empty? (databags)))
|
||||||
|
(create-databag "fred")
|
||||||
|
(is (= 1 (count (databags)))))
|
||||||
|
|
||||||
|
(deftest databag-items-test
|
||||||
|
(create-databag "databag")
|
||||||
|
(is (empty? (databag-items "databag")))
|
||||||
|
(is (create-databag-item "databag" {:id "databag-item1" :value "databag-value1"}))
|
||||||
|
(is (create-databag-item "databag" {:id "databag-item2" :value "databag-value2"}))
|
||||||
|
(is (= 2 (count (databag-items "databag")))))
|
||||||
|
|
||||||
|
(deftest databag-item-test
|
||||||
|
(create-databag "databag")
|
||||||
|
(is (create-databag-item "databag" {:id "databag-item1" :value "databag-value1"}))
|
||||||
|
(is (create-databag-item "databag" {:id "databag-item2" :value "databag-value2"}))
|
||||||
|
(is (= {:id "databag-item2" :value "databag-value2"} (databag-item "databag" "databag-item2"))))
|
||||||
|
|
|
@ -84,7 +84,7 @@ public abstract class BaseChefClientLiveTest {
|
||||||
private Node node;
|
private Node node;
|
||||||
private Role role;
|
private Role role;
|
||||||
protected Json json;
|
protected Json json;
|
||||||
private DatabagItem databagItem;
|
protected DatabagItem databagItem;
|
||||||
public static final String PREFIX = System.getProperty("user.name") + "-jcloudstest";
|
public static final String PREFIX = System.getProperty("user.name") + "-jcloudstest";
|
||||||
|
|
||||||
public BaseChefClientLiveTest() {
|
public BaseChefClientLiveTest() {
|
||||||
|
|
|
@ -0,0 +1,327 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jclouds.chef.test;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.jclouds.chef.BaseChefClientLiveTest;
|
||||||
|
import org.jclouds.chef.ChefClient;
|
||||||
|
import org.jclouds.chef.ChefContext;
|
||||||
|
import org.jclouds.chef.ChefContextFactory;
|
||||||
|
import org.jclouds.chef.config.ChefParserModule;
|
||||||
|
import org.jclouds.chef.domain.DatabagItem;
|
||||||
|
import org.jclouds.json.Json;
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.jclouds.rest.HttpClient;
|
||||||
|
import org.testng.annotations.AfterClass;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code TransientChefClient}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "integration", testName = "chef.TransientChefClientIntegrationTest")
|
||||||
|
public class TransientChefClientIntegrationTest extends BaseChefClientLiveTest {
|
||||||
|
public void testCreateDatabag1() throws Exception {
|
||||||
|
getAdminConnection().deleteDatabag(PREFIX);
|
||||||
|
getAdminConnection().createDatabag(PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateDatabag1")
|
||||||
|
public void testDatabagExists1() throws Exception {
|
||||||
|
assertNotNull(getClientConnection().databagExists(PREFIX));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = { "testCreateDatabag1"})
|
||||||
|
public void testCreateDatabagItem1() throws Exception {
|
||||||
|
Properties config = new Properties();
|
||||||
|
config.setProperty("foo", "bar");
|
||||||
|
getAdminConnection().deleteDatabagItem(PREFIX, PREFIX);
|
||||||
|
databagItem = getAdminConnection().createDatabagItem(PREFIX, new DatabagItem("config", json.toJson(config)));
|
||||||
|
assertNotNull(databagItem);
|
||||||
|
assertEquals(databagItem.getId(), "config");
|
||||||
|
assertEquals(config, json.fromJson(databagItem.toString(), Properties.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testCreateDatabagItem1")
|
||||||
|
public void testDatabagItemExists1() throws Exception {
|
||||||
|
assertNotNull(getClientConnection().databagItemExists(PREFIX, PREFIX));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testDatabagItemExists1")
|
||||||
|
public void testUpdateDatabagItem1() throws Exception {
|
||||||
|
for (String databagItemId : getClientConnection().listDatabagItems(PREFIX)) {
|
||||||
|
DatabagItem databagItem = getAdminConnection().getDatabagItem(PREFIX, databagItemId);
|
||||||
|
getAdminConnection().updateDatabagItem(PREFIX, databagItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testClientExists() throws Exception {
|
||||||
|
super.testClientExists();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testCreateClient() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testCreateDatabag() throws Exception {
|
||||||
|
super.testCreateDatabag();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testCreateDatabagItem() throws Exception {
|
||||||
|
super.testCreateDatabagItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testDatabagExists() throws Exception {
|
||||||
|
super.testDatabagExists();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testDatabagItemExists() throws Exception {
|
||||||
|
super.testDatabagItemExists();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testListDatabagItems() throws Exception {
|
||||||
|
super.testListDatabagItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testListDatabags() throws Exception {
|
||||||
|
super.testListDatabags();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testCreateCookbook() throws Exception {
|
||||||
|
super.testCreateCookbook();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testCreateNewCookbook() throws Exception {
|
||||||
|
super.testCreateNewCookbook();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testCreateNode() throws Exception {
|
||||||
|
super.testCreateNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testCreateRole() throws Exception {
|
||||||
|
super.testCreateRole();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testGenerateKeyForClient() throws Exception {
|
||||||
|
super.testGenerateKeyForClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testListCookbooks() throws Exception {
|
||||||
|
super.testListCookbooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testListNodes() throws Exception {
|
||||||
|
super.testListNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testListRoles() throws Exception {
|
||||||
|
super.testListRoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testListSearchIndexes() throws Exception {
|
||||||
|
super.testListSearchIndexes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testNodeExists() throws Exception {
|
||||||
|
super.testNodeExists();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testRoleExists() throws Exception {
|
||||||
|
super.testRoleExists();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testSearchClients() throws Exception {
|
||||||
|
super.testSearchClients();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testSearchDatabag() throws Exception {
|
||||||
|
super.testSearchDatabag();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testSearchDatabagNotFound() throws Exception {
|
||||||
|
super.testSearchDatabagNotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testSearchNodes() throws Exception {
|
||||||
|
super.testSearchNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testSearchRoles() throws Exception {
|
||||||
|
super.testSearchRoles();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testUpdateCookbook() throws Exception {
|
||||||
|
super.testUpdateCookbook();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testUpdateDatabagItem() throws Exception {
|
||||||
|
super.testUpdateDatabagItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testUpdateNode() throws Exception {
|
||||||
|
super.testUpdateNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testUpdateRole() throws Exception {
|
||||||
|
super.testUpdateRole();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testValidatorCannotCreateClient() throws Exception {
|
||||||
|
super.testValidatorCannotCreateClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testValidatorCannotDeleteClient() throws Exception {
|
||||||
|
super.testValidatorCannotDeleteClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testValidatorCannotListClients() throws Exception {
|
||||||
|
super.testValidatorCannotListClients();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChefContext validatorConnection;
|
||||||
|
private ChefContext clientConnection;
|
||||||
|
private ChefContext adminConnection;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@BeforeClass(groups = { "integration" })
|
||||||
|
public void setupClient() throws IOException {
|
||||||
|
// TODO make this nicer
|
||||||
|
validatorConnection = adminConnection = clientConnection = createConnection("user", "userkey");
|
||||||
|
json = Guice.createInjector(new GsonModule(), new ChefParserModule()).getInstance(Json.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@AfterClass(groups = { "live" })
|
||||||
|
public void teardownClient() throws IOException {
|
||||||
|
// if (getValidatorConnection().clientExists(PREFIX))
|
||||||
|
// getValidatorConnection().deleteClient(PREFIX);
|
||||||
|
// if (getAdminConnection().nodeExists(PREFIX))
|
||||||
|
// getAdminConnection().deleteNode(PREFIX);
|
||||||
|
// if (getAdminConnection().roleExists(PREFIX))
|
||||||
|
// getAdminConnection().deleteRole(PREFIX);
|
||||||
|
if (getAdminConnection().databagExists(PREFIX))
|
||||||
|
getAdminConnection().deleteDatabag(PREFIX);
|
||||||
|
closeContexts();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChefContext createConnection(String identity, String key) throws IOException {
|
||||||
|
return new ChefContextFactory().createContext("transientchef", identity, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HttpClient getHttp() {
|
||||||
|
return adminConnection.utils().http();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ChefClient getAdminConnection() {
|
||||||
|
return adminConnection.getApi();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ChefClient getValidatorConnection() {
|
||||||
|
return validatorConnection.getApi();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ChefClient getClientConnection() {
|
||||||
|
return clientConnection.getApi();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void recreateClientConnection() throws IOException {
|
||||||
|
if (clientConnection != null)
|
||||||
|
clientConnection.close();
|
||||||
|
clientConnection = createConnection(PREFIX, clientKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void closeContexts() {
|
||||||
|
if (clientConnection != null)
|
||||||
|
clientConnection.close();
|
||||||
|
if (validatorConnection != null)
|
||||||
|
validatorConnection.close();
|
||||||
|
if (adminConnection != null)
|
||||||
|
adminConnection.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -62,6 +62,9 @@ hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVC
|
||||||
chef.contextbuilder=org.jclouds.chef.ChefContextBuilder
|
chef.contextbuilder=org.jclouds.chef.ChefContextBuilder
|
||||||
chef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder
|
chef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder
|
||||||
|
|
||||||
|
transientchef.contextbuilder=org.jclouds.chef.test.TransientChefContextBuilder
|
||||||
|
transientchef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder
|
||||||
|
|
||||||
opscodeplatform.contextbuilder=org.jclouds.opscodeplatform.OpscodePlatformContextBuilder
|
opscodeplatform.contextbuilder=org.jclouds.opscodeplatform.OpscodePlatformContextBuilder
|
||||||
opscodeplatform.propertiesbuilder=org.jclouds.opscodeplatform.OpscodePlatformPropertiesBuilder
|
opscodeplatform.propertiesbuilder=org.jclouds.opscodeplatform.OpscodePlatformPropertiesBuilder
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue