From 56caac57f1f2c417fe568eec5ef0b937d16007e9 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 27 Jul 2010 17:09:10 -0700 Subject: [PATCH] Issue 191: normalized common aggregate commands into ChefService --- .../org/jclouds/chef/ChefAsyncClient.java | 9 +- .../java/org/jclouds/chef/ChefClient.java | 2 +- .../java/org/jclouds/chef/ChefContext.java | 37 +++++++ .../org/jclouds/chef/ChefContextBuilder.java | 69 +++++++++---- .../java/org/jclouds/chef/ChefService.java | 32 ++++++ .../chef/internal/BaseChefService.java | 86 ++++++++++++++++ .../chef/internal/ChefContextImpl.java | 61 ++++++++++++ .../jclouds/chef/reference/ChefConstants.java | 6 +- .../strategy/CleanupStaleNodesAndClients.java | 36 +++++++ ...ateNodeAndPopulateAutomaticAttributes.java | 37 +++++++ .../DeleteAllClientsAndNodesInList.java | 56 +---------- .../org/jclouds/chef/strategy/GetNodes.java | 42 ++++++++ .../UpdateAutomaticAttributesOnNode.java | 35 +++++++ .../CleanupStaleNodesAndClientsImpl.java | 99 +++++++++++++++++++ ...deAndPopulateAutomaticAttributesImpl.java} | 26 +++-- .../DeleteAllClientsAndNodesInListImpl.java | 81 +++++++++++++++ .../GetNodesImpl.java} | 12 ++- .../UpdateAutomaticAttributesOnNodeImpl.java} | 17 ++-- .../java/org/jclouds/ohai/Util/OhaiUtils.java | 45 +++++++++ ...OhaiModule.java => BaseOhaiJVMModule.java} | 16 ++- .../jclouds/ohai/config/BaseOhaiModule.java | 22 ++--- .../jclouds/ohai/config/ConfiguresOhai.java | 16 +++ ...{OhaiModule.java => JMXOhaiJVMModule.java} | 9 +- .../WhiteListCompliantOhaiJVMModule.java | 42 ++++++++ .../org/jclouds/ohai/{ => plugins}/JMX.java | 2 +- .../{ => plugins}/WhiteListCompliantJVM.java | 15 ++- .../org/jclouds/chef/ChefClientLiveTest.java | 16 +-- .../internal/BaseChefStrategyLiveTest.java | 85 ++++++++++++++++ .../CleanupStaleNodesAndClientsImplTest.java | 67 +++++++++++++ ...pulateAutomaticAttributesImplLiveTest.java | 93 +++++++++++++++++ ...dPopulateAutomaticAttributesImplTest.java} | 15 ++- ...eAllClientsAndNodesInListImplLiveTest.java | 69 +++++++++++++ .../internal/GetNodesImplLiveTest.java | 92 +++++++++++++++++ ...AutomaticAttributesOnNodeImplLiveTest.java | 92 +++++++++++++++++ ...ateAutomaticAttributesOnNodeImplTest.java} | 12 +-- .../jclouds/ohai/{ => plugins}/JMXTest.java | 6 +- .../WhiteListCompliantJVMTest.java | 25 ++--- .../org/jclouds/ohai/util/OhaiUtilsTest.java | 54 ++++++++++ 38 files changed, 1374 insertions(+), 162 deletions(-) create mode 100644 chef/src/main/java/org/jclouds/chef/ChefContext.java create mode 100644 chef/src/main/java/org/jclouds/chef/ChefService.java create mode 100644 chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java create mode 100644 chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java create mode 100644 chef/src/main/java/org/jclouds/chef/strategy/CleanupStaleNodesAndClients.java create mode 100644 chef/src/main/java/org/jclouds/chef/strategy/CreateNodeAndPopulateAutomaticAttributes.java create mode 100644 chef/src/main/java/org/jclouds/chef/strategy/GetNodes.java create mode 100644 chef/src/main/java/org/jclouds/chef/strategy/UpdateAutomaticAttributesOnNode.java create mode 100644 chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java rename chef/src/main/java/org/jclouds/{ohai/CreateNode.java => chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java} (67%) create mode 100644 chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImpl.java rename chef/src/main/java/org/jclouds/chef/strategy/{GetAllNodesInList.java => internal/GetNodesImpl.java} (90%) rename chef/src/main/java/org/jclouds/{ohai/UpdateNode.java => chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java} (74%) create mode 100644 chef/src/main/java/org/jclouds/ohai/Util/OhaiUtils.java rename chef/src/main/java/org/jclouds/ohai/config/{WhiteListCompliantOhaiModule.java => BaseOhaiJVMModule.java} (70%) create mode 100644 chef/src/main/java/org/jclouds/ohai/config/ConfiguresOhai.java rename chef/src/main/java/org/jclouds/ohai/config/{OhaiModule.java => JMXOhaiJVMModule.java} (86%) create mode 100644 chef/src/main/java/org/jclouds/ohai/config/WhiteListCompliantOhaiJVMModule.java rename chef/src/main/java/org/jclouds/ohai/{ => plugins}/JMX.java (98%) rename chef/src/main/java/org/jclouds/ohai/{ => plugins}/WhiteListCompliantJVM.java (84%) create mode 100644 chef/src/test/java/org/jclouds/chef/strategy/internal/BaseChefStrategyLiveTest.java create mode 100644 chef/src/test/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImplTest.java create mode 100644 chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java rename chef/src/test/java/org/jclouds/{ohai/CreateNodeTest.java => chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java} (81%) create mode 100644 chef/src/test/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImplLiveTest.java create mode 100644 chef/src/test/java/org/jclouds/chef/strategy/internal/GetNodesImplLiveTest.java create mode 100644 chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java rename chef/src/test/java/org/jclouds/{ohai/UpdateNodeTest.java => chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java} (85%) rename chef/src/test/java/org/jclouds/ohai/{ => plugins}/JMXTest.java (94%) rename chef/src/test/java/org/jclouds/ohai/{ => plugins}/WhiteListCompliantJVMTest.java (83%) create mode 100644 chef/src/test/java/org/jclouds/ohai/util/OhaiUtilsTest.java diff --git a/chef/src/main/java/org/jclouds/chef/ChefAsyncClient.java b/chef/src/main/java/org/jclouds/chef/ChefAsyncClient.java index 7596e8452e..1e350062ec 100644 --- a/chef/src/main/java/org/jclouds/chef/ChefAsyncClient.java +++ b/chef/src/main/java/org/jclouds/chef/ChefAsyncClient.java @@ -198,7 +198,7 @@ public interface ChefAsyncClient { */ @POST @Path("nodes") - ListenableFuture createNode(@BinderParam(BindToJsonPayload.class) Node node); + ListenableFuture createNode(@BinderParam(BindToJsonPayload.class) Node node); /** * @see ChefClient#updateNode @@ -288,8 +288,7 @@ public interface ChefAsyncClient { @ResponseParser(ParseKeySetFromJson.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) ListenableFuture> listRoles(); - - + /** * @see ChefClient#createDataBag */ @@ -302,8 +301,8 @@ public interface ChefAsyncClient { */ @PUT @Path("data/{path}") - ListenableFuture updateDataBag( - @PathParam("path") String path, @BinderParam(BindToJsonPayload.class) JsonBall node); + ListenableFuture updateDataBag(@PathParam("path") String path, + @BinderParam(BindToJsonPayload.class) JsonBall node); /** * @see ChefDataBag#nodeExists diff --git a/chef/src/main/java/org/jclouds/chef/ChefClient.java b/chef/src/main/java/org/jclouds/chef/ChefClient.java index cae3352bd1..258472e998 100644 --- a/chef/src/main/java/org/jclouds/chef/ChefClient.java +++ b/chef/src/main/java/org/jclouds/chef/ChefClient.java @@ -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 diff --git a/chef/src/main/java/org/jclouds/chef/ChefContext.java b/chef/src/main/java/org/jclouds/chef/ChefContext.java new file mode 100644 index 0000000000..4d909445dc --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/ChefContext.java @@ -0,0 +1,37 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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{ + + ChefService getChefService(); + +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/ChefContextBuilder.java b/chef/src/main/java/org/jclouds/chef/ChefContextBuilder.java index 1e812b7f7e..4e9c04969e 100644 --- a/chef/src/main/java/org/jclouds/chef/ChefContextBuilder.java +++ b/chef/src/main/java/org/jclouds/chef/ChefContextBuilder.java @@ -1,24 +1,19 @@ /** * - * Copyright (C) 2010 Cloud Conscious, LLC. + * Copyright (C) 2009 Cloud Conscious, LLC. * * ==================================================================== - * 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 + * 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 { @@ -41,8 +40,44 @@ public class ChefContextBuilder extends RestContextBuilder 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() { + public boolean apply(Module input) { + return input.getClass().isAnnotationPresent(ConfiguresOhai.class); + } + + })) { + addOhaiModule(); + } + } + + protected void addOhaiModule() { + modules.add(new JMXOhaiJVMModule()); + } +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/ChefService.java b/chef/src/main/java/org/jclouds/chef/ChefService.java new file mode 100644 index 0000000000..b1e7c9080f --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/ChefService.java @@ -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 runList); + + void deleteAllClientsAndNodesInList(Iterable names); + + Set getNodes(); + + Set getNodesWithNamesMatching(Predicate nodeNameSelector); + + Set getNodesNamed(Iterable names); + + void updateAutomaticAttributesOnNode(String nodeName); +} diff --git a/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java b/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java new file mode 100644 index 0000000000..4c869bcbca --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/internal/BaseChefService.java @@ -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 runList) { + createNodeAndPopulateAutomaticAttributes.execute(nodeName, runList); + } + + @Override + public void deleteAllClientsAndNodesInList(Iterable names) { + deleteAllClientsAndNodesInList.execute(names); + } + + @Override + public Set getNodes() { + return getNodes.execute(); + } + + @Override + public Set getNodesWithNamesMatching(Predicate nodeNameSelector) { + return getNodes.execute(nodeNameSelector); + } + + @Override + public Set getNodesNamed(Iterable names) { + return getNodes.execute(names); + } + + @Override + public void updateAutomaticAttributesOnNode(String nodeName) { + updateAutomaticAttributesOnNode.execute(nodeName); + } + +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java b/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java new file mode 100644 index 0000000000..dade17c85e --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/internal/ChefContextImpl.java @@ -0,0 +1,61 @@ +/** + * + * Copyright (C) 2009 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 implements ChefContext { + private final ChefService chefService; + + @Inject + protected ChefContextImpl(Closer closer, Utils utils, Injector injector, TypeLiteral syncApi, + TypeLiteral 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; + } + +} diff --git a/chef/src/main/java/org/jclouds/chef/reference/ChefConstants.java b/chef/src/main/java/org/jclouds/chef/reference/ChefConstants.java index b73c436a38..16986de279 100644 --- a/chef/src/main/java/org/jclouds/chef/reference/ChefConstants.java +++ b/chef/src/main/java/org/jclouds/chef/reference/ChefConstants.java @@ -50,7 +50,8 @@ public interface ChefConstants { /** * There are generally 3 types of identities *
    - *
  • validator - used to create clients within an organization; {@code orgname}-validator
  • + *
  • validator - used to create clients within an organization; {@code + * orgname}-validator
  • *
  • client - scoped to an organization, used on nodes to run chef
  • *
  • user - used to run commands like knife and access cookbook sites
  • *
@@ -64,4 +65,7 @@ public interface ChefConstants { /** * how often to refresh timestamps in seconds. */ + + public static final String CHEF_LOGGER = "jclouds.chef"; + } diff --git a/chef/src/main/java/org/jclouds/chef/strategy/CleanupStaleNodesAndClients.java b/chef/src/main/java/org/jclouds/chef/strategy/CleanupStaleNodesAndClients.java new file mode 100644 index 0000000000..6f9567c63e --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/strategy/CleanupStaleNodesAndClients.java @@ -0,0 +1,36 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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); + +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/strategy/CreateNodeAndPopulateAutomaticAttributes.java b/chef/src/main/java/org/jclouds/chef/strategy/CreateNodeAndPopulateAutomaticAttributes.java new file mode 100644 index 0000000000..9de98bd292 --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/strategy/CreateNodeAndPopulateAutomaticAttributes.java @@ -0,0 +1,37 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 runList); +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsAndNodesInList.java b/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsAndNodesInList.java index 80b50212a8..7637a9ee00 100644 --- a/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsAndNodesInList.java +++ b/chef/src/main/java/org/jclouds/chef/strategy/DeleteAllClientsAndNodesInList.java @@ -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 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 names) { - Map exceptions = newHashMap(); - Map> 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)); - } } \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/strategy/GetNodes.java b/chef/src/main/java/org/jclouds/chef/strategy/GetNodes.java new file mode 100644 index 0000000000..f5cdd4e231 --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/strategy/GetNodes.java @@ -0,0 +1,42 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 execute(); + + Set execute(Predicate nodeNameSelector); + + Set execute(Iterable toGet); +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/strategy/UpdateAutomaticAttributesOnNode.java b/chef/src/main/java/org/jclouds/chef/strategy/UpdateAutomaticAttributesOnNode.java new file mode 100644 index 0000000000..d135d3eb4f --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/strategy/UpdateAutomaticAttributesOnNode.java @@ -0,0 +1,35 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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); +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java b/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java new file mode 100644 index 0000000000..6e136583d0 --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java @@ -0,0 +1,99 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 staleNodes = filter(getAllNodes.execute(new Predicate() { + + @Override + public boolean apply(String input) { + return input.startsWith(prefix); + } + + }), and(notNull(), new Predicate() { + @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() { + + @Override + public String apply(Node from) { + return from.getName(); + } + + })); + } +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/ohai/CreateNode.java b/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java similarity index 67% rename from chef/src/main/java/org/jclouds/ohai/CreateNode.java rename to chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java index dcb1b24b2f..28bf75b179 100644 --- a/chef/src/main/java/org/jclouds/ohai/CreateNode.java +++ b/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java @@ -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> automaticSupplier; @Inject - public CreateNode(ChefClient chef, @Named("automatic") Supplier> automaticSupplier) { + public CreateNodeAndPopulateAutomaticAttributesImpl(ChefClient chef, + @Named("automatic") Supplier> automaticSupplier) { this.chef = checkNotNull(chef, "chef"); this.automaticSupplier = checkNotNull(automaticSupplier, "automaticSupplier"); } - public Node createNode(String nodeName, Iterable 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 runList) { + execute(new Node(nodeName, runList)); } } \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImpl.java b/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImpl.java new file mode 100644 index 0000000000..9cb1c0080b --- /dev/null +++ b/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImpl.java @@ -0,0 +1,81 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 names) { + Map exceptions = newHashMap(); + Map> 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)); + } +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/chef/strategy/GetAllNodesInList.java b/chef/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java similarity index 90% rename from chef/src/main/java/org/jclouds/chef/strategy/GetAllNodesInList.java rename to chef/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java index 73b0093a34..370b3782bc 100644 --- a/chef/src/main/java/org/jclouds/chef/strategy/GetAllNodesInList.java +++ b/chef/src/main/java/org/jclouds/chef/strategy/internal/GetNodesImpl.java @@ -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 execute() { return execute(chefClient.listNodes()); } + @Override public Set execute(Predicate nodeNameSelector) { return execute(filter(chefClient.listNodes(), nodeNameSelector)); } + @Override public Set execute(Iterable toGet) { Map exceptions = newHashMap(); final Set nodes = newHashSet(); diff --git a/chef/src/main/java/org/jclouds/ohai/UpdateNode.java b/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java similarity index 74% rename from chef/src/main/java/org/jclouds/ohai/UpdateNode.java rename to chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java index 2119c3a3f7..fc50273994 100644 --- a/chef/src/main/java/org/jclouds/ohai/UpdateNode.java +++ b/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java @@ -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> automaticSupplier; @Inject - public UpdateNode(ChefClient chef, @Named("automatic") Supplier> automaticSupplier) { + public UpdateAutomaticAttributesOnNodeImpl(ChefClient chef, + @Named("automatic") Supplier> 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); } } \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/ohai/Util/OhaiUtils.java b/chef/src/main/java/org/jclouds/ohai/Util/OhaiUtils.java new file mode 100644 index 0000000000..04192f392a --- /dev/null +++ b/chef/src/main/java/org/jclouds/ohai/Util/OhaiUtils.java @@ -0,0 +1,45 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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()); + } +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/ohai/config/WhiteListCompliantOhaiModule.java b/chef/src/main/java/org/jclouds/ohai/config/BaseOhaiJVMModule.java similarity index 70% rename from chef/src/main/java/org/jclouds/ohai/config/WhiteListCompliantOhaiModule.java rename to chef/src/main/java/org/jclouds/ohai/config/BaseOhaiJVMModule.java index a61f3859a1..afb1481ba1 100644 --- a/chef/src/main/java/org/jclouds/ohai/config/WhiteListCompliantOhaiModule.java +++ b/chef/src/main/java/org/jclouds/ohai/config/BaseOhaiJVMModule.java @@ -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(); + } } \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/ohai/config/BaseOhaiModule.java b/chef/src/main/java/org/jclouds/ohai/config/BaseOhaiModule.java index 27f10d336b..7f17341263 100644 --- a/chef/src/main/java/org/jclouds/ohai/config/BaseOhaiModule.java +++ b/chef/src/main/java/org/jclouds/ohai/config/BaseOhaiModule.java @@ -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> automaticSupplier( @Named("automatic") Iterable>> suppliers) { - return Utils.composeMapSupplier(suppliers); + return composeMapSupplier(suppliers); } @Named("automatic") @Singleton @Provides - Iterable>> suppliers(Injector injector) { - return ImmutableList.>> of(injector.getInstance(WhiteListCompliantJVM.class)); - } + protected abstract Iterable>> suppliers(Injector injector); } \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/ohai/config/ConfiguresOhai.java b/chef/src/main/java/org/jclouds/ohai/config/ConfiguresOhai.java new file mode 100644 index 0000000000..de84bbe041 --- /dev/null +++ b/chef/src/main/java/org/jclouds/ohai/config/ConfiguresOhai.java @@ -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 { +} diff --git a/chef/src/main/java/org/jclouds/ohai/config/OhaiModule.java b/chef/src/main/java/org/jclouds/ohai/config/JMXOhaiJVMModule.java similarity index 86% rename from chef/src/main/java/org/jclouds/ohai/config/OhaiModule.java rename to chef/src/main/java/org/jclouds/ohai/config/JMXOhaiJVMModule.java index 22f3a6062e..2e7f066103 100644 --- a/chef/src/main/java/org/jclouds/ohai/config/OhaiModule.java +++ b/chef/src/main/java/org/jclouds/ohai/config/JMXOhaiJVMModule.java @@ -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>> suppliers(Injector injector) { + protected Iterable>> suppliers(Injector injector) { return ImmutableList.>> of(injector.getInstance(WhiteListCompliantJVM.class), injector.getInstance(JMX.class)); } diff --git a/chef/src/main/java/org/jclouds/ohai/config/WhiteListCompliantOhaiJVMModule.java b/chef/src/main/java/org/jclouds/ohai/config/WhiteListCompliantOhaiJVMModule.java new file mode 100644 index 0000000000..286205bc4b --- /dev/null +++ b/chef/src/main/java/org/jclouds/ohai/config/WhiteListCompliantOhaiJVMModule.java @@ -0,0 +1,42 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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>> suppliers(Injector injector) { + return ImmutableList.>> of(injector.getInstance(WhiteListCompliantJVM.class)); + } +} \ No newline at end of file diff --git a/chef/src/main/java/org/jclouds/ohai/JMX.java b/chef/src/main/java/org/jclouds/ohai/plugins/JMX.java similarity index 98% rename from chef/src/main/java/org/jclouds/ohai/JMX.java rename to chef/src/main/java/org/jclouds/ohai/plugins/JMX.java index a7d650d3b1..5771fb6208 100644 --- a/chef/src/main/java/org/jclouds/ohai/JMX.java +++ b/chef/src/main/java/org/jclouds/ohai/plugins/JMX.java @@ -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; diff --git a/chef/src/main/java/org/jclouds/ohai/WhiteListCompliantJVM.java b/chef/src/main/java/org/jclouds/ohai/plugins/WhiteListCompliantJVM.java similarity index 84% rename from chef/src/main/java/org/jclouds/ohai/WhiteListCompliantJVM.java rename to chef/src/main/java/org/jclouds/ohai/plugins/WhiteListCompliantJVM.java index 93b5c96ecc..9407da5255 100644 --- a/chef/src/main/java/org/jclouds/ohai/WhiteListCompliantJVM.java +++ b/chef/src/main/java/org/jclouds/ohai/plugins/WhiteListCompliantJVM.java @@ -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> { } public Map get() { - Map returnVal = Maps.newLinkedHashMap(); + Map 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))); diff --git a/chef/src/test/java/org/jclouds/chef/ChefClientLiveTest.java b/chef/src/test/java/org/jclouds/chef/ChefClientLiveTest.java index 494d76e6d3..34cbf5a8b3 100644 --- a/chef/src/test/java/org/jclouds/chef/ChefClientLiveTest.java +++ b/chef/src/test/java/org/jclouds/chef/ChefClientLiveTest.java @@ -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 validatorConnection; - private RestContext clientConnection; - private RestContext 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 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 - . of(new Log4JLoggingModule()), props); + return (ChefContext) new RestContextFactory(). createContext("chef", identity, key, + ImmutableSet. 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 nodes = adminConnection.getApi().listNodes(); diff --git a/chef/src/test/java/org/jclouds/chef/strategy/internal/BaseChefStrategyLiveTest.java b/chef/src/test/java/org/jclouds/chef/strategy/internal/BaseChefStrategyLiveTest.java new file mode 100644 index 0000000000..3d24ee7dd0 --- /dev/null +++ b/chef/src/test/java/org/jclouds/chef/strategy/internal/BaseChefStrategyLiveTest.java @@ -0,0 +1,85 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 modules = Sets.newHashSet(); + modules.add(new Log4JLoggingModule()); + addTestModulesTo(modules); + injector = new RestContextFactory(). createContextBuilder("chef", user, + Files.toString(new File(keyfile), Charsets.UTF_8), modules, props).buildInjector(); + } + + protected void addTestModulesTo(Set modules) { + + } + + @AfterTest(groups = { "live" }) + public void teardownClient() throws IOException { + if (injector != null) + injector.getInstance(Closer.class).close(); + } +} diff --git a/chef/src/test/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImplTest.java b/chef/src/test/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImplTest.java new file mode 100644 index 0000000000..84f0499703 --- /dev/null +++ b/chef/src/test/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImplTest.java @@ -0,0 +1,67 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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. 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); + } + } + +} diff --git a/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java b/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java new file mode 100644 index 0000000000..90b99ac481 --- /dev/null +++ b/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplLiveTest.java @@ -0,0 +1,93 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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>> suppliers(Injector injector) { + Supplier> supplier = Suppliers.> ofInstance(ImmutableMap + . of("foo", new JsonBall("bar"))); + return ImmutableList.>> of(supplier); + } + } + + protected void addTestModulesTo(Set 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 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); + } + } +} diff --git a/chef/src/test/java/org/jclouds/ohai/CreateNodeTest.java b/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java similarity index 81% rename from chef/src/test/java/org/jclouds/ohai/CreateNodeTest.java rename to chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java index 1adc0da1df..6d52bddc25 100644 --- a/chef/src/test/java/org/jclouds/ohai/CreateNodeTest.java +++ b/chef/src/test/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImplTest.java @@ -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 { . of(), ImmutableMap. of(), automatic, ImmutableSet. 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. of()); + updater.execute("name", ImmutableSet. of()); verify(chef); } diff --git a/chef/src/test/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImplLiveTest.java b/chef/src/test/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImplLiveTest.java new file mode 100644 index 0000000000..db3fd2cb78 --- /dev/null +++ b/chef/src/test/java/org/jclouds/chef/strategy/internal/DeleteAllClientsAndNodesInListImplLiveTest.java @@ -0,0 +1,69 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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. of()); + creater.execute(prefix + 1, ImmutableSet. 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); + } + } +} diff --git a/chef/src/test/java/org/jclouds/chef/strategy/internal/GetNodesImplLiveTest.java b/chef/src/test/java/org/jclouds/chef/strategy/internal/GetNodesImplLiveTest.java new file mode 100644 index 0000000000..b16bf5e7f8 --- /dev/null +++ b/chef/src/test/java/org/jclouds/chef/strategy/internal/GetNodesImplLiveTest.java @@ -0,0 +1,92 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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. of()); + creater.execute(prefix + 1, ImmutableSet. 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() { + + @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); + } + +} diff --git a/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java b/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java new file mode 100644 index 0000000000..d4129bbc08 --- /dev/null +++ b/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplLiveTest.java @@ -0,0 +1,92 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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>> suppliers(Injector injector) { + Supplier> supplier = Suppliers.> ofInstance(ImmutableMap + . of("foo", new JsonBall("bar"))); + return ImmutableList.>> of(supplier); + } + } + + protected void addTestModulesTo(Set 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 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); + } + } +} diff --git a/chef/src/test/java/org/jclouds/ohai/UpdateNodeTest.java b/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java similarity index 85% rename from chef/src/test/java/org/jclouds/ohai/UpdateNodeTest.java rename to chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java index 6b091d8f30..3d970b565c 100644 --- a/chef/src/test/java/org/jclouds/ohai/UpdateNodeTest.java +++ b/chef/src/test/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImplTest.java @@ -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); } diff --git a/chef/src/test/java/org/jclouds/ohai/JMXTest.java b/chef/src/test/java/org/jclouds/ohai/plugins/JMXTest.java similarity index 94% rename from chef/src/test/java/org/jclouds/ohai/JMXTest.java rename to chef/src/test/java/org/jclouds/ohai/plugins/JMXTest.java index 1cef74d548..bcac75eef4 100644 --- a/chef/src/test/java/org/jclouds/ohai/JMXTest.java +++ b/chef/src/test/java/org/jclouds/ohai/plugins/JMXTest.java @@ -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; diff --git a/chef/src/test/java/org/jclouds/ohai/WhiteListCompliantJVMTest.java b/chef/src/test/java/org/jclouds/ohai/plugins/WhiteListCompliantJVMTest.java similarity index 83% rename from chef/src/test/java/org/jclouds/ohai/WhiteListCompliantJVMTest.java rename to chef/src/test/java/org/jclouds/ohai/plugins/WhiteListCompliantJVMTest.java index 78aaec58bd..7f016660e9 100644 --- a/chef/src/test/java/org/jclouds/ohai/WhiteListCompliantJVMTest.java +++ b/chef/src/test/java/org/jclouds/ohai/plugins/WhiteListCompliantJVMTest.java @@ -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,18 +54,19 @@ 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() { - @Override - protected Long nanoTime() { - return 1279992919325290l; - } + Injector injector = Guice.createInjector(new ChefParserModule(), new GsonModule(), + new WhiteListCompliantOhaiJVMModule() { + @Override + protected Long nanoTime() { + return 1279992919325290l; + } - @Override - protected Properties systemProperties() { - return sysProperties; - } + @Override + protected Properties systemProperties() { + return sysProperties; + } - }); + }); Json json = injector.getInstance(Json.class); WhiteListCompliantJVM WhiteListCompliantJVM = injector.getInstance(WhiteListCompliantJVM.class); diff --git a/chef/src/test/java/org/jclouds/ohai/util/OhaiUtilsTest.java b/chef/src/test/java/org/jclouds/ohai/util/OhaiUtilsTest.java new file mode 100644 index 0000000000..dbba9b539c --- /dev/null +++ b/chef/src/test/java/org/jclouds/ohai/util/OhaiUtilsTest.java @@ -0,0 +1,54 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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); + + } + +}