Issue 385: started work on example compute provider that is backed by library, not http

This commit is contained in:
Adrian Cole 2010-10-19 17:08:11 -05:00
parent a96d332ea4
commit 464bca0ec1
27 changed files with 1547 additions and 24 deletions

View File

@ -26,6 +26,7 @@ import static org.jclouds.Constants.PROPERTY_IDENTITY;
import java.util.List;
import java.util.Properties;
import org.jclouds.PropertiesBuilder;
import org.jclouds.compute.config.StandaloneComputeServiceClientModule;
import com.google.inject.Module;
@ -39,6 +40,10 @@ public class StandaloneComputeServiceContextBuilder extends
public StandaloneComputeServiceContextBuilder(Properties props) {
super(ComputeService.class, ComputeService.class, props);
if (properties.size() == 0)
properties.putAll(new PropertiesBuilder().build());
if (!properties.containsKey("jclouds.provider"))
properties.setProperty("jclouds.provider", "standalone");
if (!properties.containsKey(PROPERTY_ENDPOINT))
properties.setProperty(PROPERTY_ENDPOINT, "standalone");
if (!properties.containsKey(PROPERTY_API_VERSION))

View File

@ -204,12 +204,19 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
}
/**
* The default template if none is provided.
*/
@Provides
@Named("DEFAULT")
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
return template.osFamily(UBUNTU);
}
/**
* supplies how the tag is encoded into the name. A string of hex characters is the last argument
* and tag is the first
*/
@Provides
@Named("NAMING_CONVENTION")
@Singleton

View File

@ -29,6 +29,19 @@ import org.jclouds.compute.domain.Template;
*/
public interface AddNodeWithTagStrategy {
/**
* create a node given the name and template parameters such as imageid, hardwareid, and
* locationid.
*
* @param tag
* tag supplied by the user
* @param name
* supplied by {@link RunNodesAndAddToSetStrategy } and must have the tag encoded into
* it.
* @param template
* supplied by the user
* @return NodeMetadata from the new object, most likely in some pending state.
*/
NodeMetadata execute(String tag, String name, Template template);
}

View File

@ -362,7 +362,7 @@ public class StubComputeServiceDependenciesModule extends AbstractModule {
public static class StubHardwareSupplier implements Supplier<Set<? extends Hardware>> {
static Hardware stub(String type, int cores, int ram, float disk) {
return new org.jclouds.compute.domain.HardwareBuilder().id(type).providerId(type).name(type).processors(
return new org.jclouds.compute.domain.HardwareBuilder().ids(type).name(type).processors(
ImmutableList.of(new Processor(cores, 1.0))).ram(ram).volumes(
ImmutableList.<Volume> of(new VolumeImpl(disk, true, false))).build();
}

View File

@ -0,0 +1,70 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.collect;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.NoSuchElementException;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.Iterables;
/**
* @author Adrian Cole
*/
@Singleton
public abstract class FindResourceInSet<F, T> implements Function<F, T> {
@Resource
protected Logger logger = Logger.NULL;
private final Supplier<Set<? extends T>> set;
@Inject
public FindResourceInSet(@Memoized Supplier<Set<? extends T>> set) {
this.set = checkNotNull(set, "set");
}
public abstract boolean matches(F from, T input);
public T apply(final F from) {
try {
return Iterables.find(set.get(), new Predicate<T>() {
@Override
public boolean apply(T input) {
return matches(from, input);
}
});
} catch (NoSuchElementException e) {
logger.warn("could not find a match in set for %s", from);
}
return null;
}
}

View File

@ -0,0 +1,48 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.collect;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Sets.newHashSet;
import java.util.Set;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
/**
*
* @author Adrian Cole
*/
public abstract class TransformingSetSupplier<F, T> implements Supplier<Set<? extends T>> {
private final Function<F, T> converter;
public TransformingSetSupplier(Function<F, T> converter) {
this.converter = converter;
}
@Override
public Set<? extends T> get() {
return newHashSet(transform(supplyFrom(), converter));
}
public abstract Iterable<F> supplyFrom();
}

View File

@ -37,6 +37,7 @@
<module>core</module>
<module>compute</module>
<module>blobstore</module>
<module>skeletons</module>
<module>filesystem</module>
<module>extensions</module>
<module>tools</module>

37
skeletons/pom.xml Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>jclouds-project</artifactId>
<groupId>org.jclouds</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../project/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jclouds-skeletons-project</artifactId>
<packaging>pom</packaging>
<name>jclouds skeletons project</name>
<modules>
<module>standalone-compute</module>
</modules>
</project>

View File

@ -0,0 +1,3 @@
this is a skeleton for a standalone compute provider.
Essentially, a standalone provider is one that doesn't use jclouds http services. Examples could be native drivers like libvirt or shell-driven ones like virtualbox.

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2010 Cloud Conscious, LLC.
<info@cloudconscious.com>
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless required by
applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-project</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<artifactId>jclouds-examples-standalone-compute</artifactId>
<name>jclouds example components for a standalone compute provider</name>
<properties>
<!-- when instances are hung, open a ticket and add here -->
<jclouds.compute.blacklist.nodes>trmkrun-ccc,test.trmk-924</jclouds.compute.blacklist.nodes>
<test.servermanager-compute.endpoint>https://servermanager-compute.com</test.servermanager-compute.endpoint>
<test.servermanager-compute.apiversion>1.0</test.servermanager-compute.apiversion>
<test.servermanager-compute.identity>FIXME</test.servermanager-compute.identity>
</properties>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jclouds-jsch</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>live</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<executions>
<execution>
<id>integration</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<systemProperties>
<property>
<name>test.servermanager-compute.endpoint</name>
<value>${test.servermanager-compute.endpoint}</value>
</property>
<property>
<name>test.servermanager-compute.apiversion</name>
<value>${test.servermanager-compute.apiversion}</value>
</property>
<property>
<name>test.servermanager-compute.identity</name>
<value>${test.servermanager-compute.identity}</value>
</property>
<property>
<name>jclouds.compute.blacklist.nodes</name>
<value>${jclouds.compute.blacklist.nodes}</value>
</property>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,63 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager;
import com.google.common.base.Objects;
/**
* This would be replaced with the real java object related to the underlying hardware
*
* @author Adrian Cole
*/
public class Hardware {
public int id;
public String name;
public int cores;
public int ram;
public float disk;
public Hardware(int id, String name, int cores, int ram, float disk) {
this.id = id;
this.name = name;
this.cores = cores;
this.ram = ram;
this.disk = disk;
}
@Override
public int hashCode() {
return Objects.hashCode(id, name, cores, ram, disk);
}
@Override
public boolean equals(Object that) {
if (that == null)
return false;
return Objects.equal(this.toString(), that.toString());
}
@Override
public String toString() {
return Objects.toStringHelper(this).add("id", id).add("name", name).add("cores", cores).add("ram", ram)
.add("disk", disk).toString();
}
}

View File

@ -0,0 +1,56 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager;
import com.google.common.base.Objects;
/**
* This would be replaced with the real java object related to the underlying image
*
* @author Adrian Cole
*/
public class Image {
public int id;
public String name;
public Image(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
return Objects.hashCode(id, name);
}
@Override
public boolean equals(Object that) {
if (that == null)
return false;
return Objects.equal(this.toString(), that.toString());
}
@Override
public String toString() {
return Objects.toStringHelper(this).add("id", id).add("name", name).toString();
}
}

View File

@ -0,0 +1,67 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager;
import com.google.common.base.Objects;
/**
* This would be replaced with the real java object related to the underlying server
*
* @author Adrian Cole
*/
public class Server {
public enum Status {
ACTIVE, BUILD, TERMINATED, UNRECOGNIZED
}
public int id;
public String name;
public Status status;
public String datacenter;
public int imageId;
public int hardwareId;
public String publicAddress;
public String privateAddress;
public String loginUser;
public String password;
@Override
public int hashCode() {
return Objects.hashCode(id, name, status, datacenter, imageId, hardwareId, publicAddress, privateAddress,
loginUser);
}
@Override
public boolean equals(Object that) {
if (that == null)
return false;
return Objects.equal(this.toString(), that.toString());
}
@Override
public String toString() {
return Objects.toStringHelper(this).add("id", id).add("name", name).add("status", status)
.add("datacenter", datacenter).add("imageId", imageId).add("hardwareId", hardwareId)
.add("publicAddress", publicAddress).add("privateAddress", privateAddress).add("loginUser", loginUser)
.toString();
}
}

View File

@ -0,0 +1,99 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.Singleton;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
/**
* This would be replaced with the real connection to the service that can
* create/list/reboot/get/destroy things
*
* @author Adrian Cole
*/
@Singleton
public class ServerManager {
private final static Map<Integer, Server> servers = Maps.newHashMap();
private final static Map<Integer, Image> images = ImmutableMap.of(1, new Image(1, "ubuntu"));
private final static Map<Integer, Hardware> hardware = ImmutableMap.of(1, new Hardware(1, "small", 1, 512, 10));
private final static AtomicInteger nodeIds = new AtomicInteger(0);
/**
* simulate creating a server, as this is really going to happen with the api underneath
*
* @param name
* @param name
* @param imageId
* @param hardwareId
* @return new server
*/
public Server createServerInDC(String datacenter, String name, int imageId, int hardwareId) {
Server server = new Server();
server.id = nodeIds.getAndIncrement();
server.name = name;
server.datacenter = datacenter;
server.imageId = imageId;
server.hardwareId = hardwareId;
server.publicAddress = "7.1.1." + server.id;
server.privateAddress = "10.1.1." + server.id;
server.loginUser = "root";
server.password = "password";
servers.put(server.id, server);
return server;
}
public Server getServer(int serverId) {
return servers.get(serverId);
}
public Iterable<Server> listServers() {
return servers.values();
}
public Image getImage(int imageId) {
return images.get(imageId);
}
public Iterable<Image> listImages() {
return images.values();
}
public Hardware getHardware(int hardwareId) {
return hardware.get(hardwareId);
}
public Iterable<org.jclouds.servermanager.Hardware> listHardware() {
return hardware.values();
}
public void destroyServer(int serverId) {
servers.remove(serverId);
}
public void rebootServer(int serverId) {
}
}

View File

@ -0,0 +1,64 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute;
import java.util.List;
import java.util.Properties;
import org.jclouds.compute.StandaloneComputeServiceContextBuilder;
import org.jclouds.compute.config.StandaloneComputeServiceContextModule;
import org.jclouds.servermanager.compute.strategy.ServerManagerAddNodeWithTagStrategy;
import org.jclouds.servermanager.compute.strategy.ServerManagerDestroyNodeStrategy;
import org.jclouds.servermanager.compute.strategy.ServerManagerGetAndListNodesStrategy;
import org.jclouds.servermanager.compute.strategy.ServerManagerRebootNodeStrategy;
import org.jclouds.servermanager.compute.suppliers.ServerManagerHardwareSupplier;
import org.jclouds.servermanager.compute.suppliers.ServerManagerImageSupplier;
import org.jclouds.servermanager.compute.suppliers.ServerManagerLocationSupplier;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class ServerManagerComputeServiceContextBuilder extends StandaloneComputeServiceContextBuilder {
public ServerManagerComputeServiceContextBuilder(Properties props) {
super(props);
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(createContextModule());
}
public static StandaloneComputeServiceContextModule createContextModule() {
return StandaloneComputeServiceContextModule.builder()
.defineAddNodeWithTagStrategy(ServerManagerAddNodeWithTagStrategy.class)
.defineDestroyNodeStrategy(ServerManagerDestroyNodeStrategy.class)
.defineGetNodeMetadataStrategy(ServerManagerGetAndListNodesStrategy.class)
.defineListNodesStrategy(ServerManagerGetAndListNodesStrategy.class)
.defineRebootNodeStrategy(ServerManagerRebootNodeStrategy.class)
.defineHardwareSupplier(ServerManagerHardwareSupplier.class)
.defineLocationSupplier(ServerManagerLocationSupplier.class)
.defineImageSupplier(ServerManagerImageSupplier.class).build();
}
}

View File

@ -0,0 +1,50 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.functions;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.HardwareBuilder;
import org.jclouds.compute.domain.Processor;
import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.VolumeImpl;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
/**
* @author Adrian Cole
*/
@Singleton
public class ServerManagerHardwareToHardware implements Function<org.jclouds.servermanager.Hardware, Hardware> {
@Override
public Hardware apply(org.jclouds.servermanager.Hardware from) {
HardwareBuilder builder = new HardwareBuilder();
builder.ids(from.id + "");
builder.name(from.name);
builder.processors(ImmutableList.of(new Processor(from.cores, 1.0)));
builder.ram(from.ram);
builder.volumes(ImmutableList.<Volume> of(new VolumeImpl(from.disk, true, false)));
return builder.build();
}
}

View File

@ -0,0 +1,62 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.functions;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.ImageBuilder;
import org.jclouds.compute.domain.OperatingSystemBuilder;
import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import com.google.common.base.Function;
/**
* @author Adrian Cole
*/
@Singleton
public class ServerManagerImageToImage implements Function<org.jclouds.servermanager.Image, Image> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
@Override
public Image apply(org.jclouds.servermanager.Image from) {
ImageBuilder builder = new ImageBuilder();
builder.ids(from.id + "");
builder.name(from.name);
builder.description(from.name);
OsFamily family = null;
try {
family = OsFamily.fromValue(from.name);
builder.operatingSystem(new OperatingSystemBuilder().name(from.name).family(family).build());
} catch (IllegalArgumentException e) {
logger.debug("<< didn't match os(%s)", from);
}
return builder.build();
}
}

View File

@ -0,0 +1,135 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.collect.FindResourceInSet;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.servermanager.Server;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
*/
@Singleton
public class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
public static final Map<Server.Status, NodeState> serverStatusToNodeState = ImmutableMap
.<Server.Status, NodeState> builder().put(Server.Status.ACTIVE, NodeState.RUNNING)//
.put(Server.Status.BUILD, NodeState.PENDING)//
.put(Server.Status.TERMINATED, NodeState.TERMINATED)//
.put(Server.Status.UNRECOGNIZED, NodeState.UNRECOGNIZED)//
.build();
private final FindHardwareForServer findHardwareForServer;
private final FindLocationForServer findLocationForServer;
private final FindImageForServer findImageForServer;
private final Map<String, Credentials> credentialStore;
@Inject
ServerToNodeMetadata(Map<String, Credentials> credentialStore, FindHardwareForServer findHardwareForServer,
FindLocationForServer findLocationForServer, FindImageForServer findImageForServer) {
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.findHardwareForServer = checkNotNull(findHardwareForServer, "findHardwareForServer");
this.findLocationForServer = checkNotNull(findLocationForServer, "findLocationForServer");
this.findImageForServer = checkNotNull(findImageForServer, "findImageForServer");
}
@Override
public NodeMetadata apply(Server from) {
// convert the result object to a jclouds NodeMetadata
NodeMetadataBuilder builder = new NodeMetadataBuilder();
builder.ids(from.id + "");
builder.name(from.name);
builder.location(findLocationForServer.apply(from));
builder.tag(parseTagFromName(from.name));
builder.imageId(from.imageId + "");
Image image = findImageForServer.apply(from);
if (image != null)
builder.operatingSystem(image.getOperatingSystem());
builder.hardware(findHardwareForServer.apply(from));
builder.state(serverStatusToNodeState.get(from.status));
builder.publicAddresses(ImmutableSet.<String> of(from.publicAddress));
builder.privateAddresses(ImmutableSet.<String> of(from.privateAddress));
builder.credentials(credentialStore.get(from.id + ""));
return builder.build();
}
@Singleton
public static class FindHardwareForServer extends FindResourceInSet<Server, Hardware> {
@Inject
public FindHardwareForServer(@Memoized Supplier<Set<? extends Hardware>> hardware) {
super(hardware);
}
@Override
public boolean matches(Server from, Hardware input) {
return input.getProviderId().equals(from.hardwareId + "");
}
}
@Singleton
public static class FindImageForServer extends FindResourceInSet<Server, Image> {
@Inject
public FindImageForServer(@Memoized Supplier<Set<? extends Image>> hardware) {
super(hardware);
}
@Override
public boolean matches(Server from, Image input) {
return input.getProviderId().equals(from.imageId + "");
}
}
@Singleton
public static class FindLocationForServer extends FindResourceInSet<Server, Location> {
@Inject
public FindLocationForServer(@Memoized Supplier<Set<? extends Location>> hardware) {
super(hardware);
}
@Override
public boolean matches(Server from, Location input) {
return input.getId().equals(from.datacenter + "");
}
}
}

View File

@ -0,0 +1,89 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger;
import org.jclouds.servermanager.Server;
import org.jclouds.servermanager.ServerManager;
import org.jclouds.servermanager.compute.functions.ServerToNodeMetadata;
/**
* This creates a node in the backend client. You create it with the parameters of the
* {@link Template} object. Then, convert it to a {@link NodeMetadata} object.
*
* @author Adrian Cole
*
*/
@Singleton
public class ServerManagerAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final Map<String, Credentials> credentialStore;
private final ServerManager client;
private final ServerToNodeMetadata serverToNodeMetadata;
@Inject
public ServerManagerAddNodeWithTagStrategy(Map<String, Credentials> credentialStore, ServerManager client,
ServerToNodeMetadata serverToNodeMetadata) {
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.client = checkNotNull(client, "client");
this.serverToNodeMetadata = checkNotNull(serverToNodeMetadata, "serverToNodeMetadata");
}
/**
* {@inheritDoc}
*/
@Override
public NodeMetadata execute(String tag, String name, Template template) {
checkState(tag != null, "tag (that which groups identical nodes together) must be specified");
checkState(name != null && name.indexOf(tag) != -1, "name should have %s encoded into it", tag);
logger.debug(">> instantiating new server dc(%s) name(%s) image(%s) hardware(%s)",
template.getLocation().getId(), name, template.getImage().getProviderId(), template.getHardware()
.getProviderId());
// create the backend object using parameters from the template.
Server from = client.createServerInDC(template.getLocation().getId(), name,
Integer.parseInt(template.getImage().getProviderId()),
Integer.parseInt(template.getHardware().getProviderId()));
// store the credentials so that later functions can use them
credentialStore.put(from.id + "", new Credentials(from.loginUser, from.password));
logger.debug("<< instantiated server(%s)", from.id);
return serverToNodeMetadata.apply(from);
}
}

View File

@ -0,0 +1,68 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.DestroyNodeStrategy;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.logging.Logger;
import org.jclouds.servermanager.ServerManager;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ServerManagerDestroyNodeStrategy implements DestroyNodeStrategy {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final ServerManager client;
private final GetNodeMetadataStrategy getNodeMetadataStrategy;
@Inject
protected ServerManagerDestroyNodeStrategy(ServerManager client, GetNodeMetadataStrategy getNodeMetadataStrategy) {
this.client = checkNotNull(client, "client");
this.getNodeMetadataStrategy = checkNotNull(getNodeMetadataStrategy, "getNodeMetadataStrategy");
}
@Override
public NodeMetadata execute(String id) {
NodeMetadata node = getNodeMetadataStrategy.execute(id);
if (node == null)
return node;
logger.debug(">> destroying server(%s)", id);
client.destroyServer(Integer.parseInt(id));
logger.debug("<< destroyed server(%s)", id);
return node;
}
}

View File

@ -0,0 +1,70 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.predicates.NodePredicates;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.servermanager.Server;
import org.jclouds.servermanager.ServerManager;
import org.jclouds.servermanager.compute.functions.ServerToNodeMetadata;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ServerManagerGetAndListNodesStrategy implements ListNodesStrategy, GetNodeMetadataStrategy {
private final ServerManager client;
private final ServerToNodeMetadata serverToNodeMetadata;
@Inject
protected ServerManagerGetAndListNodesStrategy(ServerManager client, ServerToNodeMetadata serverToNodeMetadata) {
this.client = checkNotNull(client, "client");
this.serverToNodeMetadata = checkNotNull(serverToNodeMetadata, "serverToNodeMetadata");
}
@Override
public NodeMetadata execute(String id) {
int serverId = Integer.parseInt(id);
Server server = client.getServer(serverId);
return server == null ? null : serverToNodeMetadata.apply(server);
}
@Override
public Iterable<? extends ComputeMetadata> list() {
return listDetailsOnNodesMatching(NodePredicates.all());
}
@Override
public Iterable<? extends NodeMetadata> listDetailsOnNodesMatching(Predicate<ComputeMetadata> filter) {
return Iterables.filter(Iterables.transform(client.listServers(), serverToNodeMetadata), filter);
}
}

View File

@ -0,0 +1,69 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
import org.jclouds.compute.strategy.RebootNodeStrategy;
import org.jclouds.logging.Logger;
import org.jclouds.servermanager.ServerManager;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ServerManagerRebootNodeStrategy implements RebootNodeStrategy {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final ServerManager client;
private final GetNodeMetadataStrategy getNodeMetadataStrategy;
@Inject
protected ServerManagerRebootNodeStrategy(ServerManager client, GetNodeMetadataStrategy getNodeMetadataStrategy) {
this.client = checkNotNull(client, "client");
this.getNodeMetadataStrategy = checkNotNull(getNodeMetadataStrategy, "getNodeMetadataStrategy");
}
@Override
public NodeMetadata execute(String id) {
NodeMetadata node = getNodeMetadataStrategy.execute(id);
if (node == null || node.getState() == NodeState.TERMINATED)
return node;
logger.debug(">> rebooting server(%s)", id);
client.rebootServer(Integer.parseInt(id));
logger.debug("<< rebooted server(%s)", id);
return node;
}
}

View File

@ -0,0 +1,49 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.suppliers;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.collect.TransformingSetSupplier;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.servermanager.ServerManager;
import org.jclouds.servermanager.compute.functions.ServerManagerHardwareToHardware;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ServerManagerHardwareSupplier extends
TransformingSetSupplier<org.jclouds.servermanager.Hardware, Hardware> {
private final ServerManager client;
@Inject
protected ServerManagerHardwareSupplier(ServerManager client,
ServerManagerHardwareToHardware serverManagerHardwareToHardware) {
super(serverManagerHardwareToHardware);
this.client = client;
}
public Iterable<org.jclouds.servermanager.Hardware> supplyFrom() {
return client.listHardware();
}
}

View File

@ -0,0 +1,47 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.suppliers;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.collect.TransformingSetSupplier;
import org.jclouds.compute.domain.Image;
import org.jclouds.servermanager.ServerManager;
import org.jclouds.servermanager.compute.functions.ServerManagerImageToImage;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ServerManagerImageSupplier extends TransformingSetSupplier<org.jclouds.servermanager.Image, Image> {
private final ServerManager client;
@Inject
protected ServerManagerImageSupplier(ServerManager client, ServerManagerImageToImage serverManagerImageToImage) {
super(serverManagerImageToImage);
this.client = client;
}
public Iterable<org.jclouds.servermanager.Image> supplyFrom() {
return client.listImages();
}
}

View File

@ -0,0 +1,54 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.servermanager.compute.suppliers;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.domain.Location;
import org.jclouds.domain.LocationScope;
import org.jclouds.domain.internal.LocationImpl;
import org.jclouds.rest.annotations.Provider;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ServerManagerLocationSupplier implements Supplier<Set<? extends Location>> {
private final String providerName;
@Inject
ServerManagerLocationSupplier(@Provider String providerName) {
this.providerName = providerName;
}
@Override
public Set<? extends Location> get() {
Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
return ImmutableSet.of(new LocationImpl(LocationScope.ZONE, "1", "SFO", provider));
}
}

View File

@ -0,0 +1,38 @@
package org.jclouds.servermanager.compute;
import static org.testng.Assert.assertNotNull;
import java.util.Properties;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*
*/
@Test(groups = "unit")
public class ServerManagerComputeServiceContextBuilderTest {
@Test
public void testCreateContextModule() {
assertNotNull(ServerManagerComputeServiceContextBuilder.createContextModule());
}
@Test
public void testCanBuildDirectly() {
ComputeServiceContext context = new ServerManagerComputeServiceContextBuilder(new Properties())
.buildComputeServiceContext();
context.close();
}
@Test
public void testCanBuildWithComputeService() {
ComputeServiceContext context = ComputeServiceContextFactory
.createStandaloneContext(ServerManagerComputeServiceContextBuilder.createContextModule());
context.close();
}
}

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 Cloud Conscious, LLC.
<info@cloudconscious.com>
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless required by
applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
====================================================================
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!--
For more configuration infromation and examples see the Apache
Log4j website: http://logging.apache.org/log4j/
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-wire.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<!-- ================ -->
<!-- Limit categories -->
<!-- ================ -->
<category name="org.jclouds">
<priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
<category name="jclouds.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<priority value="WARN" />
</root>
</log4j:configuration>