Issue 191: normalized common aggregate commands into ChefService

This commit is contained in:
Adrian Cole 2010-07-27 17:09:10 -07:00
parent d884978a98
commit 56caac57f1
38 changed files with 1374 additions and 162 deletions

View File

@ -198,7 +198,7 @@ public interface ChefAsyncClient {
*/
@POST
@Path("nodes")
ListenableFuture<Node> createNode(@BinderParam(BindToJsonPayload.class) Node node);
ListenableFuture<Void> createNode(@BinderParam(BindToJsonPayload.class) Node node);
/**
* @see ChefClient#updateNode
@ -289,7 +289,6 @@ public interface ChefAsyncClient {
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<String>> listRoles();
/**
* @see ChefClient#createDataBag
*/
@ -302,8 +301,8 @@ public interface ChefAsyncClient {
*/
@PUT
@Path("data/{path}")
ListenableFuture<JsonBall> updateDataBag(
@PathParam("path") String path, @BinderParam(BindToJsonPayload.class) JsonBall node);
ListenableFuture<JsonBall> updateDataBag(@PathParam("path") String path,
@BinderParam(BindToJsonPayload.class) JsonBall node);
/**
* @see ChefDataBag#nodeExists

View File

@ -235,7 +235,7 @@ public interface ChefClient {
* "409 Conflict" if the node already exists
*/
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
Node createNode(Node node);
void createNode(Node node);
/**
* Creates or updates (uploads) a node //TODO document

View File

@ -0,0 +1,37 @@
/**
*
* Copyright (C) 2009 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;
import org.jclouds.chef.internal.ChefContextImpl;
import org.jclouds.rest.RestContext;
import com.google.inject.ImplementedBy;
/**
*
*
* @author Adrian Cole
*
*/
@ImplementedBy(ChefContextImpl.class)
public interface ChefContext extends RestContext<ChefClient, ChefAsyncClient>{
ChefService getChefService();
}

View File

@ -1,24 +1,19 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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
* 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.
* 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;
@ -27,12 +22,16 @@ import java.util.List;
import java.util.Properties;
import org.jclouds.chef.config.ChefRestClientModule;
import org.jclouds.ohai.config.ConfiguresOhai;
import org.jclouds.ohai.config.JMXOhaiJVMModule;
import org.jclouds.rest.RestContextBuilder;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class ChefContextBuilder extends RestContextBuilder<ChefClient, ChefAsyncClient> {
@ -41,8 +40,44 @@ public class ChefContextBuilder extends RestContextBuilder<ChefClient, ChefAsync
super(ChefClient.class, ChefAsyncClient.class, props);
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new ChefRestClientModule());
}
@Override
public Injector buildInjector() {
addOhaiModuleIfNotPresent();
return super.buildInjector();
}
/**
* {@inheritDoc}
*/
@Override
public ChefContextBuilder withModules(Module... modules) {
return (ChefContextBuilder) super.withModules(modules);
}
@SuppressWarnings("unchecked")
@Override
public ChefContext buildContext() {
Injector injector = buildInjector();
return injector.getInstance(ChefContext.class);
}
protected void addOhaiModuleIfNotPresent() {
if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(ConfiguresOhai.class);
}
})) {
addOhaiModule();
}
}
protected void addOhaiModule() {
modules.add(new JMXOhaiJVMModule());
}
}

View File

@ -0,0 +1,32 @@
package org.jclouds.chef;
import java.util.Set;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.internal.BaseChefService;
import com.google.common.base.Predicate;
import com.google.inject.ImplementedBy;
/**
* Provides high level chef operations
*
* @author Adrian Cole
*/
@ImplementedBy(BaseChefService.class)
public interface ChefService {
void cleanupStaleNodesAndClients(String prefix, int minutesStale);
void createNodeAndPopulateAutomaticAttributes(String nodeName, Iterable<String> runList);
void deleteAllClientsAndNodesInList(Iterable<String> names);
Set<Node> getNodes();
Set<Node> getNodesWithNamesMatching(Predicate<String> nodeNameSelector);
Set<Node> getNodesNamed(Iterable<String> names);
void updateAutomaticAttributesOnNode(String nodeName);
}

View File

@ -0,0 +1,86 @@
package org.jclouds.chef.internal;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.chef.ChefService;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.CleanupStaleNodesAndClients;
import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes;
import org.jclouds.chef.strategy.DeleteAllClientsAndNodesInList;
import org.jclouds.chef.strategy.GetNodes;
import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
/**
*
* @author Adrian Cole
*/
@Singleton
public class BaseChefService implements ChefService {
@Resource
@Named(ChefConstants.CHEF_LOGGER)
protected Logger logger = Logger.NULL;
private final CleanupStaleNodesAndClients cleanupStaleNodesAndClients;
private final CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes;
private final DeleteAllClientsAndNodesInList deleteAllClientsAndNodesInList;
private final GetNodes getNodes;
private final UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode;
@Inject
protected BaseChefService(CleanupStaleNodesAndClients cleanupStaleNodesAndClients,
CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes,
DeleteAllClientsAndNodesInList deleteAllClientsAndNodesInList, GetNodes getNodes,
UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode) {
this.cleanupStaleNodesAndClients = cleanupStaleNodesAndClients;
this.createNodeAndPopulateAutomaticAttributes = createNodeAndPopulateAutomaticAttributes;
this.deleteAllClientsAndNodesInList = deleteAllClientsAndNodesInList;
this.getNodes = getNodes;
this.updateAutomaticAttributesOnNode = updateAutomaticAttributesOnNode;
}
@Override
public void cleanupStaleNodesAndClients(String prefix, int minutesStale) {
cleanupStaleNodesAndClients.execute(prefix, minutesStale);
}
@Override
public void createNodeAndPopulateAutomaticAttributes(String nodeName, Iterable<String> runList) {
createNodeAndPopulateAutomaticAttributes.execute(nodeName, runList);
}
@Override
public void deleteAllClientsAndNodesInList(Iterable<String> names) {
deleteAllClientsAndNodesInList.execute(names);
}
@Override
public Set<Node> getNodes() {
return getNodes.execute();
}
@Override
public Set<Node> getNodesWithNamesMatching(Predicate<String> nodeNameSelector) {
return getNodes.execute(nodeNameSelector);
}
@Override
public Set<Node> getNodesNamed(Iterable<String> names) {
return getNodes.execute(names);
}
@Override
public void updateAutomaticAttributesOnNode(String nodeName) {
updateAutomaticAttributesOnNode.execute(nodeName);
}
}

View File

@ -0,0 +1,61 @@
/**
*
* Copyright (C) 2009 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.internal;
import java.net.URI;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.ChefContext;
import org.jclouds.chef.ChefService;
import org.jclouds.lifecycle.Closer;
import org.jclouds.rest.Utils;
import org.jclouds.rest.annotations.ApiVersion;
import org.jclouds.rest.annotations.Identity;
import org.jclouds.rest.annotations.Provider;
import org.jclouds.rest.internal.RestContextImpl;
import com.google.inject.Injector;
import com.google.inject.TypeLiteral;
/**
* @author Adrian Cole
*/
@Singleton
public class ChefContextImpl extends RestContextImpl<ChefClient, ChefAsyncClient> implements ChefContext {
private final ChefService chefService;
@Inject
protected ChefContextImpl(Closer closer, Utils utils, Injector injector, TypeLiteral<ChefClient> syncApi,
TypeLiteral<ChefAsyncClient> asyncApi, @Provider URI endpoint, @Provider String provider,
@Identity String identity, @ApiVersion String apiVersion, ChefService chefService) {
super(closer, utils, injector, syncApi, asyncApi, endpoint, provider, identity, apiVersion);
this.chefService = chefService;
}
@Override
public ChefService getChefService() {
return chefService;
}
}

View File

@ -50,7 +50,8 @@ public interface ChefConstants {
/**
* There are generally 3 types of identities
* <ul>
* <li>validator - used to create clients within an organization; {@code orgname}-validator</li>
* <li>validator - used to create clients within an organization; {@code
* orgname}-validator</li>
* <li>client - scoped to an organization, used on nodes to run chef</li>
* <li>user - used to run commands like knife and access cookbook sites</li>
* </ul>
@ -64,4 +65,7 @@ public interface ChefConstants {
/**
* how often to refresh timestamps in seconds.
*/
public static final String CHEF_LOGGER = "jclouds.chef";
}

View File

@ -0,0 +1,36 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy;
import org.jclouds.chef.strategy.internal.CleanupStaleNodesAndClientsImpl;
import com.google.inject.ImplementedBy;
/**
*
* Cleans up nodes and clients who have been hanging around too long.
*
* @author Adrian Cole
*/
@ImplementedBy(CleanupStaleNodesAndClientsImpl.class)
public interface CleanupStaleNodesAndClients {
void execute(String prefix, int secondsStale);
}

View File

@ -0,0 +1,37 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.strategy.internal.CreateNodeAndPopulateAutomaticAttributesImpl;
import com.google.inject.ImplementedBy;
/**
*
* Creates a new node with automatic attributes.
*
* @author Adrian Cole
*/
@ImplementedBy(CreateNodeAndPopulateAutomaticAttributesImpl.class)
public interface CreateNodeAndPopulateAutomaticAttributes {
void execute(Node node);
void execute(String nodeName, Iterable<String> runList);
}

View File

@ -18,64 +18,18 @@
*/
package org.jclouds.chef.strategy;
import static com.google.common.collect.Maps.newHashMap;
import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion;
import org.jclouds.chef.strategy.internal.DeleteAllClientsAndNodesInListImpl;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient;
import org.jclouds.logging.Logger;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Inject;
import com.google.inject.ImplementedBy;
/**
*
*
* @author Adrian Cole
*/
@Singleton
public class DeleteAllClientsAndNodesInList {
@ImplementedBy(DeleteAllClientsAndNodesInListImpl.class)
public interface DeleteAllClientsAndNodesInList {
protected final ChefClient chefClient;
protected final ChefAsyncClient chefAsyncClient;
protected final ExecutorService userExecutor;
@Resource
protected Logger logger = Logger.NULL;
public void execute(Iterable<String> names);
@Inject(optional = true)
@Named(Constants.PROPERTY_REQUEST_TIMEOUT)
protected Long maxTime;
@Inject
DeleteAllClientsAndNodesInList(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
ChefClient getAllNode, ChefAsyncClient ablobstore) {
this.userExecutor = userExecutor;
this.chefAsyncClient = ablobstore;
this.chefClient = getAllNode;
}
public void execute() {
execute(chefClient.listNodes());
}
public void execute(Iterable<String> names) {
Map<String, Exception> exceptions = newHashMap();
Map<String, ListenableFuture<?>> responses = newHashMap();
for (String name : names) {
responses.put(name, chefAsyncClient.deleteClient(name));
responses.put(name, chefAsyncClient.deleteNode(name));
}
exceptions = awaitCompletion(responses, userExecutor, maxTime, logger, String.format(
"getting deleting clients and nodes: %s", names));
if (exceptions.size() > 0)
throw new RuntimeException(String.format("errors deleting clients and nodes: %s: %s", names, exceptions));
}
}

View File

@ -0,0 +1,42 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy;
import java.util.Set;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.strategy.internal.GetNodesImpl;
import com.google.common.base.Predicate;
import com.google.inject.ImplementedBy;
/**
*
*
* @author Adrian Cole
*/
@ImplementedBy(GetNodesImpl.class)
public interface GetNodes {
Set<Node> execute();
Set<Node> execute(Predicate<String> nodeNameSelector);
Set<Node> execute(Iterable<String> toGet);
}

View File

@ -0,0 +1,35 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy;
import org.jclouds.chef.strategy.internal.UpdateAutomaticAttributesOnNodeImpl;
import com.google.inject.ImplementedBy;
/**
*
* Updates node with new automatic attributes.
*
* @author Adrian Cole
*/
@ImplementedBy(UpdateAutomaticAttributesOnNodeImpl.class)
public interface UpdateAutomaticAttributesOnNode {
public void execute(String nodeName);
}

View File

@ -0,0 +1,99 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.notNull;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.ohai.Util.OhaiUtils.fromOhaiTime;
import java.util.Calendar;
import java.util.Date;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.CleanupStaleNodesAndClients;
import org.jclouds.domain.JsonBall;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
/**
*
* Cleans up nodes and clients who have been hanging around too long.
*
* @author Adrian Cole
*/
@Singleton
public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClients {
@Resource
@Named(ChefConstants.CHEF_LOGGER)
protected Logger logger = Logger.NULL;
private final GetNodesImpl getAllNodes;
private final DeleteAllClientsAndNodesInListImpl deleter;
@Inject
public CleanupStaleNodesAndClientsImpl(DeleteAllClientsAndNodesInListImpl deleter, GetNodesImpl getAllNodes) {
this.getAllNodes = checkNotNull(getAllNodes, "getAllNodes");
this.deleter = checkNotNull(deleter, "deleter");
}
@Override
public void execute(final String prefix, int secondsStale) {
final Calendar expired = Calendar.getInstance();
expired.setTime(new Date());
expired.add(Calendar.SECOND, -secondsStale);
Iterable<Node> staleNodes = filter(getAllNodes.execute(new Predicate<String>() {
@Override
public boolean apply(String input) {
return input.startsWith(prefix);
}
}), and(notNull(), new Predicate<Node>() {
@Override
public boolean apply(Node input) {
JsonBall dateLong = input.getAutomatic().get("ohai_time");
if (dateLong == null)
return true;
Calendar nodeUpdate = Calendar.getInstance();
nodeUpdate.setTime(fromOhaiTime(dateLong));
return expired.after(nodeUpdate);
}
}));
deleter.execute(transform(staleNodes, new Function<Node, String>() {
@Override
public String apply(Node from) {
return from.getName();
}
}));
}
}

View File

@ -16,7 +16,7 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.ohai;
package org.jclouds.chef.strategy.internal;
import static com.google.common.base.Preconditions.checkNotNull;
@ -29,6 +29,8 @@ import javax.inject.Singleton;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes;
import org.jclouds.domain.JsonBall;
import org.jclouds.logging.Logger;
@ -41,26 +43,32 @@ import com.google.common.base.Supplier;
* @author Adrian Cole
*/
@Singleton
public class CreateNode {
public class CreateNodeAndPopulateAutomaticAttributesImpl implements CreateNodeAndPopulateAutomaticAttributes {
@Resource
@Named(ChefConstants.CHEF_LOGGER)
protected Logger logger = Logger.NULL;
private final ChefClient chef;
private final Supplier<Map<String, JsonBall>> automaticSupplier;
@Inject
public CreateNode(ChefClient chef, @Named("automatic") Supplier<Map<String, JsonBall>> automaticSupplier) {
public CreateNodeAndPopulateAutomaticAttributesImpl(ChefClient chef,
@Named("automatic") Supplier<Map<String, JsonBall>> automaticSupplier) {
this.chef = checkNotNull(chef, "chef");
this.automaticSupplier = checkNotNull(automaticSupplier, "automaticSupplier");
}
public Node createNode(String nodeName, Iterable<String> runList) {
logger.info("creating node %s", nodeName);
Node node = new Node(nodeName, runList);
@Override
public void execute(Node node) {
logger.trace("creating node %s", node.getName());
node.getAutomatic().putAll(automaticSupplier.get());
node = chef.createNode(node);
logger.debug("done creating node %s", nodeName);
return node;
chef.createNode(node);
logger.debug("created node %s", node.getName());
}
@Override
public void execute(String nodeName, Iterable<String> runList) {
execute(new Node(nodeName, runList));
}
}

View File

@ -0,0 +1,81 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy.internal;
import static com.google.common.collect.Maps.newHashMap;
import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.DeleteAllClientsAndNodesInList;
import org.jclouds.logging.Logger;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Inject;
/**
*
*
* @author Adrian Cole
*/
@Singleton
public class DeleteAllClientsAndNodesInListImpl implements DeleteAllClientsAndNodesInList {
protected final ChefClient chefClient;
protected final ChefAsyncClient chefAsyncClient;
protected final ExecutorService userExecutor;
@Resource
@Named(ChefConstants.CHEF_LOGGER)
protected Logger logger = Logger.NULL;
@Inject(optional = true)
@Named(Constants.PROPERTY_REQUEST_TIMEOUT)
protected Long maxTime;
@Inject
DeleteAllClientsAndNodesInListImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
ChefClient getAllNode, ChefAsyncClient ablobstore) {
this.userExecutor = userExecutor;
this.chefAsyncClient = ablobstore;
this.chefClient = getAllNode;
}
@Override
public void execute(Iterable<String> names) {
Map<String, Exception> exceptions = newHashMap();
Map<String, ListenableFuture<?>> responses = newHashMap();
for (String name : names) {
responses.put(name, chefAsyncClient.deleteClient(name));
responses.put(name, chefAsyncClient.deleteNode(name));
}
exceptions = awaitCompletion(responses, userExecutor, maxTime, logger, String.format(
"getting deleting clients and nodes: %s", names));
if (exceptions.size() > 0)
throw new RuntimeException(String.format("errors deleting clients and nodes: %s: %s", names, exceptions));
}
}

View File

@ -16,7 +16,7 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy;
package org.jclouds.chef.strategy.internal;
import static com.google.common.base.Throwables.propagate;
import static com.google.common.collect.Iterables.filter;
@ -38,6 +38,8 @@ import org.jclouds.Constants;
import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.GetNodes;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
@ -50,12 +52,13 @@ import com.google.inject.Inject;
* @author Adrian Cole
*/
@Singleton
public class GetAllNodesInList {
public class GetNodesImpl implements GetNodes {
protected final ChefClient chefClient;
protected final ChefAsyncClient chefAsyncClient;
protected final ExecutorService userExecutor;
@Resource
@Named(ChefConstants.CHEF_LOGGER)
protected Logger logger = Logger.NULL;
@Inject(optional = true)
@ -63,21 +66,24 @@ public class GetAllNodesInList {
protected Long maxTime;
@Inject
GetAllNodesInList(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ChefClient getAllNode,
GetNodesImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ChefClient getAllNode,
ChefAsyncClient ablobstore) {
this.userExecutor = userExecutor;
this.chefAsyncClient = ablobstore;
this.chefClient = getAllNode;
}
@Override
public Set<Node> execute() {
return execute(chefClient.listNodes());
}
@Override
public Set<Node> execute(Predicate<String> nodeNameSelector) {
return execute(filter(chefClient.listNodes(), nodeNameSelector));
}
@Override
public Set<Node> execute(Iterable<String> toGet) {
Map<String, Exception> exceptions = newHashMap();
final Set<Node> nodes = newHashSet();

View File

@ -16,7 +16,7 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.ohai;
package org.jclouds.chef.strategy.internal;
import static com.google.common.base.Preconditions.checkNotNull;
@ -29,6 +29,8 @@ import javax.inject.Singleton;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.domain.Node;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode;
import org.jclouds.domain.JsonBall;
import org.jclouds.logging.Logger;
@ -41,25 +43,28 @@ import com.google.common.base.Supplier;
* @author Adrian Cole
*/
@Singleton
public class UpdateNode {
public class UpdateAutomaticAttributesOnNodeImpl implements UpdateAutomaticAttributesOnNode {
@Resource
@Named(ChefConstants.CHEF_LOGGER)
protected Logger logger = Logger.NULL;
private final ChefClient chef;
private final Supplier<Map<String, JsonBall>> automaticSupplier;
@Inject
public UpdateNode(ChefClient chef, @Named("automatic") Supplier<Map<String, JsonBall>> automaticSupplier) {
public UpdateAutomaticAttributesOnNodeImpl(ChefClient chef,
@Named("automatic") Supplier<Map<String, JsonBall>> automaticSupplier) {
this.chef = checkNotNull(chef, "chef");
this.automaticSupplier = checkNotNull(automaticSupplier, "automaticSupplier");
}
public void updateNode(String nodeName) {
logger.info("updating node %s", nodeName);
@Override
public void execute(String nodeName) {
logger.trace("updating node %s", nodeName);
Node node = chef.getNode(nodeName);
node.getAutomatic().putAll(automaticSupplier.get());
chef.updateNode(node);
logger.debug("done updating node %s", nodeName);
logger.debug("updated node %s", nodeName);
}
}

View File

@ -0,0 +1,45 @@
/**
*
* 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.ohai.Util;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
import org.jclouds.domain.JsonBall;
/**
*
*
* @author Adrian Cole
*/
public class OhaiUtils {
public static Date fromOhaiTime(JsonBall ohaiDate) {
return new Date(Long.parseLong(checkNotNull(ohaiDate, "ohaiDate").toString().replaceAll("\\.[0-9]*$", "")));
}
public static JsonBall toOhaiTime(long nanos) {
String now = nanos + "";
StringBuilder nowBuilder = new StringBuilder(now).insert(now.length() - 6, '.');
while (nowBuilder.lastIndexOf("0") != -1 && nowBuilder.lastIndexOf("0") == nowBuilder.length() - 1)
nowBuilder.deleteCharAt(nowBuilder.length() - 1);
return new JsonBall(nowBuilder.toString());
}
}

View File

@ -18,11 +18,23 @@
*/
package org.jclouds.ohai.config;
import java.util.Properties;
import javax.inject.Named;
import com.google.inject.Provides;
/**
* Wires the components needed to parse ohai data without violating the GAE JVM
* Wires the components needed to parse ohai data from a JVM
*
* @author Adrian Cole
*/
public class WhiteListCompliantOhaiModule extends BaseOhaiModule {
public abstract class BaseOhaiJVMModule extends BaseOhaiModule {
@Named("systemProperties")
@Provides
protected Properties systemProperties() {
return System.getProperties();
}
}

View File

@ -18,31 +18,29 @@
*/
package org.jclouds.ohai.config;
import static org.jclouds.util.Utils.composeMapSupplier;
import java.util.Map;
import java.util.Properties;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.domain.JsonBall;
import org.jclouds.ohai.WhiteListCompliantJVM;
import org.jclouds.ohai.functions.ByteArrayToMacAddress;
import org.jclouds.util.Utils;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
/**
* Wires the components needed to parse ohai data from a JVM
* Wires the components needed to parse ohai data
*
* @author Adrian Cole
*/
public class BaseOhaiModule extends AbstractModule {
public abstract class BaseOhaiModule extends AbstractModule {
@Override
protected void configure() {
@ -57,25 +55,17 @@ public class BaseOhaiModule extends AbstractModule {
return System.nanoTime();
}
@Named("systemProperties")
@Provides
protected Properties systemProperties() {
return System.getProperties();
}
@Named("automatic")
@Provides
@Singleton
Supplier<Map<String, JsonBall>> automaticSupplier(
@Named("automatic") Iterable<Supplier<Map<String, JsonBall>>> suppliers) {
return Utils.composeMapSupplier(suppliers);
return composeMapSupplier(suppliers);
}
@Named("automatic")
@Singleton
@Provides
Iterable<Supplier<Map<String, JsonBall>>> suppliers(Injector injector) {
return ImmutableList.<Supplier<Map<String, JsonBall>>> of(injector.getInstance(WhiteListCompliantJVM.class));
}
protected abstract Iterable<Supplier<Map<String, JsonBall>>> suppliers(Injector injector);
}

View File

@ -0,0 +1,16 @@
package org.jclouds.ohai.config;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
*
* @author Adrian Cole
*/
@Retention(RUNTIME)
@Target(TYPE)
public @interface ConfiguresOhai {
}

View File

@ -25,8 +25,8 @@ import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.domain.JsonBall;
import org.jclouds.ohai.JMX;
import org.jclouds.ohai.WhiteListCompliantJVM;
import org.jclouds.ohai.plugins.JMX;
import org.jclouds.ohai.plugins.WhiteListCompliantJVM;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
@ -38,7 +38,8 @@ import com.google.inject.Provides;
*
* @author Adrian Cole
*/
public class OhaiModule extends BaseOhaiModule {
@ConfiguresOhai
public class JMXOhaiJVMModule extends BaseOhaiJVMModule {
@Provides
@Singleton
@ -47,7 +48,7 @@ public class OhaiModule extends BaseOhaiModule {
}
@Override
Iterable<Supplier<Map<String, JsonBall>>> suppliers(Injector injector) {
protected Iterable<Supplier<Map<String, JsonBall>>> suppliers(Injector injector) {
return ImmutableList.<Supplier<Map<String, JsonBall>>> of(injector.getInstance(WhiteListCompliantJVM.class),
injector.getInstance(JMX.class));
}

View File

@ -0,0 +1,42 @@
/**
*
* 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.ohai.config;
import java.util.Map;
import org.jclouds.domain.JsonBall;
import org.jclouds.ohai.plugins.WhiteListCompliantJVM;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.inject.Injector;
/**
* Wires the components needed to parse ohai data without violating the GAE JVM
*
* @author Adrian Cole
*/
@ConfiguresOhai
public class WhiteListCompliantOhaiJVMModule extends BaseOhaiJVMModule {
@Override
protected Iterable<Supplier<Map<String, JsonBall>>> suppliers(Injector injector) {
return ImmutableList.<Supplier<Map<String, JsonBall>>> of(injector.getInstance(WhiteListCompliantJVM.class));
}
}

View File

@ -16,7 +16,7 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.ohai;
package org.jclouds.ohai.plugins;
import static com.google.common.base.Preconditions.checkNotNull;

View File

@ -16,9 +16,11 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.ohai;
package org.jclouds.ohai.plugins;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.inject.internal.Maps.newLinkedHashMap;
import static org.jclouds.ohai.Util.OhaiUtils.toOhaiTime;
import java.util.Map;
import java.util.Properties;
@ -34,7 +36,6 @@ import org.jclouds.json.Json;
import org.jclouds.logging.Logger;
import com.google.common.base.Supplier;
import com.google.inject.internal.Maps;
/**
*
@ -63,14 +64,10 @@ public class WhiteListCompliantJVM implements Supplier<Map<String, JsonBall>> {
}
public Map<String, JsonBall> get() {
Map<String, JsonBall> returnVal = Maps.newLinkedHashMap();
Map<String, JsonBall> returnVal = newLinkedHashMap();
Properties systemProperties = systemPropertiesProvider.get();
String now = nanoTimeProvider.get() + "";
StringBuilder nowBuilder = new StringBuilder(now).insert(now.length() - 6, '.');
while (nowBuilder.lastIndexOf("0") != -1 && nowBuilder.lastIndexOf("0") == nowBuilder.length() - 1)
nowBuilder.deleteCharAt(nowBuilder.length() - 1);
now = nowBuilder.toString();
returnVal.put("ohai_time", new JsonBall(now));
returnVal.put("ohai_time", toOhaiTime(nanoTimeProvider.get()));
returnVal.put("java", new JsonBall(json.toJson(systemProperties)));

View File

@ -44,7 +44,6 @@ import org.jclouds.chef.domain.UploadSandbox;
import org.jclouds.io.Payloads;
import org.jclouds.io.payloads.FilePayload;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
@ -65,9 +64,9 @@ import com.google.inject.Module;
@Test(groups = "live", testName = "chef.ChefClientLiveTest")
public class ChefClientLiveTest {
private RestContext<ChefClient, ChefAsyncClient> validatorConnection;
private RestContext<ChefClient, ChefAsyncClient> clientConnection;
private RestContext<ChefClient, ChefAsyncClient> adminConnection;
private ChefContext validatorConnection;
private ChefContext clientConnection;
private ChefContext adminConnection;
private String clientKey;
private String endpoint;
@ -95,11 +94,11 @@ public class ChefClientLiveTest {
adminConnection = createConnection(user, Files.toString(new File(keyfile), Charsets.UTF_8));
}
private RestContext<ChefClient, ChefAsyncClient> createConnection(String identity, String key) throws IOException {
private ChefContext createConnection(String identity, String key) throws IOException {
Properties props = new Properties();
props.setProperty("chef.endpoint", endpoint);
return new RestContextFactory().createContext("chef", identity, key, ImmutableSet
.<Module> of(new Log4JLoggingModule()), props);
return (ChefContext) new RestContextFactory().<ChefClient, ChefAsyncClient> createContext("chef", identity, key,
ImmutableSet.<Module> of(new Log4JLoggingModule()), props);
}
public void testCreateNewCookbook() throws Exception {
@ -228,7 +227,8 @@ public class ChefClientLiveTest {
@Test(dependsOnMethods = "testCreateRole")
public void testCreateNode() throws Exception {
adminConnection.getApi().deleteNode(PREFIX);
node = clientConnection.getApi().createNode(new Node(PREFIX, Collections.singleton("role[" + PREFIX + "]")));
clientConnection.getApi().createNode(new Node(PREFIX, Collections.singleton("role[" + PREFIX + "]")));
node = adminConnection.getApi().getNode(PREFIX);
// TODO check recipes
assertNotNull(node);
Set<String> nodes = adminConnection.getApi().listNodes();

View File

@ -0,0 +1,85 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient;
import org.jclouds.lifecycle.Closer;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContextFactory;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.base.Charsets;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
* Tests behavior of {@code ChefService} strategies
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "chef.BaseChefStrategyLiveTest")
public abstract class BaseChefStrategyLiveTest {
protected Injector injector;
protected String prefix = System.getProperty("user.name") + getClass().getSimpleName();
@BeforeTest(groups = { "live" })
public void setupClient() throws IOException {
String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"), "jclouds.test.endpoint");
String user = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
String keyfile = System.getProperty("jclouds.test.credential");
if (keyfile == null || keyfile.equals(""))
keyfile = System.getProperty("user.home") + "/.chef/" + user + ".pem";
Properties props = new Properties();
props.setProperty("chef.endpoint", endpoint);
Set<Module> modules = Sets.newHashSet();
modules.add(new Log4JLoggingModule());
addTestModulesTo(modules);
injector = new RestContextFactory().<ChefClient, ChefAsyncClient> createContextBuilder("chef", user,
Files.toString(new File(keyfile), Charsets.UTF_8), modules, props).buildInjector();
}
protected void addTestModulesTo(Set<Module> modules) {
}
@AfterTest(groups = { "live" })
public void teardownClient() throws IOException {
if (injector != null)
injector.getInstance(Closer.class).close();
}
}

View File

@ -0,0 +1,67 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy.internal;
import org.jclouds.chef.ChefClient;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code CleanupStaleNodesAndClientsImpl} strategies
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "chef.CleanupStaleNodesAndClientsImplLiveTest")
public class CleanupStaleNodesAndClientsImplTest extends BaseChefStrategyLiveTest {
private CreateNodeAndPopulateAutomaticAttributesImpl creater;
private CleanupStaleNodesAndClientsImpl strategy;
private ChefClient chef;
@BeforeTest(groups = "live", dependsOnMethods = "setupClient")
void setupStrategy() {
this.creater = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class);
this.strategy = injector.getInstance(CleanupStaleNodesAndClientsImpl.class);
this.chef = injector.getInstance(ChefClient.class);
}
@Test
public void testExecute() throws InterruptedException {
try {
creater.execute(prefix, ImmutableSet.<String> of());
// http://tickets.corp.opscode.com/browse/PL-522
// assert chef.nodeExists(prefix);
assert chef.getNode(prefix) != null;
strategy.execute(prefix, 10);
assert chef.getNode(prefix) != null;
Thread.sleep(1000);
strategy.execute(prefix, 1);
assert chef.getNode(prefix) == null;
} finally {
chef.deleteNode(prefix);
}
}
}

View File

@ -0,0 +1,93 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy.internal;
import static org.testng.Assert.assertEquals;
import java.util.Map;
import java.util.Set;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.domain.Node;
import org.jclouds.domain.JsonBall;
import org.jclouds.ohai.config.BaseOhaiModule;
import org.jclouds.ohai.config.ConfiguresOhai;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
* Tests behavior of {@code CreateNodeAndPopulateAutomaticAttributesImpl}
* strategies
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "chef.CreateNodeAndPopulateAutomaticAttributesImplLiveTest")
public class CreateNodeAndPopulateAutomaticAttributesImplLiveTest extends BaseChefStrategyLiveTest {
private CreateNodeAndPopulateAutomaticAttributesImpl strategy;
private ChefClient chef;
@ConfiguresOhai
static class TestOhaiModule extends BaseOhaiModule {
@Override
protected Iterable<Supplier<Map<String, JsonBall>>> suppliers(Injector injector) {
Supplier<Map<String, JsonBall>> supplier = Suppliers.<Map<String, JsonBall>> ofInstance(ImmutableMap
.<String, JsonBall> of("foo", new JsonBall("bar")));
return ImmutableList.<Supplier<Map<String, JsonBall>>> of(supplier);
}
}
protected void addTestModulesTo(Set<Module> modules) {
modules.add(new TestOhaiModule());
}
@BeforeTest(groups = "live", dependsOnMethods = "setupClient")
void setupStrategy() {
this.strategy = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class);
this.chef = injector.getInstance(ChefClient.class);
}
@Test
public void testExecute() {
Set<String> runList = ImmutableSet.of("role[" + prefix + "]");
try {
strategy.execute(prefix, runList);
Node node = chef.getNode(prefix);
assertEquals(node.getName(), prefix);
assertEquals(node.getRunList(), runList);
assertEquals(node.getAutomatic().get("foo").toString(), "\"bar\"");
} finally {
injector.getInstance(ChefClient.class).deleteNode(prefix);
}
}
}

View File

@ -21,9 +21,8 @@
* under the License.
* ====================================================================
*/
package org.jclouds.ohai;
package org.jclouds.chef.strategy.internal;
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;
@ -41,12 +40,12 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code CreateNode}
* Tests behavior of {@code CreateNodeAndPopulateAutomaticAttributesImpl}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ohai.CreateNodeTest")
public class CreateNodeTest {
@Test(groups = "unit", testName = "ohai.CreateNodeAndPopulateAutomaticAttributesImplTest")
public class CreateNodeAndPopulateAutomaticAttributesImplTest {
@Test
public void testWithNoRunlist() {
@ -62,13 +61,13 @@ public class CreateNodeTest {
.<String, JsonBall> of(), ImmutableMap.<String, JsonBall> of(), automatic, ImmutableSet.<String> of());
node.getAutomatic().putAll(automaticSupplier.get());
expect(chef.createNode(nodeWithAutomatic)).andReturn(null);
chef.createNode(nodeWithAutomatic);
replay(chef);
CreateNode updater = new CreateNode(chef, automaticSupplier);
CreateNodeAndPopulateAutomaticAttributesImpl updater = new CreateNodeAndPopulateAutomaticAttributesImpl(chef, automaticSupplier);
updater.createNode("name", ImmutableSet.<String> of());
updater.execute("name", ImmutableSet.<String> of());
verify(chef);
}

View File

@ -0,0 +1,69 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy.internal;
import org.jclouds.chef.ChefClient;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code DeleteAllClientsAndNodesInListImpl} strategies
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "chef.DeleteAllClientsAndNodesInListImplTest")
public class DeleteAllClientsAndNodesInListImplLiveTest extends BaseChefStrategyLiveTest {
private DeleteAllClientsAndNodesInListImpl strategy;
private CreateNodeAndPopulateAutomaticAttributesImpl creater;
private ChefClient chef;
@BeforeTest(groups = "live", dependsOnMethods = "setupClient")
void setupStrategy() {
this.creater = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class);
this.strategy = injector.getInstance(DeleteAllClientsAndNodesInListImpl.class);
this.chef = injector.getInstance(ChefClient.class);
}
@Test
public void testExecute() throws InterruptedException {
try {
creater.execute(prefix, ImmutableSet.<String> of());
creater.execute(prefix + 1, ImmutableSet.<String> of());
// http://tickets.corp.opscode.com/browse/PL-522
// assert chef.nodeExists(prefix);
assert chef.getNode(prefix) != null;
assert chef.getNode(prefix + 1) != null;
strategy.execute(ImmutableSet.of(prefix, prefix + 1));
assert chef.getNode(prefix) == null;
assert chef.getNode(prefix + 1) == null;
} finally {
chef.deleteNode(prefix);
chef.deleteNode(prefix + 1);
}
}
}

View File

@ -0,0 +1,92 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy.internal;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import org.jclouds.chef.ChefClient;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code GetNodesImpl} strategies
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "chef.GetNodesImplLiveTest")
public class GetNodesImplLiveTest extends BaseChefStrategyLiveTest {
private GetNodesImpl strategy;
private CreateNodeAndPopulateAutomaticAttributesImpl creater;
private ChefClient chef;
@BeforeTest(groups = "live", dependsOnMethods = "setupClient")
void setupStrategy() {
this.creater = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class);
this.strategy = injector.getInstance(GetNodesImpl.class);
this.chef = injector.getInstance(ChefClient.class);
}
@BeforeTest(groups = "live", dependsOnMethods = "setupStrategy")
void setupNodes() {
creater.execute(prefix, ImmutableSet.<String> of());
creater.execute(prefix + 1, ImmutableSet.<String> of());
}
@AfterTest(groups = { "live" })
@Override
public void teardownClient() throws IOException {
chef.deleteNode(prefix);
chef.deleteNode(prefix + 1);
super.teardownClient();
}
@Test
public void testExecute() {
assert strategy.execute().size() > 0;
}
@Test
public void testExecutePredicateOfString() {
assertEquals(strategy.execute(new Predicate<String>() {
@Override
public boolean apply(String input) {
return input.startsWith(prefix);
}
}).size(), 2);
}
@Test
public void testExecuteIterableOfString() {
assertEquals(strategy.execute(ImmutableSet.of(prefix, prefix + 1)).size(), 2);
}
}

View File

@ -0,0 +1,92 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy.internal;
import static org.testng.Assert.assertEquals;
import java.util.Map;
import java.util.Set;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.domain.Node;
import org.jclouds.domain.JsonBall;
import org.jclouds.ohai.config.BaseOhaiModule;
import org.jclouds.ohai.config.ConfiguresOhai;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Injector;
import com.google.inject.Module;
/**
* Tests behavior of {@code UpdateAutomaticAttributesOnNodeImpl} strategies
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "chef.UpdateAutomaticAttributesOnNodeImplLiveTest")
public class UpdateAutomaticAttributesOnNodeImplLiveTest extends BaseChefStrategyLiveTest {
private UpdateAutomaticAttributesOnNodeImpl strategy;
private ChefClient chef;
@ConfiguresOhai
static class TestOhaiModule extends BaseOhaiModule {
@Override
protected Iterable<Supplier<Map<String, JsonBall>>> suppliers(Injector injector) {
Supplier<Map<String, JsonBall>> supplier = Suppliers.<Map<String, JsonBall>> ofInstance(ImmutableMap
.<String, JsonBall> of("foo", new JsonBall("bar")));
return ImmutableList.<Supplier<Map<String, JsonBall>>> of(supplier);
}
}
protected void addTestModulesTo(Set<Module> modules) {
modules.add(new TestOhaiModule());
}
@BeforeTest(groups = "live", dependsOnMethods = "setupClient")
void setupStrategy() {
this.strategy = injector.getInstance(UpdateAutomaticAttributesOnNodeImpl.class);
this.chef = injector.getInstance(ChefClient.class);
}
@Test
public void testExecute() {
Set<String> runList = ImmutableSet.of("role[" + prefix + "]");
try {
chef.createNode(new Node(prefix, runList));
strategy.execute(prefix);
Node node = chef.getNode(prefix);
assertEquals(node.getName(), prefix);
assertEquals(node.getRunList(), runList);
assertEquals(node.getAutomatic().get("foo").toString(), "\"bar\"");
} finally {
injector.getInstance(ChefClient.class).deleteNode(prefix);
}
}
}

View File

@ -21,7 +21,7 @@
* under the License.
* ====================================================================
*/
package org.jclouds.ohai;
package org.jclouds.chef.strategy.internal;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
@ -41,12 +41,12 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
* Tests behavior of {@code UpdateNode}
* Tests behavior of {@code UpdateAutomaticAttributesOnNodeImpl}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ohai.UpdateNodeTest")
public class UpdateNodeTest {
@Test(groups = "unit", testName = "ohai.UpdateAutomaticAttributesOnNodeImplTest")
public class UpdateAutomaticAttributesOnNodeImplTest {
@Test
public void test() {
@ -67,9 +67,9 @@ public class UpdateNodeTest {
replay(chef);
UpdateNode updater = new UpdateNode(chef, automaticSupplier);
UpdateAutomaticAttributesOnNodeImpl updater = new UpdateAutomaticAttributesOnNodeImpl(chef, automaticSupplier);
updater.updateNode("name");
updater.execute("name");
verify(chef);
}

View File

@ -21,7 +21,7 @@
* under the License.
* ====================================================================
*/
package org.jclouds.ohai;
package org.jclouds.ohai.plugins;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
@ -34,7 +34,7 @@ import java.lang.management.RuntimeMXBean;
import org.jclouds.chef.config.ChefParserModule;
import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule;
import org.jclouds.ohai.config.OhaiModule;
import org.jclouds.ohai.config.JMXOhaiJVMModule;
import org.testng.annotations.Test;
import com.google.inject.Guice;
@ -57,7 +57,7 @@ public class JMXTest {
replay(runtime);
Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule(), new OhaiModule() {
Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule(), new JMXOhaiJVMModule() {
@Override
protected RuntimeMXBean provideRuntimeMXBean() {
return runtime;

View File

@ -21,7 +21,7 @@
* under the License.
* ====================================================================
*/
package org.jclouds.ohai;
package org.jclouds.ohai.plugins;
import static org.testng.Assert.assertEquals;
@ -31,7 +31,7 @@ import java.util.Properties;
import org.jclouds.chef.config.ChefParserModule;
import org.jclouds.json.Json;
import org.jclouds.json.config.GsonModule;
import org.jclouds.ohai.config.BaseOhaiModule;
import org.jclouds.ohai.config.WhiteListCompliantOhaiJVMModule;
import org.testng.annotations.Test;
import com.google.inject.Guice;
@ -54,7 +54,8 @@ public class WhiteListCompliantJVMTest {
sysProperties.setProperty("os.version", "10.3.0");
sysProperties.setProperty("user.name", "user");
Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule(), new BaseOhaiModule() {
Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule(),
new WhiteListCompliantOhaiJVMModule() {
@Override
protected Long nanoTime() {
return 1279992919325290l;

View File

@ -0,0 +1,54 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* 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.ohai.util;
import static org.testng.Assert.assertEquals;
import java.util.Date;
import org.jclouds.domain.JsonBall;
import org.jclouds.ohai.Util.OhaiUtils;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code OhaiUtils}
*
* @author Adrian Cole
*/
@Test(groups = "unit", sequential = true, testName = "ohai.OhaiUtilsTest")
public class OhaiUtilsTest {
public static long nanotime = 1280251180727244000l;
public static String nanotimeString = "1280251180727.244";
public static Date now = new Date(1280251180727l);
public void testToOhaiTime() {
assertEquals(OhaiUtils.toOhaiTime(nanotime).toString(), nanotimeString);
}
public void testFromOhaiTime() {
assertEquals(OhaiUtils.fromOhaiTime(new JsonBall(nanotimeString)), now);
}
}