http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/BaseListNodesImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/BaseListNodesImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/BaseListNodesImpl.java new file mode 100644 index 0000000..a426b8d --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/BaseListNodesImpl.java @@ -0,0 +1,77 @@ +/* + * 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 com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.domain.Node; +import org.jclouds.logging.Logger; + +import java.util.List; +import java.util.concurrent.Callable; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.transform; +import static com.google.common.util.concurrent.Futures.allAsList; +import static com.google.common.util.concurrent.Futures.getUnchecked; + +public abstract class BaseListNodesImpl { + + protected final ChefApi api; + + protected Logger logger = Logger.NULL; + + BaseListNodesImpl(ChefApi api) { + this.api = checkNotNull(api, "api"); + } + + protected Iterable<? extends Node> execute(Iterable<String> toGet) { + Iterable<? extends Node> nodes = transform(toGet, new Function<String, Node>() { + @Override + public Node apply(final String input) { + return api.getNode(input); + } + } + ); + + logger.trace(String.format("getting nodes: %s", Joiner.on(',').join(toGet))); + return nodes; + + } + + protected Iterable<? extends Node> executeConcurrently(final ListeningExecutorService executor, + Iterable<String> toGet) { + ListenableFuture<List<Node>> futures = allAsList(transform(toGet, new Function<String, ListenableFuture<Node>>() { + @Override + public ListenableFuture<Node> apply(final String input) { + return executor.submit(new Callable<Node>() { + @Override + public Node call() throws Exception { + return api.getNode(input); + } + }); + } + })); + + logger.trace(String.format("getting nodes: %s", Joiner.on(',').join(toGet))); + return getUnchecked(futures); + } + +}
http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java new file mode 100644 index 0000000..46c765b --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CleanupStaleNodesAndClientsImpl.java @@ -0,0 +1,102 @@ +/* + * 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 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.chef.util.ChefUtils.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.config.ChefProperties; +import org.jclouds.chef.domain.Node; +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.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; + +/** + * + * Cleans up nodes and apis who have been hanging around too long. + */ +@Singleton +public class CleanupStaleNodesAndClientsImpl implements CleanupStaleNodesAndClients { + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + private final ListNodes nodeLister; + private final DeleteAllNodesInList nodeDeleter; + private final DeleteAllClientsInList clientDeleter; + + @Inject + public CleanupStaleNodesAndClientsImpl(DeleteAllNodesInList nodeDeleter, DeleteAllClientsInList clientDeleter, + ListNodes nodeLister) { + this.nodeLister = checkNotNull(nodeLister, "nodeLister"); + this.nodeDeleter = checkNotNull(nodeDeleter, "nodeDeleter"); + this.clientDeleter = checkNotNull(clientDeleter, "clientDeleter"); + } + + @Override + public void execute(final String prefix, int secondsStale) { + final Calendar expired = Calendar.getInstance(); + expired.setTime(new Date()); + expired.add(Calendar.SECOND, -secondsStale); + Iterable<? extends Node> staleNodes = filter( + nodeLister.execute(), and(notNull(), new Predicate<Node>() { + @Override + public boolean apply(Node input) { + return input.getName().startsWith(prefix); + } + }, + new Predicate<Node>() { + @Override + public boolean apply(Node input) { + JsonBall dateLong = input.getAutomaticAttributes().get("ohai_time"); + if (dateLong == null) + return true; + Calendar nodeUpdate = Calendar.getInstance(); + nodeUpdate.setTime(fromOhaiTime(dateLong)); + return expired.after(nodeUpdate); + } + })); + Iterable<String> nodeNames = transform(staleNodes, new Function<Node, String>() { + + @Override + public String apply(Node from) { + return from.getName(); + } + + }); + nodeDeleter.execute(nodeNames); + clientDeleter.execute(nodeNames); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java new file mode 100644 index 0000000..7dabd06 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/CreateNodeAndPopulateAutomaticAttributesImpl.java @@ -0,0 +1,83 @@ +/* + * 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.util.Map; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.strategy.CreateNodeAndPopulateAutomaticAttributes; +import org.jclouds.domain.JsonBall; +import org.jclouds.logging.Logger; +import org.jclouds.ohai.Automatic; + +import com.google.common.base.Supplier; + +/** + * + * Updates node with new automatic attributes. + */ +@Singleton +public class CreateNodeAndPopulateAutomaticAttributesImpl implements CreateNodeAndPopulateAutomaticAttributes { + + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + private final ChefApi chef; + private final Supplier<Map<String, JsonBall>> automaticSupplier; + + @Inject + public CreateNodeAndPopulateAutomaticAttributesImpl(ChefApi chef, + @Automatic Supplier<Map<String, JsonBall>> automaticSupplier) { + this.chef = checkNotNull(chef, "chef"); + this.automaticSupplier = checkNotNull(automaticSupplier, "automaticSupplier"); + } + + @Override + public Node execute(Node node) { + logger.trace("creating node %s", node.getName()); + Node withAutomatic = Node.builder() // + .name(node.getName()) // + .normalAttributes(node.getNormalAttributes()) // + .overrideAttributes(node.getOverrideAttributes()) // + .defaultAttributes(node.getDefaultAttributes()) // + .automaticAttributes(node.getAutomaticAttributes()) // + .automaticAttributes(automaticSupplier.get()) // + .runList(node.getRunList()) // + .environment(node.getEnvironment()) // + .build(); + + + chef.createNode(withAutomatic); + logger.debug("created node %s", withAutomatic.getName()); + return node; + } + + @Override + public Node execute(String nodeName, Iterable<String> runList) { + return execute(Node.builder().name(nodeName).runList(runList).environment("_default").build()); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsInListImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsInListImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsInListImpl.java new file mode 100644 index 0000000..ffdd3ec --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllClientsInListImpl.java @@ -0,0 +1,85 @@ +/* + * 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 static com.google.common.collect.Iterables.transform; +import static com.google.common.util.concurrent.Futures.allAsList; +import static com.google.common.util.concurrent.Futures.getUnchecked; + +import java.util.List; +import java.util.concurrent.Callable; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.Constants; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.strategy.DeleteAllClientsInList; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.Inject; + +/** + * Concurrently delete all given clients. + */ +@Singleton +public class DeleteAllClientsInListImpl implements DeleteAllClientsInList { + + protected final ChefApi api; + protected final ListeningExecutorService userExecutor; + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + DeleteAllClientsInListImpl(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, ChefApi api) { + this.userExecutor = checkNotNull(userExecutor, "userExecuor"); + this.api = checkNotNull(api, "api"); + } + + @Override + public void execute(Iterable<String> names) { + execute(userExecutor, names); + } + + @Override + public void execute(final ListeningExecutorService executor, Iterable<String> names) { + ListenableFuture<List<Client>> futures = allAsList(transform(names, + new Function<String, ListenableFuture<Client>>() { + @Override + public ListenableFuture<Client> apply(final String input) { + return executor.submit(new Callable<Client>() { + @Override + public Client call() throws Exception { + return api.deleteClient(input); + } + }); + } + })); + + logger.trace(String.format("deleting clients: %s", Joiner.on(',').join(names))); + getUnchecked(futures); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllNodesInListImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllNodesInListImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllNodesInListImpl.java new file mode 100644 index 0000000..212d8b7 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/DeleteAllNodesInListImpl.java @@ -0,0 +1,81 @@ +/* + * 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 static com.google.common.collect.Iterables.transform; +import static com.google.common.util.concurrent.Futures.allAsList; +import static com.google.common.util.concurrent.Futures.getUnchecked; + +import java.util.List; +import java.util.concurrent.Callable; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.Constants; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.strategy.DeleteAllNodesInList; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.Inject; + +@Singleton +public class DeleteAllNodesInListImpl implements DeleteAllNodesInList { + + protected final ChefApi api; + protected final ListeningExecutorService userExecutor; + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + DeleteAllNodesInListImpl(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, ChefApi api) { + this.userExecutor = checkNotNull(userExecutor, "userExecuor"); + this.api = checkNotNull(api, "api"); + } + + @Override + public void execute(Iterable<String> names) { + execute(userExecutor, names); + } + + @Override + public void execute(final ListeningExecutorService executor, Iterable<String> names) { + ListenableFuture<List<Node>> futures = allAsList(transform(names, new Function<String, ListenableFuture<Node>>() { + @Override + public ListenableFuture<Node> apply(final String input) { + return executor.submit(new Callable<Node>() { + @Override + public Node call() throws Exception { + return api.deleteNode(input); + } + }); + } + })); + + logger.trace(String.format("deleting nodes: %s", Joiner.on(',').join(names))); + getUnchecked(futures); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListClientsImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListClientsImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListClientsImpl.java new file mode 100644 index 0000000..105be2f --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListClientsImpl.java @@ -0,0 +1,109 @@ +/* + * 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 static com.google.common.collect.Iterables.transform; +import static com.google.common.util.concurrent.Futures.allAsList; +import static com.google.common.util.concurrent.Futures.getUnchecked; + +import java.util.List; +import java.util.concurrent.Callable; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.inject.Inject; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.strategy.ListClients; +import org.jclouds.logging.Logger; + +import java.util.concurrent.ExecutorService; + + +@Singleton +public class ListClientsImpl implements ListClients { + + protected final ChefApi api; + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + ListClientsImpl(ChefApi api) { + this.api = checkNotNull(api, "api"); + } + + @Override + public Iterable<? extends Client> execute() { + + Iterable<String> toGet = api.listClients(); + Iterable<? extends Client> clients = transform(toGet, + new Function<String, Client>() { + @Override + public Client apply(final String input) { + + return api.getClient(input); + } + + } + ); + + logger.trace(String.format("getting clients: %s", Joiner.on(',').join(toGet))); + return clients; + + } + + @Override + public Iterable<? extends Client> execute(ExecutorService executorService) { + return this.execute(MoreExecutors.listeningDecorator(executorService)); + } + + + private Iterable<? extends Client> execute(ListeningExecutorService listeningExecutor) { + return executeConcurrently(listeningExecutor, api.listClients()); + } + + private Iterable<? extends Client> executeConcurrently(final ListeningExecutorService executor, + Iterable<String> toGet) { + ListenableFuture<List<Client>> futures = allAsList(transform(toGet, + new Function<String, ListenableFuture<Client>>() { + @Override + public ListenableFuture<Client> apply(final String input) { + return executor.submit(new Callable<Client>() { + @Override + public Client call() throws Exception { + return api.getClient(input); + } + }); + } + } + )); + + logger.trace(String.format("getting clients: %s", Joiner.on(',').join(toGet))); + return getUnchecked(futures); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsImpl.java new file mode 100644 index 0000000..d109038 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsImpl.java @@ -0,0 +1,60 @@ +/* + * 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 com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.inject.Inject; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.strategy.ListCookbookVersions; +import org.jclouds.logging.Logger; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; +import java.util.concurrent.ExecutorService; + +@Singleton +public class ListCookbookVersionsImpl extends BaseListCookbookVersionsImpl implements ListCookbookVersions { + + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + ListCookbookVersionsImpl(ChefApi api) { + super(api); + } + + @Override + public Iterable<? extends CookbookVersion> execute() { + return super.execute(api.listCookbooks()); + } + + @Override + public Iterable<? extends CookbookVersion> execute(ExecutorService executor) { + return this.executeConcurrently(MoreExecutors.listeningDecorator(executor)); + } + + + private Iterable<? extends CookbookVersion> executeConcurrently(ListeningExecutorService executor) { + return super.executeConcurrently(executor, api.listCookbooks()); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImpl.java new file mode 100644 index 0000000..a7142dc --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListCookbookVersionsInEnvironmentImpl.java @@ -0,0 +1,117 @@ +/* + * 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.collect.Iterables.transform; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import com.google.common.base.Function; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.inject.Inject; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.CookbookDefinition; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.strategy.ListCookbookVersionsInEnvironment; +import org.jclouds.logging.Logger; + +import java.util.concurrent.ExecutorService; + +@Singleton +public class ListCookbookVersionsInEnvironmentImpl extends BaseListCookbookVersionsImpl + implements ListCookbookVersionsInEnvironment { + + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + ListCookbookVersionsInEnvironmentImpl(ChefApi api) { + super(api); + } + + @Override + public Iterable<? extends CookbookVersion> execute(String environmentName) { + return super.execute(transform(api.listCookbooksInEnvironment(environmentName), + new Function<CookbookDefinition, String>() { + + @Override + public String apply(CookbookDefinition cookbookDefinition) { + return cookbookDefinition.getName(); + } + } + )); + } + + @Override + public Iterable<? extends CookbookVersion> execute(String environmentName, String numVersions) { + return super.execute(transform(api.listCookbooksInEnvironment(environmentName, numVersions), + new Function<CookbookDefinition, String>() { + + @Override + public String apply(CookbookDefinition cookbookDefinition) { + return cookbookDefinition.getName(); + } + } + )); + } + + @Override + public Iterable<? extends CookbookVersion> execute(ExecutorService executor, + String environmentName) { + return this.executeConcurrently(MoreExecutors.listeningDecorator(executor), environmentName); + } + + @Override + public Iterable<? extends CookbookVersion> execute(ExecutorService executor, + String environmentName, String numVersions) { + return this.executeConcurrently(MoreExecutors.listeningDecorator(executor), environmentName, numVersions); + } + + + private Iterable<? extends CookbookVersion> executeConcurrently(ListeningExecutorService executor, + String environmentName) { + return super.execute( + transform(api.listCookbooksInEnvironment(environmentName), new Function<CookbookDefinition, String>() { + + @Override + public String apply(CookbookDefinition cookbookDefinition) { + return cookbookDefinition.getName(); + } + }) + ); + } + + + private Iterable<? extends CookbookVersion> executeConcurrently(ListeningExecutorService executor, + String environmentName, String numVersions) { + return super.execute(transform(api.listCookbooksInEnvironment(environmentName, numVersions), + new Function<CookbookDefinition, String>() { + + @Override + public String apply(CookbookDefinition cookbookDefinition) { + return cookbookDefinition.getName(); + } + } + )); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListEnvironmentsImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListEnvironmentsImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListEnvironmentsImpl.java new file mode 100644 index 0000000..0ed792e --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListEnvironmentsImpl.java @@ -0,0 +1,96 @@ +/* + * 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 static com.google.common.collect.Iterables.transform; +import static com.google.common.util.concurrent.Futures.allAsList; +import static com.google.common.util.concurrent.Futures.getUnchecked; + +import java.util.List; +import java.util.concurrent.Callable; + +import javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.Constants; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.Environment; +import org.jclouds.chef.strategy.ListEnvironments; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.inject.Inject; +import com.google.common.util.concurrent.MoreExecutors; + + +import java.util.concurrent.ExecutorService; + + + +@Singleton +public class ListEnvironmentsImpl implements ListEnvironments { + + protected final ChefApi api; + protected final ListeningExecutorService userExecutor; + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + ListEnvironmentsImpl(@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, ChefApi api) { + this.userExecutor = checkNotNull(userExecutor, "userExecuor"); + this.api = checkNotNull(api, "api"); + } + + @Override + public Iterable<? extends Environment> execute() { + return execute(userExecutor); + } + + @Override + public Iterable<? extends Environment> execute(ExecutorService executor) { + return this.execute(MoreExecutors.listeningDecorator(executor)); + } + + private Iterable<? extends Environment> execute(ListeningExecutorService executor) { + return execute(executor, api.listEnvironments()); + } + + private Iterable<? extends Environment> execute(final ListeningExecutorService executor, Iterable<String> toGet) { + ListenableFuture<List<Environment>> futures = allAsList(transform(toGet, + new Function<String, ListenableFuture<Environment>>() { + @Override + public ListenableFuture<Environment> apply(final String input) { + return executor.submit(new Callable<Environment>() { + @Override + public Environment call() throws Exception { + return api.getEnvironment(input); + } + }); + } + })); + + logger.trace(String.format("deleting environments: %s", Joiner.on(',').join(toGet))); + return getUnchecked(futures); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListNodesImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListNodesImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListNodesImpl.java new file mode 100644 index 0000000..8d95965 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListNodesImpl.java @@ -0,0 +1,62 @@ +/* + * 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 javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.inject.Inject; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.strategy.ListNodes; +import org.jclouds.logging.Logger; + +import java.util.concurrent.ExecutorService; + +@Singleton +public class ListNodesImpl extends BaseListNodesImpl implements ListNodes { + + + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + ListNodesImpl(ChefApi api) { + super(api); + } + + @Override + public Iterable<? extends Node> execute() { + return super.execute(api.listNodes()); + } + + @Override + public Iterable<? extends Node> execute(ExecutorService executor) { + return this.executeConcurrently(MoreExecutors.listeningDecorator(executor)); + } + + + private Iterable<? extends Node> executeConcurrently(ListeningExecutorService executor) { + return super.executeConcurrently(executor, api.listNodes()); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListNodesInEnvironmentImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListNodesInEnvironmentImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListNodesInEnvironmentImpl.java new file mode 100644 index 0000000..58ecaaa --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/ListNodesInEnvironmentImpl.java @@ -0,0 +1,62 @@ +/* + * 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 javax.annotation.Resource; +import javax.inject.Named; +import javax.inject.Singleton; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import com.google.inject.Inject; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.strategy.ListNodesInEnvironment; +import org.jclouds.logging.Logger; + +import java.util.concurrent.ExecutorService; + +@Singleton +public class ListNodesInEnvironmentImpl extends BaseListNodesImpl implements ListNodesInEnvironment { + + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + @Inject + ListNodesInEnvironmentImpl(ChefApi api) { + super(api); + } + + @Override + public Iterable<? extends Node> execute(String environmentName) { + return super.execute(api.listNodesInEnvironment(environmentName)); + } + + @Override + public Iterable<? extends Node> execute(ExecutorService executor, String environmentName) { + return this.executeConcurrently(MoreExecutors.listeningDecorator(executor), environmentName); + } + + + private Iterable<? extends Node> executeConcurrently(ListeningExecutorService executor, + String environmentName) { + return super.executeConcurrently(executor, api.listNodesInEnvironment(environmentName)); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java new file mode 100644 index 0000000..a6dcac2 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/strategy/internal/UpdateAutomaticAttributesOnNodeImpl.java @@ -0,0 +1,75 @@ +/* + * 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.util.Map; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.strategy.UpdateAutomaticAttributesOnNode; +import org.jclouds.domain.JsonBall; +import org.jclouds.logging.Logger; +import org.jclouds.ohai.Automatic; + +import com.google.common.base.Supplier; + +/** + * + * Updates node with new automatic attributes. + */ +@Singleton +public class UpdateAutomaticAttributesOnNodeImpl implements UpdateAutomaticAttributesOnNode { + + @Resource + @Named(ChefProperties.CHEF_LOGGER) + protected Logger logger = Logger.NULL; + + private final ChefApi chef; + private final Supplier<Map<String, JsonBall>> automaticSupplier; + + @Inject + public UpdateAutomaticAttributesOnNodeImpl(ChefApi chef, @Automatic Supplier<Map<String, JsonBall>> automaticSupplier) { + this.chef = checkNotNull(chef, "chef"); + this.automaticSupplier = checkNotNull(automaticSupplier, "automaticSupplier"); + } + + @Override + public void execute(String nodeName) { + logger.trace("updating node %s", nodeName); + Node node = chef.getNode(nodeName); + Node updated = Node.builder() // + .name(node.getName()) // + .normalAttributes(node.getNormalAttributes()) // + .overrideAttributes(node.getOverrideAttributes()) // + .defaultAttributes(node.getDefaultAttributes()) // + .automaticAttributes(automaticSupplier.get()) // + .runList(node.getRunList()) // + .environment(node.getEnvironment()) // + .build(); + + chef.updateNode(updated); + logger.debug("updated node %s", nodeName); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/suppliers/ChefVersionSupplier.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/suppliers/ChefVersionSupplier.java b/apis/chef/src/main/java/org/jclouds/chef/suppliers/ChefVersionSupplier.java new file mode 100644 index 0000000..a0d8b04 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/suppliers/ChefVersionSupplier.java @@ -0,0 +1,73 @@ +/* + * 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.suppliers; + +import static com.google.common.base.Objects.firstNonNull; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.chef.config.ChefProperties; +import org.jclouds.logging.Logger; +import org.jclouds.rest.annotations.ApiVersion; + +import com.google.common.base.Supplier; + +/** + * Properly supply the version of the Chef Server. + */ +@Singleton +public class ChefVersionSupplier implements Supplier<Integer> { + + /** The default version to assume in case we can not parse it. */ + public static final Integer FALLBACK_VERSION = 10; + + @Resource + @Named(ChefProperties.CHEF_LOGGER) + private Logger logger = Logger.NULL; + + /** The configured version of the Chef Server API. */ + private final String apiVersion; + + @Inject + ChefVersionSupplier(@ApiVersion String apiVersion) { + this.apiVersion = checkNotNull(apiVersion, "apiVersion must not be null"); + } + + @Override + public Integer get() { + // Old versions of Chef have versions like 0.9.x, 0.10.x, but newer + // versions are in the format 10.x.y, 11.x.y + Pattern versionPattern = Pattern.compile("(?:0\\.(\\d+)|(\\d+)\\.\\d+)(?:\\.\\d)*"); + + Matcher m = versionPattern.matcher(apiVersion); + if (!m.matches()) { + logger.warn("Configured version does not match the standard version pattern. Assuming version %s", + FALLBACK_VERSION); + return FALLBACK_VERSION; + } + + return Integer.valueOf(firstNonNull(m.group(1), m.group(2))); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApi.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApi.java b/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApi.java new file mode 100644 index 0000000..c2c5f10 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApi.java @@ -0,0 +1,387 @@ +/* + * 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.test; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Throwables.propagate; +import static com.google.common.collect.Iterables.transform; +import static com.google.common.collect.Sets.newLinkedHashSet; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.blobstore.config.LocalBlobStore; +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.PageSet; +import org.jclouds.blobstore.domain.StorageMetadata; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.domain.CookbookDefinition; +import org.jclouds.chef.domain.CookbookVersion; +import org.jclouds.chef.domain.DatabagItem; +import org.jclouds.chef.domain.Environment; +import org.jclouds.chef.domain.Node; +import org.jclouds.chef.domain.Resource; +import org.jclouds.chef.domain.Role; +import org.jclouds.chef.domain.Sandbox; +import org.jclouds.chef.domain.SearchResult; +import org.jclouds.chef.domain.UploadSandbox; +import org.jclouds.chef.options.CreateClientOptions; +import org.jclouds.chef.options.SearchOptions; +import org.jclouds.io.Payload; +import org.jclouds.lifecycle.Closer; +import org.jclouds.util.Strings2; + +import com.google.common.base.Function; + +/** + * In-memory chef simulator. + */ +public class TransientChefApi implements ChefApi { + @Singleton + private static class StorageMetadataToName implements Function<PageSet<? extends StorageMetadata>, Set<String>> { + @Override + public Set<String> apply(PageSet<? extends StorageMetadata> from) { + return newLinkedHashSet(transform(from, new Function<StorageMetadata, String>() { + + @Override + public String apply(StorageMetadata from) { + return from.getName(); + } + })); + } + } + + @Singleton + private static class BlobToDatabagItem implements Function<Blob, DatabagItem> { + @Override + public DatabagItem apply(Blob from) { + try { + return from == null ? null : new DatabagItem(from.getMetadata().getName(), Strings2.toStringAndClose(from + .getPayload().getInput())); + } catch (IOException e) { + propagate(e); + return null; + } + } + } + + private final LocalBlobStore databags; + private final BlobToDatabagItem blobToDatabagItem; + private final StorageMetadataToName storageMetadataToName; + private final Closer closer; + + @Inject + TransientChefApi(@Named("databags") LocalBlobStore databags, StorageMetadataToName storageMetadataToName, + BlobToDatabagItem blobToDatabagItem, Closer closer) { + this.databags = checkNotNull(databags, "databags"); + this.storageMetadataToName = checkNotNull(storageMetadataToName, "storageMetadataToName"); + this.blobToDatabagItem = checkNotNull(blobToDatabagItem, "blobToDatabagItem"); + this.closer = checkNotNull(closer, "closer"); + } + + @Override + public Sandbox commitSandbox(String id, boolean isCompleted) { + throw new UnsupportedOperationException(); + } + + @Override + public Client createClient(String clientName) { + throw new UnsupportedOperationException(); + } + + @Override + public Client createClient(String clientName, CreateClientOptions options) { + throw new UnsupportedOperationException(); + } + + @Override + public void createDatabag(String databagName) { + databags.createContainerInLocation(null, databagName); + } + + @Override + public DatabagItem createDatabagItem(String databagName, DatabagItem databagItem) { + Blob blob = databags.blobBuilder(databagItem.getId()).payload(databagItem.toString()).build(); + databags.putBlob(databagName, blob); + return databagItem; + } + + @Override + public void createNode(Node node) { + throw new UnsupportedOperationException(); + } + + @Override + public void createRole(Role role) { + throw new UnsupportedOperationException(); + } + + @Override + public Client deleteClient(String clientName) { + throw new UnsupportedOperationException(); + } + + @Override + public CookbookVersion deleteCookbook(String cookbookName, String version) { + throw new UnsupportedOperationException(); + } + + @Override + public void deleteDatabag(String databagName) { + databags.deleteContainer(databagName); + } + + @Override + public DatabagItem deleteDatabagItem(String databagName, String databagItemId) { + DatabagItem item = blobToDatabagItem.apply(databags.getBlob(databagName, databagItemId)); + databags.removeBlob(databagName, databagItemId); + return item; + } + + @Override + public Node deleteNode(String nodeName) { + throw new UnsupportedOperationException(); + } + + @Override + public Role deleteRole(String rolename) { + throw new UnsupportedOperationException(); + } + + @Override + public Client generateKeyForClient(String clientName) { + throw new UnsupportedOperationException(); + } + + @Override + public Client getClient(String clientName) { + throw new UnsupportedOperationException(); + } + + @Override + public CookbookVersion getCookbook(String cookbookName, String version) { + throw new UnsupportedOperationException(); + } + + @Override + public DatabagItem getDatabagItem(String databagName, String databagItemId) { + return blobToDatabagItem.apply(databags.getBlob(databagName, databagItemId)); + } + + @Override + public Node getNode(String nodeName) { + throw new UnsupportedOperationException(); + } + + @Override + public Role getRole(String roleName) { + throw new UnsupportedOperationException(); + } + + @Override + public UploadSandbox createUploadSandboxForChecksums(Set<List<Byte>> md5s) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> listVersionsOfCookbook(String cookbookName) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> listClients() { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> listCookbooks() { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> listDatabagItems(String databagName) { + return storageMetadataToName.apply(databags.list(databagName)); + } + + @Override + public Set<String> listDatabags() { + return storageMetadataToName.apply(databags.list()); + } + + @Override + public Set<String> listNodes() { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> listRoles() { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> listSearchIndexes() { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends Client> searchClients() { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends Client> searchClients(SearchOptions options) { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends DatabagItem> searchDatabagItems(String databagName) { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends DatabagItem> searchDatabagItems(String databagName, SearchOptions options) { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends Node> searchNodes() { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends Node> searchNodes(SearchOptions options) { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends Role> searchRoles() { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends Role> searchRoles(SearchOptions options) { + throw new UnsupportedOperationException(); + } + + @Override + public CookbookVersion updateCookbook(String cookbookName, String version, CookbookVersion cookbook) { + throw new UnsupportedOperationException(); + } + + @Override + public DatabagItem updateDatabagItem(String databagName, DatabagItem item) { + return createDatabagItem(databagName, item); + } + + @Override + public Node updateNode(Node node) { + throw new UnsupportedOperationException(); + } + + @Override + public Role updateRole(Role role) { + throw new UnsupportedOperationException(); + } + + @Override + public void uploadContent(URI location, Payload content) { + throw new UnsupportedOperationException(); + } + + @Override + public InputStream getResourceContents(Resource resource) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> listEnvironments() { + throw new UnsupportedOperationException(); + } + + @Override + public void createEnvironment(Environment environment) { + throw new UnsupportedOperationException(); + } + + @Override + public Environment deleteEnvironment(String environmentName) { + throw new UnsupportedOperationException(); + } + + @Override + public Environment getEnvironment(String environmentName) { + throw new UnsupportedOperationException(); + } + + @Override + public Environment updateEnvironment(Environment environment) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<CookbookDefinition> listCookbooksInEnvironment(String environmentName) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<CookbookDefinition> listCookbooksInEnvironment(String environmentName, String numVersions) { + throw new UnsupportedOperationException(); + } + + @Override + public CookbookDefinition getCookbookInEnvironment(String environmentName, String cookbookName) { + throw new UnsupportedOperationException(); + } + + @Override + public CookbookDefinition getCookbookInEnvironment(String environmentName, String cookbookName, String numVersions) { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends Environment> searchEnvironments() { + throw new UnsupportedOperationException(); + } + + @Override + public SearchResult<? extends Environment> searchEnvironments(SearchOptions options) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> listRecipesInEnvironment(String environmentName) { + throw new UnsupportedOperationException(); + } + + @Override + public Set<String> listNodesInEnvironment(String environmentName) { + throw new UnsupportedOperationException(); + } + + @Override + public void close() throws IOException { + closer.close(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApiMetadata.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApiMetadata.java b/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApiMetadata.java new file mode 100644 index 0000000..c485080 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/test/TransientChefApiMetadata.java @@ -0,0 +1,75 @@ +/* + * 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.test; + +import java.net.URI; + +import org.jclouds.chef.ChefApiMetadata; +import org.jclouds.chef.config.ChefBootstrapModule; +import org.jclouds.chef.config.ChefParserModule; +import org.jclouds.chef.test.config.TransientChefApiModule; +import org.jclouds.ohai.config.JMXOhaiModule; +import org.jclouds.rest.internal.BaseHttpApiMetadata; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; + +/** + * Implementation of {@link ApiMetadata} for the Amazon-specific Chef API + */ +public class TransientChefApiMetadata extends BaseHttpApiMetadata<TransientChefApi> { + + @Override + public Builder toBuilder() { + return new Builder().fromApiMetadata(this); + } + + public TransientChefApiMetadata() { + this(new Builder()); + } + + protected TransientChefApiMetadata(Builder builder) { + super(builder); + } + + public static class Builder extends BaseHttpApiMetadata.Builder<TransientChefApi, Builder> { + protected Builder() { + id("transientchef") + .name("In-memory Chef API") + .identityName("unused") + .defaultIdentity("api") + .documentation(URI.create("http://localhost")) + .defaultCredential( + "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAyb2ZJJqGm0KKR+8nfQJNsSd+F9tXNMV7CfOcW6jsqs8EZgiV\nR09hD1IYOj4YqM0qJONlgyg4xRWewdSG7QTPj1lJpVAida9sXy2+kzyagZA1Am0O\nZcbqb5hoeIDgcX+eDa79s0u0DomjcfO9EKhvHLBz+zM+3QqPRkPV8nYTbfs+HjVz\nzOU6D1B0XR3+IPZZl2AnWs2d0qhnStHcDUvnRVQ0P482YwN9VgceOZtpPz0DCKEJ\n5Tx5STub8k0/zt/VAMHQafLSuQMLd2s4ZLuOZptN//uAsTmxireqd37z+8ZTdBbJ\n8LEpJ+iCXuSfm5aUh7iw6oxvToY2AL53+jK2UQIDAQABAoIBAQDA88B3i/xWn0vX\nBVxFamCYoecuNjGwXXkSyZew616A+EOCu47bh4aTurdFbYL0YFaAtaWvzlaN2eHg\nDb+HDuTefE29+WkcGk6SshPmiz5T0XOCAICWw6wSVDkHmGwS4jZvbAFm7W8nwGk9\nYhxgxFiRngswJZFopOLoF5WXs2td8guIYNslMpo7tu50iFnBHwKO2ZsPAk8t9nnS\nxlDavKruymEmqHCr3+dtio5eaenJcp3fjoXBQOKUk3ipII29XRB8NqeCVV/7Kxwq\nckqOBEbRwBclckyIbD+RiAgKvOelORjEiE9R42vuqvxRA6k9kd9o7utlX0AUtpEn\n3gZc6LepAoGBAP9ael5Y75+sK2JJUNOOhO8ae45cdsilp2yI0X+UBaSuQs2+dyPp\nkpEHAxd4pmmSvn/8c9TlEZhr+qYbABXVPlDncxpIuw2Ajbk7s/S4XaSKsRqpXL57\nzj/QOqLkRk8+OVV9q6lMeQNqLtEj1u6JPviX70Ro+FQtRttNOYbfdP/fAoGBAMpA\nXjR5woV5sUb+REg9vE uYo8RSyOarxqKFCIXVUNsLOx+22+AK4+CQpbueWN7jotrl\nYD6uT6svWi3AAC7kiY0UI/fjVPRCUi8tVoQUE0TaU5VLITaYOB+W/bBaDE4M9560\n1NuDWO90baA5dfU44iuzva02rGJXK9+nS3o8nk/PAoGBALOL6djnDe4mwAaG6Jco\ncd4xr8jkyPzCRZuyBCSBbwphIUXLc7hDprPky064ncJD1UDmwIdkXd/fpMkg2QmA\n/CUk6LEFjMisqHojOaCL9gQZJPhLN5QUN2x1PJWGjs1vQh8Tkx0iUUCOa8bQPXNR\n+34OTsW6TUna4CSZAycLfhffAoGBAIggVsefBCvuQkF0NeUhmDCRZfhnd8y55RHR\n1HCvqKIlpv+rhcX/zmyBLuteopYyRJRsOiE2FW00i8+rIPRu4Z3Q5nybx7w3PzV9\noHN5R5baE9OyI4KpZWztpYYitZF67NcnAvVULHHOvVJQGnKYfLHJYmrJF7GA1ojM\nAuMdFbjFAoGAPxUhxwFy8gaqBahKUEZn4F81HFP5ihGhkT4QL6AFPO2e+JhIGjuR\n27+85hcFqQ+HHVtFsm81b/a+R7P4UuCRgc8eCjxQMoJ1Xl4n7VbjPbHMnIN0Ryvd\nO4ZpWDWYnCO021JTOUUOJ4J/y0416Bvkw0z59y7sNX7wDBBHHbK/XCc=\n-----END RSA PRIVATE KEY-----\n") + .defaultEndpoint("transientchef") + .defaultProperties(ChefApiMetadata.defaultProperties()) + .defaultModules( + ImmutableSet.<Class<? extends Module>> of(TransientChefApiModule.class, ChefParserModule.class, + ChefBootstrapModule.class, JMXOhaiModule.class)); + } + + @Override + public TransientChefApiMetadata build() { + return new TransientChefApiMetadata(this); + } + + @Override + protected Builder self() { + return this; + } + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/test/config/TransientChefApiModule.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/test/config/TransientChefApiModule.java b/apis/chef/src/main/java/org/jclouds/chef/test/config/TransientChefApiModule.java new file mode 100644 index 0000000..d9eab4d --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/test/config/TransientChefApiModule.java @@ -0,0 +1,116 @@ +/* + * 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.test.config; + +import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor; + +import java.io.IOException; +import java.security.PrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.util.List; + +import javax.inject.Singleton; + +import org.jclouds.ContextBuilder; +import org.jclouds.blobstore.TransientApiMetadata; +import org.jclouds.blobstore.config.LocalBlobStore; +import org.jclouds.chef.ChefApi; +import org.jclouds.chef.config.Validator; +import org.jclouds.chef.domain.Client; +import org.jclouds.chef.functions.BootstrapConfigForGroup; +import org.jclouds.chef.functions.ClientForGroup; +import org.jclouds.chef.functions.RunListForGroup; +import org.jclouds.chef.test.TransientChefApi; +import org.jclouds.concurrent.config.ExecutorServiceModule; +import org.jclouds.crypto.Crypto; +import org.jclouds.domain.JsonBall; +import org.jclouds.rest.ConfiguresHttpApi; +import org.jclouds.rest.config.RestModule; +import org.jclouds.rest.config.SyncToAsyncHttpInvocationModule; + +import com.google.common.base.Optional; +import com.google.common.base.Supplier; +import com.google.common.cache.CacheLoader; +import com.google.common.collect.ImmutableSet; +import com.google.inject.AbstractModule; +import com.google.inject.Injector; +import com.google.inject.Module; +import com.google.inject.Provides; +import com.google.inject.name.Names; + +@ConfiguresHttpApi +public class TransientChefApiModule extends AbstractModule { + + @Override + protected void configure() { + install(new RestModule()); + install(new SyncToAsyncHttpInvocationModule()); + bind(ChefApi.class).to(TransientChefApi.class); + bind(LocalBlobStore.class).annotatedWith(Names.named("databags")) + .toInstance( + ContextBuilder + .newBuilder(new TransientApiMetadata()) + .modules( + ImmutableSet.<Module> of(new ExecutorServiceModule(sameThreadExecutor(), + sameThreadExecutor()))).buildInjector().getInstance(LocalBlobStore.class)); + } + + @Provides + @Singleton + public Supplier<PrivateKey> supplyKey() { + return new Supplier<PrivateKey>() { + @Override + public PrivateKey get() { + return null; + } + }; + } + + @Provides + @Singleton + CacheLoader<String, List<String>> runListForGroup(RunListForGroup runListForGroup) { + return CacheLoader.from(runListForGroup); + } + + @Provides + @Singleton + CacheLoader<String, ? extends JsonBall> bootstrapConfigForGroup(BootstrapConfigForGroup bootstrapConfigForGroup) { + return CacheLoader.from(bootstrapConfigForGroup); + } + + @Provides + @Singleton + CacheLoader<String, Client> groupToClient(ClientForGroup clientForGroup) { + return CacheLoader.from(clientForGroup); + } + + @Provides + @Singleton + @Validator + public Optional<String> provideValidatorName(Injector injector) { + return Optional.absent(); + } + + @Provides + @Singleton + @Validator + public Optional<PrivateKey> provideValidatorCredential(Crypto crypto, Injector injector) + throws InvalidKeySpecException, IOException { + return Optional.absent(); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/util/ChefUtils.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/util/ChefUtils.java b/apis/chef/src/main/java/org/jclouds/chef/util/ChefUtils.java new file mode 100644 index 0000000..3ba0c59 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/util/ChefUtils.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.util; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Date; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.jclouds.domain.JsonBall; +import org.jclouds.ohai.Automatic; + +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.collect.Iterables; +import com.google.inject.Binder; +import com.google.inject.TypeLiteral; +import com.google.inject.multibindings.MapBinder; + +public class ChefUtils { + + public static Date fromOhaiTime(JsonBall ohaiDate) { + return new Date(Long.parseLong(checkNotNull(ohaiDate, "ohaiDate").toString().replaceAll("\\.[0-9]*$", ""))); + } + + public static JsonBall toOhaiTime(long millis) { + return new JsonBall(millis + ""); + } + + public static MapBinder<String, Supplier<JsonBall>> ohaiAutomaticAttributeBinder(Binder binder) { + MapBinder<String, Supplier<JsonBall>> mapbinder = MapBinder.newMapBinder(binder, new TypeLiteral<String>() { + }, new TypeLiteral<Supplier<JsonBall>>() { + }, Automatic.class); + return mapbinder; + } + + /** + * + * @return NoSuchElementException if no element in the runList is a role. + */ + public static String findRoleInRunList(List<String> runList) { + final Pattern pattern = Pattern.compile("^role\\[(.*)\\]$"); + String roleToParse = Iterables.find(runList, new Predicate<String>() { + + @Override + public boolean apply(String input) { + return pattern.matcher(input).matches(); + } + + }); + Matcher matcher = pattern.matcher(roleToParse); + matcher.find(); + return matcher.group(1); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/util/CollectionUtils.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/util/CollectionUtils.java b/apis/chef/src/main/java/org/jclouds/chef/util/CollectionUtils.java new file mode 100644 index 0000000..cabfbde --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/util/CollectionUtils.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.util; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.jclouds.javax.annotation.Nullable; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +/** + * Utility methods to work with collections. + */ +public class CollectionUtils { + + /** + * Creates an immutable list with the elements of the given list. If the + * input list is <code>null</code>, it returns an empty list. + * + * @param input + * The list used to build the immutable one. + * @return An immutable list with the elements of the given list. + */ + public static <T> ImmutableList<T> copyOfOrEmpty(@Nullable List<T> input) { + return input == null ? ImmutableList.<T> of() : ImmutableList.copyOf(input); + } + + /** + * Creates an immutable set with the elements of the given set. If the input + * set is <code>null</code>, it returns an empty set. + * + * @param input + * The set used to build the immutable one. + * @return An immutable set with the elements of the given set. + */ + public static <T> ImmutableSet<T> copyOfOrEmpty(@Nullable Set<T> input) { + return input == null ? ImmutableSet.<T> of() : ImmutableSet.copyOf(input); + } + + /** + * Creates an immutable map with the elements of the given map. If the input + * map is <code>null</code>, it returns an empty map. + * + * @param input + * The map used to build the immutable one. + * @return An immutable map with the elements of the given map. + */ + public static <K, V> ImmutableMap<K, V> copyOfOrEmpty(@Nullable Map<K, V> input) { + return input == null ? ImmutableMap.<K, V> of() : ImmutableMap.copyOf(input); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/chef/util/RunListBuilder.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/chef/util/RunListBuilder.java b/apis/chef/src/main/java/org/jclouds/chef/util/RunListBuilder.java new file mode 100644 index 0000000..27cc377 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/chef/util/RunListBuilder.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.chef.util; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.addAll; +import static com.google.common.collect.Lists.newArrayList; +import static com.google.common.collect.Lists.transform; + +import java.util.Arrays; +import java.util.List; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; + +/** + * builds a run list in the correct syntax for chef. + */ +public class RunListBuilder { + private List<String> list = newArrayList(); + + /** + * Add the following recipe to the run list + */ + public RunListBuilder addRecipe(String recipe) { + return addRecipes(checkNotNull(recipe, "recipe")); + } + + /** + * Add the following recipes to the run list + */ + public RunListBuilder addRecipes(String... recipes) { + addAll(list, transform(Arrays.asList(checkNotNull(recipes, "recipes")), new Function<String, String>() { + + @Override + public String apply(String from) { + return "recipe[" + from + "]"; + } + + })); + return this; + } + + /** + * Add the following role to the run list + */ + public RunListBuilder addRole(String role) { + return addRoles(checkNotNull(role, "role")); + } + + /** + * Add the following roles to the run list + */ + public RunListBuilder addRoles(String... roles) { + addAll(list, transform(Arrays.asList(checkNotNull(roles, "roles")), new Function<String, String>() { + + @Override + public String apply(String from) { + return "role[" + from + "]"; + } + + })); + return this; + } + + public List<String> build() { + return ImmutableList.copyOf(list); + } +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/ohai/Automatic.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/ohai/Automatic.java b/apis/chef/src/main/java/org/jclouds/ohai/Automatic.java new file mode 100644 index 0000000..9b3d134 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/ohai/Automatic.java @@ -0,0 +1,33 @@ +/* + * 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; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + +@Retention(RUNTIME) +@Target({ TYPE, METHOD, PARAMETER }) +@Qualifier +public @interface Automatic { +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/ohai/AutomaticSupplier.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/ohai/AutomaticSupplier.java b/apis/chef/src/main/java/org/jclouds/ohai/AutomaticSupplier.java new file mode 100644 index 0000000..681558e --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/ohai/AutomaticSupplier.java @@ -0,0 +1,48 @@ +/* + * 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; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.domain.JsonBall; +import org.jclouds.ohai.functions.NestSlashKeys; + +import com.google.common.base.Supplier; +import com.google.common.collect.Multimap; + +@Singleton +public class AutomaticSupplier implements Supplier<Map<String, JsonBall>> { + private final Multimap<String, Supplier<JsonBall>> autoAttrs; + private final NestSlashKeys nester; + + @Inject + AutomaticSupplier(@Automatic Multimap<String, Supplier<JsonBall>> autoAttrs, NestSlashKeys nester) { + this.autoAttrs = checkNotNull(autoAttrs, "autoAttrs"); + this.nester = checkNotNull(nester, "nester"); + } + + @Override + public Map<String, JsonBall> get() { + return nester.apply(autoAttrs); + } + +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/ohai/config/ConfiguresOhai.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/ohai/config/ConfiguresOhai.java b/apis/chef/src/main/java/org/jclouds/ohai/config/ConfiguresOhai.java new file mode 100644 index 0000000..1ca0df4 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/ohai/config/ConfiguresOhai.java @@ -0,0 +1,28 @@ +/* + * 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.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; + +@Retention(RUNTIME) +@Target(TYPE) +public @interface ConfiguresOhai { +} http://git-wip-us.apache.org/repos/asf/jclouds/blob/867c7a40/apis/chef/src/main/java/org/jclouds/ohai/config/JMXOhaiModule.java ---------------------------------------------------------------------- diff --git a/apis/chef/src/main/java/org/jclouds/ohai/config/JMXOhaiModule.java b/apis/chef/src/main/java/org/jclouds/ohai/config/JMXOhaiModule.java new file mode 100644 index 0000000..a8d01f7 --- /dev/null +++ b/apis/chef/src/main/java/org/jclouds/ohai/config/JMXOhaiModule.java @@ -0,0 +1,48 @@ +/* + * 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.config; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; + +import javax.inject.Singleton; + +import org.jclouds.domain.JsonBall; +import org.jclouds.ohai.suppliers.UptimeSecondsSupplier; + +import com.google.common.base.Supplier; +import com.google.inject.Provides; +import com.google.inject.multibindings.MapBinder; + +/** + * Wires the components needed to parse ohai data from a JVM + */ +@ConfiguresOhai +public class JMXOhaiModule extends OhaiModule { + + @Provides + @Singleton + protected RuntimeMXBean provideRuntimeMXBean() { + return ManagementFactory.getRuntimeMXBean(); + } + + public MapBinder<String, Supplier<JsonBall>> bindOhai() { + MapBinder<String, Supplier<JsonBall>> mapBinder = super.bindOhai(); + mapBinder.addBinding("uptime_seconds").to(UptimeSecondsSupplier.class); + return mapBinder; + } +}
