updated to allow aggregate client commands

This commit is contained in:
Adrian Cole 2010-09-02 01:36:43 -07:00
parent a96471c9a8
commit 64a52c0420
11 changed files with 329 additions and 32 deletions

View File

@ -22,6 +22,7 @@ package org.jclouds.chef;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.domain.Node; import org.jclouds.chef.domain.Node;
import org.jclouds.chef.internal.BaseChefService; import org.jclouds.chef.internal.BaseChefService;
@ -61,7 +62,15 @@ public interface ChefService {
Iterable<? extends Node> listNodesDetailsMatching(Predicate<String> nodeNameSelector); Iterable<? extends Node> listNodesDetailsMatching(Predicate<String> nodeNameSelector);
Iterable<? extends Node> getNodesNamed(Iterable<String> names); Iterable<? extends Node> listNodesNamed(Iterable<String> names);
void deleteAllClientsInList(Iterable<String> names);
Iterable<? extends Client> listClientsDetails();
Iterable<? extends Client> listClientsDetailsMatching(Predicate<String> clientNameSelector);
Iterable<? extends Client> listClientsNamed(Iterable<String> names);
void updateAutomaticAttributesOnNode(String nodeName); void updateAutomaticAttributesOnNode(String nodeName);
} }

View File

@ -33,12 +33,15 @@ import javax.inject.Singleton;
import org.jclouds.chef.ChefContext; import org.jclouds.chef.ChefContext;
import org.jclouds.chef.ChefService; import org.jclouds.chef.ChefService;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.domain.Node; import org.jclouds.chef.domain.Node;
import org.jclouds.chef.reference.ChefConstants; import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.CleanupStaleNodesAndClients; import org.jclouds.chef.strategy.CleanupStaleNodesAndClients;
import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes; import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes;
import org.jclouds.chef.strategy.DeleteAllClientsInList;
import org.jclouds.chef.strategy.DeleteAllNodesInList; import org.jclouds.chef.strategy.DeleteAllNodesInList;
import org.jclouds.chef.strategy.GetNodes; import org.jclouds.chef.strategy.ListClients;
import org.jclouds.chef.strategy.ListNodes;
import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode; import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode;
import org.jclouds.io.Payloads; import org.jclouds.io.Payloads;
import org.jclouds.io.payloads.RSADecryptingPayload; import org.jclouds.io.payloads.RSADecryptingPayload;
@ -64,23 +67,28 @@ public class BaseChefService implements ChefService {
private final CleanupStaleNodesAndClients cleanupStaleNodesAndClients; private final CleanupStaleNodesAndClients cleanupStaleNodesAndClients;
private final CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes; private final CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes;
private final DeleteAllNodesInList deleteAllNodesInList; private final DeleteAllNodesInList deleteAllNodesInList;
private final GetNodes getNodes; private final ListNodes listNodes;
private final DeleteAllClientsInList deleteAllClientsInList;
private final ListClients listClients;
private final UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode; private final UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode;
private final Provider<PrivateKey> privateKey; private final Provider<PrivateKey> privateKey;
@Inject @Inject
protected BaseChefService(ChefContext chefContext, CleanupStaleNodesAndClients cleanupStaleNodesAndClients, protected BaseChefService(ChefContext chefContext, CleanupStaleNodesAndClients cleanupStaleNodesAndClients,
CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes, CreateNodeAndPopulateAutomaticAttributes createNodeAndPopulateAutomaticAttributes,
DeleteAllNodesInList deleteAllNodesInList, GetNodes getNodes, DeleteAllNodesInList deleteAllNodesInList, ListNodes listNodes,
UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Provider<PrivateKey> privateKey) { DeleteAllClientsInList deleteAllClientsInList, ListClients listClients,
UpdateAutomaticAttributesOnNode updateAutomaticAttributesOnNode, Provider<PrivateKey> privateKey) {
this.chefContext = checkNotNull(chefContext, "chefContext"); this.chefContext = checkNotNull(chefContext, "chefContext");
this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients"); this.cleanupStaleNodesAndClients = checkNotNull(cleanupStaleNodesAndClients, "cleanupStaleNodesAndClients");
this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes, this.createNodeAndPopulateAutomaticAttributes = checkNotNull(createNodeAndPopulateAutomaticAttributes,
"createNodeAndPopulateAutomaticAttributes"); "createNodeAndPopulateAutomaticAttributes");
this.deleteAllNodesInList = checkNotNull(deleteAllNodesInList, "deleteAllNodesInList"); this.deleteAllNodesInList = checkNotNull(deleteAllNodesInList, "deleteAllNodesInList");
this.getNodes = checkNotNull(getNodes, "getNodes"); this.listNodes = checkNotNull(listNodes, "listNodes");
this.deleteAllClientsInList = checkNotNull(deleteAllClientsInList, "deleteAllClientsInList");
this.listClients = checkNotNull(listClients, "listClients");
this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode, this.updateAutomaticAttributesOnNode = checkNotNull(updateAutomaticAttributesOnNode,
"updateAutomaticAttributesOnNode"); "updateAutomaticAttributesOnNode");
this.privateKey = checkNotNull(privateKey, "privateKey"); this.privateKey = checkNotNull(privateKey, "privateKey");
} }
@ -101,17 +109,37 @@ public class BaseChefService implements ChefService {
@Override @Override
public Iterable<? extends Node> listNodesDetails() { public Iterable<? extends Node> listNodesDetails() {
return getNodes.execute(); return listNodes.execute();
} }
@Override @Override
public Iterable<? extends Node> listNodesDetailsMatching(Predicate<String> nodeNameSelector) { public Iterable<? extends Node> listNodesDetailsMatching(Predicate<String> nodeNameSelector) {
return getNodes.execute(nodeNameSelector); return listNodes.execute(nodeNameSelector);
} }
@Override @Override
public Iterable<? extends Node> getNodesNamed(Iterable<String> names) { public Iterable<? extends Node> listNodesNamed(Iterable<String> names) {
return getNodes.execute(names); return listNodes.execute(names);
}
@Override
public void deleteAllClientsInList(Iterable<String> names) {
deleteAllClientsInList.execute(names);
}
@Override
public Iterable<? extends Client> listClientsDetails() {
return listClients.execute();
}
@Override
public Iterable<? extends Client> listClientsDetailsMatching(Predicate<String> clientNameSelector) {
return listClients.execute(clientNameSelector);
}
@Override
public Iterable<? extends Client> listClientsNamed(Iterable<String> names) {
return listClients.execute(names);
} }
@Override @Override
@ -127,13 +155,13 @@ public class BaseChefService implements ChefService {
@Override @Override
public byte[] decrypt(InputSupplier<? extends InputStream> supplier) throws IOException { public byte[] decrypt(InputSupplier<? extends InputStream> supplier) throws IOException {
return ByteStreams.toByteArray(new RSADecryptingPayload(Payloads.newPayload(supplier.getInput()), privateKey return ByteStreams.toByteArray(new RSADecryptingPayload(Payloads.newPayload(supplier.getInput()), privateKey
.get())); .get()));
} }
@Override @Override
public byte[] encrypt(InputSupplier<? extends InputStream> supplier) throws IOException { public byte[] encrypt(InputSupplier<? extends InputStream> supplier) throws IOException {
return ByteStreams.toByteArray(new RSAEncryptingPayload(Payloads.newPayload(supplier.getInput()), privateKey return ByteStreams.toByteArray(new RSAEncryptingPayload(Payloads.newPayload(supplier.getInput()), privateKey
.get())); .get()));
} }
} }

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.DeleteAllClientsInListImpl;
import com.google.inject.ImplementedBy;
/**
*
*
* @author Adrian Cole
*/
@ImplementedBy(DeleteAllClientsInListImpl.class)
public interface DeleteAllClientsInList {
public void execute(Iterable<String> names);
}

View File

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

View File

@ -20,7 +20,7 @@
package org.jclouds.chef.strategy; package org.jclouds.chef.strategy;
import org.jclouds.chef.domain.Node; import org.jclouds.chef.domain.Node;
import org.jclouds.chef.strategy.internal.GetNodesImpl; import org.jclouds.chef.strategy.internal.ListNodesImpl;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.inject.ImplementedBy; import com.google.inject.ImplementedBy;
@ -30,8 +30,8 @@ import com.google.inject.ImplementedBy;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@ImplementedBy(GetNodesImpl.class) @ImplementedBy(ListNodesImpl.class)
public interface GetNodes { public interface ListNodes {
Iterable<? extends Node> execute(); Iterable<? extends Node> execute();

View File

@ -37,6 +37,9 @@ import javax.inject.Singleton;
import org.jclouds.chef.domain.Node; import org.jclouds.chef.domain.Node;
import org.jclouds.chef.reference.ChefConstants; import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.CleanupStaleNodesAndClients; import org.jclouds.chef.strategy.CleanupStaleNodesAndClients;
import org.jclouds.chef.strategy.DeleteAllClientsInList;
import org.jclouds.chef.strategy.DeleteAllNodesInList;
import org.jclouds.chef.strategy.ListNodes;
import org.jclouds.domain.JsonBall; import org.jclouds.domain.JsonBall;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
@ -55,13 +58,16 @@ public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClie
@Named(ChefConstants.CHEF_LOGGER) @Named(ChefConstants.CHEF_LOGGER)
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
private final GetNodesImpl getAllNodes; private final ListNodes nodeLister;
private final DeleteAllNodesInListImpl deleter; private final DeleteAllNodesInList nodeDeleter;
private final DeleteAllClientsInList clientDeleter;
@Inject @Inject
public CleanupStaleNodesAndClientsImpl(DeleteAllNodesInListImpl deleter, GetNodesImpl getAllNodes) { public CleanupStaleNodesAndClientsImpl(DeleteAllNodesInList nodeDeleter, DeleteAllClientsInList clientDeleter,
this.getAllNodes = checkNotNull(getAllNodes, "getAllNodes"); ListNodes nodeLister) {
this.deleter = checkNotNull(deleter, "deleter"); this.nodeLister = checkNotNull(nodeLister, "nodeLister");
this.nodeDeleter = checkNotNull(nodeDeleter, "nodeDeleter");
this.clientDeleter = checkNotNull(clientDeleter, "clientDeleter");
} }
@Override @Override
@ -69,7 +75,7 @@ public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClie
final Calendar expired = Calendar.getInstance(); final Calendar expired = Calendar.getInstance();
expired.setTime(new Date()); expired.setTime(new Date());
expired.add(Calendar.SECOND, -secondsStale); expired.add(Calendar.SECOND, -secondsStale);
Iterable<? extends Node> staleNodes = filter(getAllNodes.execute(new Predicate<String>() { Iterable<? extends Node> staleNodes = filter(nodeLister.execute(new Predicate<String>() {
@Override @Override
public boolean apply(String input) { public boolean apply(String input) {
@ -88,13 +94,15 @@ public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClie
} }
})); }));
deleter.execute(transform(staleNodes, new Function<Node, String>() { Iterable<String> nodeNames = transform(staleNodes, new Function<Node, String>() {
@Override @Override
public String apply(Node from) { public String apply(Node from) {
return from.getName(); return from.getName();
} }
})); });
nodeDeleter.execute(nodeNames);
clientDeleter.execute(nodeNames);
} }
} }

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.FutureIterables.awaitCompletion;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.DeleteAllClientsInList;
import org.jclouds.logging.Logger;
import com.google.inject.Inject;
/**
*
*
* @author Adrian Cole
*/
@Singleton
public class DeleteAllClientsInListImpl implements DeleteAllClientsInList {
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
DeleteAllClientsInListImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor,
ChefClient getAllClient, ChefAsyncClient ablobstore) {
this.userExecutor = userExecutor;
this.chefAsyncClient = ablobstore;
this.chefClient = getAllClient;
}
@Override
public void execute(Iterable<String> names) {
Map<String, Exception> exceptions = newHashMap();
Map<String, Future<?>> responses = newHashMap();
for (String name : names) {
responses.put(name, chefAsyncClient.deleteClient(name));
}
exceptions = awaitCompletion(responses, userExecutor, maxTime, logger, String.format(
"deleting clients: %s", names));
if (exceptions.size() > 0)
throw new RuntimeException(String.format("errors deleting clients: %s: %s", names, exceptions));
}
}

View File

@ -74,7 +74,7 @@ public class DeleteAllNodesInListImpl implements DeleteAllNodesInList {
responses.put(name, chefAsyncClient.deleteNode(name)); responses.put(name, chefAsyncClient.deleteNode(name));
} }
exceptions = awaitCompletion(responses, userExecutor, maxTime, logger, String.format( exceptions = awaitCompletion(responses, userExecutor, maxTime, logger, String.format(
"getting deleting nodes: %s", names)); "deleting nodes: %s", names));
if (exceptions.size() > 0) if (exceptions.size() > 0)
throw new RuntimeException(String.format("errors deleting nodes: %s: %s", names, exceptions)); throw new RuntimeException(String.format("errors deleting nodes: %s: %s", names, exceptions));
} }

View File

@ -0,0 +1,94 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.chef.strategy.internal;
import static com.google.common.collect.Iterables.filter;
import static org.jclouds.concurrent.FutureIterables.transformParallel;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient;
import org.jclouds.chef.domain.Client;
import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.ListClients;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.inject.Inject;
/**
*
*
* @author Adrian Cole
*/
@Singleton
public class ListClientsImpl implements ListClients {
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
ListClientsImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ChefClient getAllClient,
ChefAsyncClient ablobstore) {
this.userExecutor = userExecutor;
this.chefAsyncClient = ablobstore;
this.chefClient = getAllClient;
}
@Override
public Iterable<? extends Client> execute() {
return execute(chefClient.listClients());
}
@Override
public Iterable<? extends Client> execute(Predicate<String> clientNameSelector) {
return execute(filter(chefClient.listClients(), clientNameSelector));
}
@Override
public Iterable<? extends Client> execute(Iterable<String> toGet) {
return transformParallel(toGet, new Function<String, Future<Client>>() {
@Override
public Future<Client> apply(String from) {
return chefAsyncClient.getClient(from);
}
}, userExecutor, maxTime, logger, "getting clients");
}
}

View File

@ -34,7 +34,7 @@ import org.jclouds.chef.ChefAsyncClient;
import org.jclouds.chef.ChefClient; import org.jclouds.chef.ChefClient;
import org.jclouds.chef.domain.Node; import org.jclouds.chef.domain.Node;
import org.jclouds.chef.reference.ChefConstants; import org.jclouds.chef.reference.ChefConstants;
import org.jclouds.chef.strategy.GetNodes; import org.jclouds.chef.strategy.ListNodes;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import com.google.common.base.Function; import com.google.common.base.Function;
@ -47,7 +47,7 @@ import com.google.inject.Inject;
* @author Adrian Cole * @author Adrian Cole
*/ */
@Singleton @Singleton
public class GetNodesImpl implements GetNodes { public class ListNodesImpl implements ListNodes {
protected final ChefClient chefClient; protected final ChefClient chefClient;
protected final ChefAsyncClient chefAsyncClient; protected final ChefAsyncClient chefAsyncClient;
@ -61,7 +61,7 @@ public class GetNodesImpl implements GetNodes {
protected Long maxTime; protected Long maxTime;
@Inject @Inject
GetNodesImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ChefClient getAllNode, ListNodesImpl(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ChefClient getAllNode,
ChefAsyncClient ablobstore) { ChefAsyncClient ablobstore) {
this.userExecutor = userExecutor; this.userExecutor = userExecutor;
this.chefAsyncClient = ablobstore; this.chefAsyncClient = ablobstore;

View File

@ -39,14 +39,14 @@ import com.google.common.collect.ImmutableSet;
*/ */
@Test(groups = "live", testName = "chef.GetNodesImplLiveTest") @Test(groups = "live", testName = "chef.GetNodesImplLiveTest")
public class GetNodesImplLiveTest extends BaseChefStrategyLiveTest { public class GetNodesImplLiveTest extends BaseChefStrategyLiveTest {
private GetNodesImpl strategy; private ListNodesImpl strategy;
private CreateNodeAndPopulateAutomaticAttributesImpl creater; private CreateNodeAndPopulateAutomaticAttributesImpl creater;
private ChefClient chef; private ChefClient chef;
@BeforeTest(groups = "live", dependsOnMethods = "setupClient") @BeforeTest(groups = "live", dependsOnMethods = "setupClient")
void setupStrategy() { void setupStrategy() {
this.creater = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class); this.creater = injector.getInstance(CreateNodeAndPopulateAutomaticAttributesImpl.class);
this.strategy = injector.getInstance(GetNodesImpl.class); this.strategy = injector.getInstance(ListNodesImpl.class);
this.chef = injector.getInstance(ChefClient.class); this.chef = injector.getInstance(ChefClient.class);
} }