diff --git a/archetypes/compute-service-archetype/.gitignore b/archetypes/compute-service-archetype/.gitignore
new file mode 100644
index 0000000000..17c6813eae
--- /dev/null
+++ b/archetypes/compute-service-archetype/.gitignore
@@ -0,0 +1,9 @@
+# use glob syntax.
+syntax: glob
+target
+.settings
+.classpath
+.project
+jclouds-compute-service-archetype.iml
+jclouds-compute-service-archetype.ipr
+jclouds-compute-service-archetype.iws
\ No newline at end of file
diff --git a/archetypes/compute-service-archetype/pom.xml b/archetypes/compute-service-archetype/pom.xml
new file mode 100644
index 0000000000..f43e4e0bf1
--- /dev/null
+++ b/archetypes/compute-service-archetype/pom.xml
@@ -0,0 +1,74 @@
+
+
+
+
+ 4.0.0
+
+ org.jclouds
+ jclouds-archetypes
+ 1.0-SNAPSHOT
+
+ jclouds-compute-service-archetype
+ jclouds Compute service archetype
+ Maven archetype for a provider of a Computer service
+ maven-archetype
+
+
+
+
+ maven-archetype-plugin
+ 2.0-alpha-4
+ true
+
+
+ maven-resources-plugin
+
+ UTF-8
+
+
+
+
+
+ org.apache.maven.archetype
+ archetype-packaging
+ 2.0-alpha-4
+
+
+
+
+
+ false
+ jclouds-googlecode-deploy
+ svn:https://jclouds.googlecode.com/svn/repo
+
+
+ jclouds-rimu-snapshots
+ dav:http://jclouds.rimuhosting.com/maven2/snapshots/
+
+
+ website
+ website
+ file://${basedir}/target/dist/site/jclouds-testing/
+
+
+
diff --git a/archetypes/compute-service-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml b/archetypes/compute-service-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml
new file mode 100644
index 0000000000..697610ea1c
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+ org.jclouds
+
+
+ Adrian Cole
+
+
+
+
+
+
+
+
+ src/main/java
+
+ **/*.java
+
+
+
+ src/test/java
+
+ **/*.java
+
+
+
+ src/test/resources
+
+ **/*.xml
+
+
+
+ src/test/resources
+
+ **/*.json
+
+
+
+
+
+ .gitignore
+
+
+
+
\ No newline at end of file
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/.gitignore b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/.gitignore
new file mode 100644
index 0000000000..6173a03a60
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/.gitignore
@@ -0,0 +1,9 @@
+# use glob syntax.
+syntax: glob
+target
+.settings
+.classpath
+.project
+jclouds-${artifactId}.iml
+jclouds-${artifactId}.ipr
+jclouds-${artifactId}.iws
\ No newline at end of file
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml
new file mode 100644
index 0000000000..818db1d9f4
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml
@@ -0,0 +1,93 @@
+#set( $lcaseProviderName = ${providerName.toLowerCase()} )
+#set( $symbol_dollar = '$' )
+
+
+
+ 4.0.0
+
+ org.jclouds
+ jclouds-project
+ 1.0-SNAPSHOT
+ ../project/pom.xml
+
+ ${groupId}
+ jclouds-${artifactId}
+ jclouds ${providerName} compute service
+ jar
+ jclouds components to access ${providerName}
+
+
+ scm:svn:http://jclouds.googlecode.com/svn/trunk/${lcaseProviderName}
+ scm:svn:https://jclouds.googlecode.com/svn/trunk/${lcaseProviderName}
+ http://jclouds.googlecode.com/svn/trunk/${lcaseProviderName}
+
+
+ ${providerUser}
+ ${providerPassword}
+ ${providerEndpoint}
+
+
+
+ ${symbol_dollar}{project.groupId}
+ jclouds-compute
+ ${symbol_dollar}{project.version}
+
+
+ ${symbol_dollar}{project.groupId}
+ jclouds-compute
+ ${symbol_dollar}{project.version}
+ test-jar
+ test
+
+
+ ${symbol_dollar}{project.groupId}
+ jclouds-core
+ ${symbol_dollar}{project.version}
+ test-jar
+ test
+
+
+ ${symbol_dollar}{project.groupId}
+ jclouds-jsch
+ ${symbol_dollar}{project.version}
+ test
+
+
+ ${symbol_dollar}{project.groupId}
+ jclouds-log4j
+ ${symbol_dollar}{project.version}
+ test
+
+
+ log4j
+ log4j
+ 1.2.14
+ test
+
+
+
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__.java
new file mode 100644
index 0000000000..764ae0cf71
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__.java
@@ -0,0 +1,47 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+package ${package};
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.inject.Qualifier;
+
+/**
+ * Related to a ${providerName} resource.
+ *
+ * @author ${author}
+ *
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Qualifier
+public @interface ${providerName} {
+
+}
\ No newline at end of file
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__AsyncClient.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__AsyncClient.java
new file mode 100644
index 0000000000..2820a4703a
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__AsyncClient.java
@@ -0,0 +1,40 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+package ${package};
+
+import com.google.inject.ImplementedBy;
+import ${package}.internal.${providerName}AsyncClientImpl;
+
+/**
+ * @author ${author}
+ */
+@ImplementedBy(${providerName}AsyncClientImpl.class)
+public interface ${providerName}AsyncClient {
+ /*
+ * TODO: define interface methods for ${providerName}
+ */
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__Client.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__Client.java
new file mode 100644
index 0000000000..d65d10541f
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__Client.java
@@ -0,0 +1,41 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+package ${package};
+
+import java.util.concurrent.TimeUnit;
+
+import org.jclouds.concurrent.Timeout;
+
+/**
+ * @author ${author}
+ */
+@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
+public interface ${providerName}Client {
+ /*
+ * TODO: define synchronous versions of methods in ${providerName}AsyncClient
+ */
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__ContextBuilder.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__ContextBuilder.java
new file mode 100644
index 0000000000..fed78aad81
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__ContextBuilder.java
@@ -0,0 +1,69 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+package ${package};
+
+
+import java.util.List;
+import java.util.Properties;
+
+import com.google.inject.Key;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.ComputeServiceContextBuilder;
+import org.jclouds.compute.internal.ComputeServiceContextImpl;
+import ${package}.config.${providerName}ComputeServiceContextModule;
+import ${package}.config.${providerName}RestClientModule;
+
+import com.google.inject.Module;
+import com.google.inject.TypeLiteral;
+
+/**
+ * @author ${author}
+ */
+public class ${providerName}ContextBuilder extends ComputeServiceContextBuilder<${providerName}AsyncClient, ${providerName}Client> {
+
+ public ${providerName}ContextBuilder(Properties props) {
+ super(new TypeLiteral<${providerName}AsyncClient>() {},
+ new TypeLiteral<${providerName}Client>() {},
+ props);
+ }
+
+ protected void addClientModule(List modules) {
+ modules.add(new ${providerName}RestClientModule());
+ }
+
+ @Override
+ protected void addContextModule(List modules) {
+ modules.add(new ${providerName}ComputeServiceContextModule());
+ }
+
+ @Override
+ public ComputeServiceContext buildComputeServiceContext() {
+ return this.buildInjector().getInstance(Key.get(
+ new TypeLiteral>() {}));
+ }
+
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__ContextFactory.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__ContextFactory.java
new file mode 100644
index 0000000000..9f5cd09296
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__ContextFactory.java
@@ -0,0 +1,66 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ */
+package ${package};
+
+import java.net.URI;
+import java.util.Properties;
+
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
+import org.jclouds.logging.jdk.config.JDKLoggingModule;
+
+import com.google.inject.Module;
+
+/**
+ * Creates {@link ComputeServiceContext} instances based on the most commonly
+ * requested arguments.
+ *
+ * Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
+ *
+ *
+ * If no Module
s are specified, the default {@link JDKLoggingModule logging} and
+ * {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
+ *
+ * @author ${author}
+ * @see ComputeServiceContext
+ */
+public class ${providerName}ContextFactory {
+ public static ComputeServiceContext createContext(Properties properties, Module... modules) {
+ return new ${providerName}ContextBuilder(
+ new ${providerName}PropertiesBuilder(properties).build()).withModules(modules)
+ .buildComputeServiceContext();
+ }
+
+ public static ComputeServiceContext createContext(Properties properties, String user,
+ String key, Module... modules) {
+ return new ${providerName}ContextBuilder(
+ new ${providerName}PropertiesBuilder(properties).withCredentials(user, key)
+ .build()).withModules(modules).buildComputeServiceContext();
+ }
+
+ public static ComputeServiceContext createContext(URI endpoint, String user, String key,
+ Module... modules) {
+ return new ${providerName}ContextBuilder(
+ new ${providerName}PropertiesBuilder(endpoint, user, key).withEndpoint(endpoint).build())
+ .withModules(modules).buildComputeServiceContext();
+ }
+}
\ No newline at end of file
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__PropertiesBuilder.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__PropertiesBuilder.java
new file mode 100644
index 0000000000..dd5f0fabfe
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/__providerName__PropertiesBuilder.java
@@ -0,0 +1,76 @@
+#set( $ucaseProviderName = ${providerName.toUpperCase()} )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+package ${package};
+
+import org.jclouds.PropertiesBuilder;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static ${package}.reference.${providerName}Constants.*;
+
+import java.net.URI;
+import java.util.Properties;
+
+/**
+ * Builds properties used in ${providerName} Clients
+ *
+ * @author ${author}
+ *
+ */
+public class ${providerName}PropertiesBuilder extends PropertiesBuilder {
+ @Override
+ protected Properties defaultProperties() {
+ Properties properties = super.defaultProperties();
+ properties.setProperty(PROPERTY_${ucaseProviderName}_ENDPOINT, "${providerEndpoint}");
+ properties.setProperty(PROPERTY_${ucaseProviderName}_SESSIONINTERVAL, 8 * 60 + "");
+ return properties;
+ }
+
+ public ${providerName}PropertiesBuilder(Properties properties) {
+ super(properties);
+ }
+
+ public ${providerName}PropertiesBuilder(URI endpoint, String id, String secret) {
+ super();
+ withCredentials(id, secret);
+ withEndpoint(endpoint);
+ }
+
+ public ${providerName}PropertiesBuilder withTokenExpiration(long seconds) {
+ properties.setProperty(PROPERTY_${ucaseProviderName}_SESSIONINTERVAL, seconds + "");
+ return this;
+ }
+
+ public ${providerName}PropertiesBuilder withCredentials(String id, String secret) {
+ properties.setProperty(PROPERTY_${ucaseProviderName}_USER, checkNotNull(id, "user"));
+ properties.setProperty(PROPERTY_${ucaseProviderName}_KEY, checkNotNull(secret, "key"));
+ return this;
+ }
+
+ public ${providerName}PropertiesBuilder withEndpoint(URI endpoint) {
+ properties.setProperty(PROPERTY_${ucaseProviderName}_ENDPOINT,
+ checkNotNull(endpoint, "endpoint").toString());
+ return this;
+ }
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__ComputeServiceContextModule.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__ComputeServiceContextModule.java
new file mode 100644
index 0000000000..32fbef6f96
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__ComputeServiceContextModule.java
@@ -0,0 +1,256 @@
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ */
+package ${package}.config;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContext;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Size;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.internal.ComputeServiceContextImpl;
+import org.jclouds.compute.predicates.RunScriptRunning;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.strategy.AddNodeWithTagStrategy;
+import org.jclouds.compute.strategy.DestroyNodeStrategy;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
+import org.jclouds.compute.strategy.ListNodesStrategy;
+import org.jclouds.compute.strategy.RebootNodeStrategy;
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.domain.internal.LocationImpl;
+import org.jclouds.logging.Logger;
+import org.jclouds.predicates.RetryablePredicate;
+import org.jclouds.rest.RestContext;
+import org.jclouds.ssh.SshClient;
+import ${package}.${providerName}AsyncClient;
+import ${package}.${providerName}Client;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.inject.Provides;
+
+/**
+ * @author ${author}
+ */
+public class ${providerName}ComputeServiceContextModule extends ${providerName}ContextModule {
+
+ @Override
+ protected void configure() {
+ super.configure();
+ bind(AddNodeWithTagStrategy.class).to(${providerName}AddNodeWithTagStrategy.class);
+ bind(ListNodesStrategy.class).to(${providerName}ListNodesStrategy.class);
+ bind(GetNodeMetadataStrategy.class).to(${providerName}GetNodeMetadataStrategy.class);
+ bind(RebootNodeStrategy.class).to(${providerName}RebootNodeStrategy.class);
+ bind(DestroyNodeStrategy.class).to(${providerName}DestroyNodeStrategy.class);
+ }
+
+ @Provides
+ @Named("NAMING_CONVENTION")
+ @Singleton
+ String provideNamingConvention() {
+ return "%s-%d";
+ }
+
+ @Singleton
+ public static class ${providerName}AddNodeWithTagStrategy implements AddNodeWithTagStrategy {
+
+ @Inject
+ protected ${providerName}AddNodeWithTagStrategy() {
+ }
+
+ @Override
+ public NodeMetadata execute(String tag, String name, Template template) {
+ /*
+ * TODO: implement
+ */
+ return null;
+ }
+ }
+
+ @Singleton
+ public static class ${providerName}RebootNodeStrategy implements RebootNodeStrategy {
+
+ @Inject
+ protected ${providerName}RebootNodeStrategy() {
+ }
+
+ @Override
+ public boolean execute(ComputeMetadata node) {
+ /*
+ * TODO: implement
+ */
+ return false;
+ }
+ }
+
+ @Singleton
+ public static class ${providerName}ListNodesStrategy implements ListNodesStrategy {
+
+ @Inject
+ protected ${providerName}ListNodesStrategy() {
+ }
+
+ @Override
+ public Iterable extends ComputeMetadata> execute() {
+ /*
+ * TODO: implement
+ */
+ return null;
+ }
+
+ }
+
+ @Singleton
+ public static class ${providerName}GetNodeMetadataStrategy implements GetNodeMetadataStrategy {
+
+ @Inject
+ protected ${providerName}GetNodeMetadataStrategy() {
+ }
+
+ @Override
+ public NodeMetadata execute(ComputeMetadata node) {
+ /*
+ * TODO: implement
+ */
+ return null;
+ }
+ }
+
+ @Singleton
+ public static class ${providerName}DestroyNodeStrategy implements DestroyNodeStrategy {
+
+ @Inject
+ protected ${providerName}DestroyNodeStrategy() {
+ }
+
+ @Override
+ public boolean execute(ComputeMetadata node) {
+ /*
+ * TODO: implement
+ */
+ return false;
+ }
+
+ }
+
+ @Provides
+ @Singleton
+ ComputeServiceContext provideContext(ComputeService computeService,
+ RestContext<${providerName}AsyncClient, ${providerName}Client> context) {
+ return new ComputeServiceContextImpl<${providerName}AsyncClient, ${providerName}Client>(computeService, context);
+ }
+
+ @Provides
+ @Singleton
+ @Named("NOT_RUNNING")
+ protected Predicate runScriptRunning(RunScriptRunning stateRunning) {
+ return new RetryablePredicate(Predicates.not(stateRunning), 600, 3,
+ TimeUnit.SECONDS);
+ }
+
+ @Provides
+ @Singleton
+ Location getDefaultLocation(Map locations) {
+ return locations.get("SANFRANCISCO");
+ }
+
+ @Provides
+ @Singleton
+ Map getDefaultLocations(${providerName}Client sync, LogHolder holder,
+ Function indexer) {
+ final Set locations = Sets.newHashSet();
+ holder.logger.debug(">> providing locations");
+ locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO", "San Francisco, CA", null,
+ true));
+ holder.logger.debug("<< locations(%d)", locations.size());
+ return Maps.uniqueIndex(locations, new Function() {
+
+ @Override
+ public String apply(Location from) {
+ return from.getId();
+ }
+ });
+ }
+
+ @Provides
+ @Singleton
+ protected Function indexer() {
+ return new Function() {
+ @Override
+ public String apply(ComputeMetadata from) {
+ return from.getId();
+ }
+ };
+ }
+
+ @Provides
+ @Singleton
+ protected Map provideSizes(${providerName}Client sync,
+ Map images, LogHolder holder,
+ Function indexer) throws InterruptedException,
+ TimeoutException, ExecutionException {
+ final Set sizes = Sets.newHashSet();
+ holder.logger.debug(">> providing sizes");
+
+ /*
+ * TODO: implement
+ */
+
+ holder.logger.debug("<< sizes(%d)", sizes.size());
+ return Maps.uniqueIndex(sizes, indexer);
+ }
+
+ private static class LogHolder {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+ }
+
+ @Provides
+ @Singleton
+ protected Map provideImages(final ${providerName}Client sync, LogHolder holder,
+ Function indexer, Location location)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ final Set images = Sets.newHashSet();
+ holder.logger.debug(">> providing images");
+
+ /*
+ * TODO: implement
+ */
+
+ holder.logger.debug("<< images(%d)", images.size());
+ return Maps.uniqueIndex(images, indexer);
+ }
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__ContextModule.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__ContextModule.java
new file mode 100644
index 0000000000..362942736a
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__ContextModule.java
@@ -0,0 +1,78 @@
+#set( $ucaseProviderName = ${providerName.toUpperCase()} )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+package ${package}.config;
+
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.Date;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import com.google.gson.*;
+import ${package}.${providerName}AsyncClient;
+import ${package}.${providerName}Client;
+import org.jclouds.http.functions.config.ParserModule.DateAdapter;
+import org.jclouds.lifecycle.Closer;
+import org.jclouds.rest.RestContext;
+import org.jclouds.rest.internal.RestContextImpl;
+import ${package}.${providerName};
+import ${package}.reference.${providerName}Constants;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+
+/**
+ * Configures the ${providerName} connection, including logging and http transport.
+ *
+ * @author ${author}
+ */
+public class ${providerName}ContextModule extends AbstractModule {
+ @Override
+ protected void configure() {
+ bind(DateAdapter.class).to(DateSecondsAdapter.class);
+ }
+
+ @Provides
+ @Singleton
+ RestContext<${providerName}AsyncClient, ${providerName}Client> provideContext(Closer closer, ${providerName}AsyncClient asyncApi,
+ ${providerName}Client syncApi, @${providerName} URI endPoint, @Named(${providerName}Constants.PROPERTY_${ucaseProviderName}_USER) String account) {
+ return new RestContextImpl<${providerName}AsyncClient, ${providerName}Client>(closer, asyncApi, syncApi, endPoint, account);
+ }
+
+ @Singleton
+ public static class DateSecondsAdapter implements DateAdapter {
+
+ public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
+ return new JsonPrimitive(src.getTime());
+ }
+
+ public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+ throws JsonParseException {
+ String toParse = json.getAsJsonPrimitive().getAsString();
+ return new Date(Long.valueOf(toParse));
+ }
+ }
+}
\ No newline at end of file
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__RestClientModule.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__RestClientModule.java
new file mode 100644
index 0000000000..4106cd9ce2
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/config/__providerName__RestClientModule.java
@@ -0,0 +1,87 @@
+#set( $ucaseProviderName = ${providerName.toUpperCase()} )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+package ${package}.config;
+
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.GridO;
+import org.jclouds.concurrent.ExpirableSupplier;
+import org.jclouds.date.TimeStamp;
+import org.jclouds.http.RequiresHttp;
+import org.jclouds.logging.Logger;
+import org.jclouds.reference.GridOConstants;
+import org.jclouds.rest.ConfiguresRestClient;
+
+import com.google.common.base.Supplier;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+
+import static ${package}.reference.${providerName}Constants.*;
+
+/**
+ * Configures the ${providerName} connection.
+ *
+ * @author ${author}
+ */
+@RequiresHttp
+@ConfiguresRestClient
+public class ${providerName}RestClientModule extends AbstractModule {
+ /*
+ * TODO: modify configuration for ${providerName}Client
+ */
+
+ @Resource
+ protected Logger logger = Logger.NULL;
+
+ @Override
+ protected void configure() {
+ requestInjection(this);
+ }
+
+ @Provides
+ @Singleton
+ @${providerName}
+ protected URI provideURI(@Named(${providerName}Constants.PROPERTY_${ucaseProviderName}_ENDPOINT) String endpoint) {
+ return URI.create(endpoint);
+ }
+
+ // borrowing concurrency code to ensure that caching takes place properly
+ @Provides
+ @TimeStamp
+ Supplier provideTimeStampCache(
+ @Named(PROPERTY_${ucaseProviderName}_SESSIONINTERVAL) long seconds) {
+ return new ExpirableSupplier(new Supplier() {
+ public Long get() {
+ return System.currentTimeMillis() / 1000;
+ }
+ }, seconds, TimeUnit.SECONDS);
+ }
+
+}
\ No newline at end of file
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/internal/__providerName__AsyncClientImpl.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/internal/__providerName__AsyncClientImpl.java
new file mode 100644
index 0000000000..ac8f5303fb
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/internal/__providerName__AsyncClientImpl.java
@@ -0,0 +1,46 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+package ${package}.internal;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import ${package}.${providerName}AsyncClient;
+
+/**
+ * @author ${author}
+ */
+@Singleton
+public class ${providerName}AsyncClientImpl implements ${providerName}AsyncClient {
+
+ @Inject
+ public ${providerName}AsyncClientImpl() {
+ }
+
+ /*
+ * TODO: implement ${providerName}AsyncClient
+ */
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/reference/__providerName__Constants.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/reference/__providerName__Constants.java
new file mode 100644
index 0000000000..9d4c692e9c
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/main/java/reference/__providerName__Constants.java
@@ -0,0 +1,42 @@
+#set( $lcaseProviderName = ${providerName.toLowerCase()} )
+#set( $ucaseProviderName = ${providerName.toUpperCase()} )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+package ${package}.reference;
+
+/**
+ * Configuration properties and constants used in ${providerName} connections.
+ *
+ * @author Adrian Cole
+ */
+public interface ${providerName}Constants {
+ public static final String PROPERTY_${ucaseProviderName}_ENDPOINT = "jclouds.${lcaseProviderName}.endpoint";
+ public static final String PROPERTY_${ucaseProviderName}_USER = "jclouds.${lcaseProviderName}.user";
+ public static final String PROPERTY_${ucaseProviderName}_KEY = "jclouds.${lcaseProviderName}.key";
+ /**
+ * how long do we wait before obtaining a new timestamp for requests.
+ */
+ public static final String PROPERTY_${ucaseProviderName}_SESSIONINTERVAL = "jclouds.${lcaseProviderName}.sessioninterval";
+
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/PropertiesTest.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/PropertiesTest.java
new file mode 100644
index 0000000000..694801b638
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/PropertiesTest.java
@@ -0,0 +1,53 @@
+#set( $lcaseProviderName = ${providerName.toLowerCase()} )
+#set( $ucaseProviderName = ${providerName.toUpperCase()} )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ */
+package ${package};
+
+import com.google.common.io.Resources;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * @author ${author}
+ */
+@Test(groups = "unit", testName = "compute.PropertiesTest")
+public class PropertiesTest {
+ private Properties properties;
+
+ @BeforeTest
+ public void setUp() throws IOException {
+ properties = new Properties();
+ properties.load(Resources.newInputStreamSupplier(Resources.getResource("compute.properties"))
+ .getInput());
+ }
+
+ public void test${providerName}() {
+ assertEquals(properties.getProperty("${lcaseProviderName}.contextbuilder"),
+ ${providerName}ContextBuilder.class.getName());
+ assertEquals(properties.getProperty("${lcaseProviderName}.propertiesbuilder"),
+ ${providerName}PropertiesBuilder.class.getName());
+ }
+
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__ComputeServiceLiveTest.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__ComputeServiceLiveTest.java
new file mode 100644
index 0000000000..3b090fc9b2
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__ComputeServiceLiveTest.java
@@ -0,0 +1,109 @@
+#set( $lcaseProviderName = ${providerName.toLowerCase()} )
+#set( $camelCaseProviderName = "${providerName.substring(0, 1).toLowerCase()}${providerName.substring(1)}" )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ */
+package ${package};
+
+import static org.jclouds.compute.domain.OsFamily.CENTOS;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.jclouds.compute.BaseComputeServiceLiveTest;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.compute.ComputeServiceContextFactory;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeState;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.domain.TemplateBuilder;
+import org.jclouds.rest.RestContext;
+import org.jclouds.ssh.jsch.config.JschSshClientModule;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author ${author}
+ */
+@Test(groups = "live", enabled = true, sequential = true, testName = "${lcaseProviderName}.${providerName}ComputeServiceLiveTest")
+public class ${providerName}ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
+
+ @BeforeClass
+ @Override
+ public void setServiceDefaults() {
+ service = "${lcaseProviderName}";
+ }
+
+ @Override
+ public String buildScript() {
+ return new StringBuilder()
+ .append("TODO: define build script")
+ .toString();
+ }
+
+ protected Template buildTemplate(TemplateBuilder templateBuilder) {
+ return templateBuilder.osFamily(CENTOS).imageDescriptionMatches("TODO: insert image description").smallest()
+ .build();
+ }
+
+ @Override
+ protected JschSshClientModule getSshModule() {
+ return new JschSshClientModule();
+ }
+
+ public void testAssignability() throws Exception {
+ @SuppressWarnings("unused")
+ RestContext<${providerName}AsyncClient, ${providerName}Client> ${camelCaseProviderName}Context =
+ new ComputeServiceContextFactory().createContext(service, user, password).getProviderSpecificContext();
+ }
+
+ @Test(enabled = true)
+ public void endToEndComputeServiceTest() {
+ /*
+ * TODO: adapt the following sample test for ${providerName}
+ */
+ ComputeService service = context.getComputeService();
+ Template t = service.templateBuilder().minRam(1024).imageId("1532").build();
+
+ assertEquals(t.getImage().getId(), "1532");
+ service.runNodesWithTag(this.service, 1, t);
+
+ Map nodes = service.getNodes();
+
+ ComputeMetadata node = Iterables.find(nodes.values(), new Predicate() {
+ @Override
+ public boolean apply(ComputeMetadata computeMetadata) {
+ return computeMetadata.getName().startsWith(${providerName}ComputeServiceLiveTest.this.service);
+ }
+ });
+
+ NodeMetadata nodeMetadata = service.getNodeMetadata(node);
+ assertEquals(nodeMetadata.getPublicAddresses().size(), 1,
+ "There must be 1 public address for the node");
+ assertTrue(nodeMetadata.getName().startsWith(this.service));
+ service.rebootNode(nodeMetadata); // blocks until finished
+
+ assertEquals(service.getNodeMetadata(nodeMetadata).getState(), NodeState.RUNNING);
+ service.destroyNode(nodeMetadata);
+ }
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__LiveTest.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__LiveTest.java
new file mode 100644
index 0000000000..74a2dcc5b5
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/__providerName__LiveTest.java
@@ -0,0 +1,94 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ */
+package ${package};
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.jclouds.logging.log4j.config.Log4JLoggingModule;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeGroups;
+import org.testng.annotations.Test;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * End to end live test for ${providerName}
+ *
+ * @author ${author}
+ */
+@Test(groups = "live", testName = "${lcaseProviderName}.${providerName}LiveTest")
+public class ${providerName}LiveTest {
+ private ${providerName}Client client;
+
+ @BeforeGroups(groups = { "live" })
+ public void setupClient() {
+ String endpoint = checkNotNull(System.getProperty("jclouds.test.endpoint"),
+ "jclouds.test.endpoint");
+ String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
+ String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
+
+ client = new ${providerName}ContextBuilder(
+ new ${providerName}PropertiesBuilder(URI.create(endpoint), user, password).build())
+ .withModules(new Log4JLoggingModule()).buildContext().getApi();
+ }
+
+ /**
+ * Tests server start, reboot and deletion.
+ * TODO: describe additional services tested
+ */
+ @Test(enabled=true)
+ public void testServerLifecycle() {
+ /*
+ * TODO: implement
+ */
+ }
+
+ /**
+ * Tests common server image operations.
+ */
+ @Test(enabled=true)
+ public void testImageLifecycle() {
+ /*
+ * TODO: implement
+ */
+ }
+
+ @Test(enabled=true)
+ public void testShellAccess() throws IOException {
+ /*
+ * TODO: implement
+ */
+ }
+
+ /**
+ * In case anything went wrong during the tests, removes the objects
+ * created in the tests.
+ */
+ @AfterTest
+ public void cleanup() {
+ /*
+ * TODO: implement
+ */
+ }
+
+}
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/config/__providerName__ContextModuleTest.java b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/config/__providerName__ContextModuleTest.java
new file mode 100644
index 0000000000..633e65ab79
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/java/config/__providerName__ContextModuleTest.java
@@ -0,0 +1,117 @@
+#set( $lcaseProviderName = ${providerName.toLowerCase()} )
+#set( $ucaseProviderName = ${providerName.toUpperCase()} )
+/**
+ *
+ * Copyright (C) 2010 Cloud Conscious, LLC.
+ *
+ * ====================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ====================================================================
+ */
+package ${package}.config;
+
+import static org.testng.Assert.assertEquals;
+import static com.google.common.util.concurrent.Executors.sameThreadExecutor;
+
+import org.jclouds.concurrent.config.ExecutorServiceModule;
+import org.jclouds.http.HttpRetryHandler;
+import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
+import org.jclouds.http.functions.config.ParserModule;
+import org.jclouds.http.functions.config.ParserModule.DateAdapter;
+import org.jclouds.http.handlers.DelegatingErrorHandler;
+import org.jclouds.http.handlers.DelegatingRetryHandler;
+import org.jclouds.http.handlers.RedirectionRetryHandler;
+import org.jclouds.logging.Logger;
+import org.jclouds.logging.Logger.LoggerFactory;
+import ${package}.reference.${providerName}Constants;
+import org.jclouds.util.Jsr330;
+import org.jclouds.Constants;
+import org.testng.annotations.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+/**
+ * @author ${author}
+ */
+@Test(groups = "unit", testName = "${lcaseProviderName}.${providerName}ContextModule")
+public class ${providerName}ContextModuleTest {
+
+ Injector createInjector() {
+ return Guice.createInjector(new ${providerName}RestClientModule(), new ${providerName}ContextModule() {
+ @Override
+ protected void configure() {
+ bindConstant().annotatedWith(Jsr330.named(${providerName}Constants.PROPERTY_${ucaseProviderName}_USER)).to(
+ "user");
+ bindConstant().annotatedWith(Jsr330.named(${providerName}Constants.PROPERTY_${ucaseProviderName}_KEY))
+ .to("password");
+ bindConstant().annotatedWith(Jsr330.named(${providerName}Constants.PROPERTY_${ucaseProviderName}_ENDPOINT))
+ .to("http://localhost");
+ bindConstant().annotatedWith(Jsr330.named(${providerName}Constants.PROPERTY_${ucaseProviderName}_SESSIONINTERVAL))
+ .to("30");
+ bindConstant().annotatedWith(Jsr330.named(Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST))
+ .to("1");
+ bindConstant().annotatedWith(Jsr330.named(Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT))
+ .to("0");
+ bindConstant().annotatedWith(Jsr330.named(Constants.PROPERTY_IO_WORKER_THREADS))
+ .to("1");
+ bindConstant().annotatedWith(Jsr330.named(Constants.PROPERTY_USER_THREADS))
+ .to("1");
+ bindConstant().annotatedWith(Jsr330.named(Constants.PROPERTY_CONNECTION_TIMEOUT))
+ .to("30");
+ bindConstant().annotatedWith(Jsr330.named(Constants.PROPERTY_SO_TIMEOUT))
+ .to("10");
+ bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
+ public Logger getLogger(String category) {
+ return Logger.NULL;
+ }
+ });
+ super.configure();
+ }
+ }, new ParserModule(), new JavaUrlHttpCommandExecutorServiceModule(),
+ new ExecutorServiceModule(sameThreadExecutor(), sameThreadExecutor()));
+ }
+
+ @Test
+ void testServerErrorHandler() {
+ DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class);
+ assertEquals(handler.getServerErrorHandler().getClass(),
+ "TODO: insert expected error handler class");
+ }
+
+ @Test
+ void testDateTimeAdapter() {
+ assertEquals(this.createInjector().getInstance(DateAdapter.class).getClass(),
+ ${providerName}ContextModule.DateSecondsAdapter.class);
+ }
+
+ @Test
+ void testClientErrorHandler() {
+ DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class);
+ assertEquals(handler.getClientErrorHandler().getClass(),
+ "TODO: insert expected error handler class");
+ }
+
+ @Test
+ void testClientRetryHandler() {
+ DelegatingRetryHandler handler = createInjector().getInstance(DelegatingRetryHandler.class);
+ assertEquals(handler.getClientErrorRetryHandler(), HttpRetryHandler.NEVER_RETRY);
+ }
+
+ @Test
+ void testRedirectionRetryHandler() {
+ DelegatingRetryHandler handler = createInjector().getInstance(DelegatingRetryHandler.class);
+ assertEquals(handler.getRedirectionRetryHandler().getClass(), RedirectionRetryHandler.class);
+ }
+
+}
\ No newline at end of file
diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/resources/log4j.xml b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/resources/log4j.xml
new file mode 100644
index 0000000000..e170ef641e
--- /dev/null
+++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/src/test/resources/log4j.xml
@@ -0,0 +1,145 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/archetypes/json-client-archetype/src/main/resources/archetype-resources/pom.xml b/archetypes/json-client-archetype/src/main/resources/archetype-resources/pom.xml
index 10e98cc7c1..5a39109e04 100644
--- a/archetypes/json-client-archetype/src/main/resources/archetype-resources/pom.xml
+++ b/archetypes/json-client-archetype/src/main/resources/archetype-resources/pom.xml
@@ -1,78 +1,79 @@
-#set( $lcaseClientName = ${clientName.toLowerCase()} )
-#set( $symbol_dollar = '$' )
-
-
-
- 4.0.0
-
- org.jclouds
- jclouds-project
- 1.0-SNAPSHOT
- ../project/pom.xml
-
- ${groupId}
- jclouds-${artifactId}
- jclouds ${clientName} core
- jclouds components to access ${clientName}
-
-
- scm:svn:http://jclouds.googlecode.com/svn/trunk/${lcaseClientName}
- scm:svn:https://jclouds.googlecode.com/svn/trunk/${lcaseClientName}
- http://jclouds.googlecode.com/svn/trunk/${lcaseClientName}
-
-
- ${clientUser}
- ${clientPassword}
-
-
-
- ${symbol_dollar}{project.groupId}
- jclouds-core
- ${symbol_dollar}{project.version}
-
-
- ${symbol_dollar}{project.groupId}
- jclouds-core
- ${symbol_dollar}{project.version}
- test-jar
- test
-
-
- log4j
- log4j
- 1.2.14
- test
-
-
- ${symbol_dollar}{project.groupId}
- jclouds-log4j
- ${symbol_dollar}{project.version}
- test
-
-
-
+#set( $lcaseClientName = ${clientName.toLowerCase()} )
+#set( $symbol_dollar = '$' )
+
+
+
+
+ org.jclouds
+ jclouds-project
+ 1.0-SNAPSHOT
+ ../project/pom.xml
+
+ 4.0.0
+ ${groupId}
+ jclouds-${artifactId}
+ jclouds ${clientName} core
+ jar
+ jclouds components to access ${clientName}
+
+
+ scm:svn:http://jclouds.googlecode.com/svn/trunk/${lcaseClientName}
+ scm:svn:https://jclouds.googlecode.com/svn/trunk/${lcaseClientName}
+ http://jclouds.googlecode.com/svn/trunk/${lcaseClientName}
+
+
+ ${clientUser}
+ ${clientPassword}
+
+
+
+ ${symbol_dollar}{project.groupId}
+ jclouds-core
+ ${symbol_dollar}{project.version}
+
+
+ ${symbol_dollar}{project.groupId}
+ jclouds-core
+ ${symbol_dollar}{project.version}
+ test-jar
+ test
+
+
+ log4j
+ log4j
+ 1.2.14
+ test
+
+
+ ${symbol_dollar}{project.groupId}
+ jclouds-log4j
+ ${symbol_dollar}{project.version}
+ test
+
+
+
diff --git a/archetypes/pom.xml b/archetypes/pom.xml
index 78e826c354..9fc6a035ab 100644
--- a/archetypes/pom.xml
+++ b/archetypes/pom.xml
@@ -33,5 +33,6 @@
jclouds Maven archetypes
json-client-archetype
+ compute-service-archetype