Issue 695: initial import for new terremark api

This commit is contained in:
Adrian Cole 2011-11-08 21:08:05 +02:00
parent f78f74e68e
commit 6d453aa8d8
32 changed files with 2595 additions and 0 deletions

View File

@ -50,6 +50,9 @@ trmk-vcloudexpress.propertiesbuilder=org.jclouds.trmk.vcloudexpress.TerremarkVCl
trmk-ecloud.contextbuilder=org.jclouds.trmk.ecloud.TerremarkECloudContextBuilder
trmk-ecloud.propertiesbuilder=org.jclouds.trmk.ecloud.TerremarkECloudPropertiesBuilder
trmk-enterprisecloud.contextbuilder=org.jclouds.trmk.enterprisecloud.TerremarkEnterpriseCloudContextBuilder
trmk-enterprisecloud.propertiesbuilder=org.jclouds.trmk.enterprisecloud.TerremarkEnterpriseCloudPropertiesBuilder
chef.contextbuilder=org.jclouds.chef.ChefContextBuilder
chef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder

View File

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to jclouds, Inc. (jclouds) under one or more
contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. jclouds 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.
-->
<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.3.0-SNAPSHOT</version>
<relativePath>../../project/pom.xml</relativePath>
</parent>
<groupId>org.jclouds.provider</groupId>
<artifactId>trmk-enterprisecloud</artifactId>
<name>jclouds Terremark Enterprise Cloud core</name>
<description>jclouds components to access Terremark Enterprise Cloud</description>
<packaging>bundle</packaging>
<!-- bootstrapping: need to fetch the project POM -->
<repositories>
<repository>
<id>jclouds-sona-snapshots-nexus</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<test.trmk-enterprisecloud.endpoint>http://209.251.187.125/livespec</test.trmk-enterprisecloud.endpoint>
<test.trmk-enterprisecloud.apiversion>2011-07-01</test.trmk-enterprisecloud.apiversion>
<test.trmk-enterprisecloud.identity>readonly@terremark.com</test.trmk-enterprisecloud.identity>
<test.trmk-enterprisecloud.credential>T3rr3m@rk</test.trmk-enterprisecloud.credential>
</properties>
<dependencies>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-log4j</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-sshj</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.trmk-enterprisecloud.endpoint</name>
<value>${test.trmk-enterprisecloud.endpoint}</value>
</property>
<property>
<name>test.trmk-enterprisecloud.apiversion</name>
<value>${test.trmk-enterprisecloud.apiversion}</value>
</property>
<property>
<name>test.trmk-enterprisecloud.identity</name>
<value>${test.trmk-enterprisecloud.identity}</value>
</property>
<property>
<name>test.trmk-enterprisecloud.credential</name>
<value>${test.trmk-enterprisecloud.credential}</value>
</property>
</systemProperties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Export-Package>org.jclouds.trmk.enterprisecloud.*;version="${project.version}"</Export-Package>
<Import-Package>org.jclouds.*;version="${project.version}",*</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,41 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.trmk.enterprisecloud.features.TaskAsyncClient;
/**
* Provides asynchronous access to TerremarkEnterpriseCloud via their REST API.
* <p/>
*
* @see TerremarkEnterpriseCloudClient
* @see <a href=
* "http://support.theenterprisecloud.com/kb/default.asp?id=984&Lang=1&SID="
* />
* @author Adrian Cole
*/
public interface TerremarkEnterpriseCloudAsyncClient {
/**
* Provides asynchronous access to Task features.
*/
@Delegate
TaskAsyncClient getTaskClient();
}

View File

@ -0,0 +1,45 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.Delegate;
import org.jclouds.trmk.enterprisecloud.features.TaskClient;
/**
* Provides synchronous access to TerremarkEnterpriseCloud.
* <p/>
*
* @see TerremarkEnterpriseCloudAsyncClient
* @see <a href=
* "http://support.theenterprisecloud.com/kb/default.asp?id=984&Lang=1&SID="
* />
* @author Adrian Cole
*/
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
public interface TerremarkEnterpriseCloudClient {
/**
* Provides synchronous access to Task features.
*/
@Delegate
TaskClient getTaskClient();
}

View File

@ -0,0 +1,45 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud;
import java.util.List;
import java.util.Properties;
import org.jclouds.rest.RestContextBuilder;
import org.jclouds.trmk.enterprisecloud.config.TerremarkEnterpriseCloudRestClientModule;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class TerremarkEnterpriseCloudContextBuilder extends
RestContextBuilder<TerremarkEnterpriseCloudClient, TerremarkEnterpriseCloudAsyncClient> {
public TerremarkEnterpriseCloudContextBuilder(Properties props) {
super(TerremarkEnterpriseCloudClient.class, TerremarkEnterpriseCloudAsyncClient.class, props);
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new TerremarkEnterpriseCloudRestClientModule());
}
}

View File

@ -0,0 +1,47 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud;
import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import java.util.Properties;
import org.jclouds.PropertiesBuilder;
/**
* Builds properties used in TerremarkEnterpriseCloud Clients
*
* @author Adrian Cole
*/
public class TerremarkEnterpriseCloudPropertiesBuilder extends PropertiesBuilder {
@Override
protected Properties defaultProperties() {
Properties properties = super.defaultProperties();
// TODO replace with the actual rest url
properties.setProperty(PROPERTY_ENDPOINT, "http://209.251.187.125/livespec");
properties.setProperty(PROPERTY_API_VERSION, "2011-07-01");
return properties;
}
public TerremarkEnterpriseCloudPropertiesBuilder(Properties properties) {
super(properties);
}
}

View File

@ -0,0 +1,117 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud;
import java.net.URI;
import java.util.Set;
import org.jclouds.providers.BaseProviderMetadata;
import org.jclouds.providers.ProviderMetadata;
import com.google.common.collect.ImmutableSet;
/**
* Implementation of {@link org.jclouds.types.ProviderMetadata} for Terremark
* Enterprise Cloud.
*
* @author Adrian Cole
*/
public class TerremarkEnterpriseCloudProviderMetadata extends BaseProviderMetadata {
/**
* {@inheritDoc}
*/
@Override
public String getId() {
return "trmk-enterprisecloud";
}
/**
* {@inheritDoc}
*/
@Override
public String getType() {
return ProviderMetadata.COMPUTE_TYPE;
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return "Terremark Enterprise Cloud";
}
/**
* {@inheritDoc}
*/
@Override
public String getIdentityName() {
return "Email";
}
/**
* {@inheritDoc}
*/
@Override
public String getCredentialName() {
return "Password";
}
/**
* {@inheritDoc}
*/
@Override
public URI getHomepage() {
return URI.create("TODO");
}
/**
* {@inheritDoc}
*/
@Override
public URI getConsole() {
return URI.create("TODO");
}
/**
* {@inheritDoc}
*/
@Override
public URI getApiDocumentation() {
return URI.create("http://support.theenterprisecloud.com/kb/default.asp?id=984&Lang=1&SID=");
}
/**
* {@inheritDoc}
*/
@Override
public Set<String> getLinkedServices() {
return ImmutableSet.of("trmk-enterprisecloud", "trmk-ecloud", "trmk-vcloudexpress");
}
/**
* {@inheritDoc}
*/
@Override
public Set<String> getIso3166Codes() {
return ImmutableSet.of("TODO");
}
}

View File

@ -0,0 +1,75 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.config;
import java.util.Map;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
import org.jclouds.http.annotation.ClientError;
import org.jclouds.http.annotation.Redirection;
import org.jclouds.http.annotation.ServerError;
import org.jclouds.http.handlers.BackoffLimitedRetryHandler;
import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import org.jclouds.trmk.enterprisecloud.TerremarkEnterpriseCloudAsyncClient;
import org.jclouds.trmk.enterprisecloud.TerremarkEnterpriseCloudClient;
import org.jclouds.trmk.enterprisecloud.features.TaskAsyncClient;
import org.jclouds.trmk.enterprisecloud.features.TaskClient;
import org.jclouds.trmk.enterprisecloud.handlers.TerremarkEnterpriseCloudErrorHandler;
import com.google.common.collect.ImmutableMap;
/**
* Configures the TerremarkEnterpriseCloud connection.
*
* @author Adrian Cole
*/
@RequiresHttp
@ConfiguresRestClient
public class TerremarkEnterpriseCloudRestClientModule extends
RestClientModule<TerremarkEnterpriseCloudClient, TerremarkEnterpriseCloudAsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(TaskClient.class, TaskAsyncClient.class)//
.build();
public TerremarkEnterpriseCloudRestClientModule() {
super(TerremarkEnterpriseCloudClient.class, TerremarkEnterpriseCloudAsyncClient.class, DELEGATE_MAP);
}
@Override
protected void configure() {
super.configure();
}
@Override
protected void bindErrorHandlers() {
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(TerremarkEnterpriseCloudErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(TerremarkEnterpriseCloudErrorHandler.class);
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(TerremarkEnterpriseCloudErrorHandler.class);
}
@Override
protected void bindRetryHandlers() {
bind(HttpRetryHandler.class).annotatedWith(ClientError.class).to(BackoffLimitedRetryHandler.class);
}
}

View File

@ -0,0 +1,132 @@
package org.jclouds.trmk.enterprisecloud.domain;
import static com.google.common.base.CaseFormat.LOWER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.trmk.enterprisecloud.domain.internal.BaseNamedResource;
/**
*
* @author Adrian Cole
*
*/
public class Action extends BaseNamedResource<Action> {
public static enum ActionDisabled {
/**
* The actionDisabled attribute will have a value of noAccess when a user
* does not have permission to perform the action. For example, for a user
* with read-only access, all actions have actionDisabled="noAccess" set.
*/
NO_ACCESS,
/**
* The attribute will have a value of disabled when the action is contrary
* to business rules. For example, the action virtual machine with
* name="power:powerOff" has actionDisabled="disabled" when the virtual
* machine is currently powered off; a virtual machine, which is currently
* off, may not be powered off; it may only be powered on. If both
* conditions apply, actions have actionDisabled="noAccess" set. If
* neither condition applies, the attribute will not appear.
*/
DISABLED,
/**
* ActionDisabled was not parsed by jclouds.
*/
UNRECOGNIZED;
public String value() {
return UPPER_UNDERSCORE.to(LOWER_CAMEL, name());
}
@Override
public String toString() {
return value();
}
public static ActionDisabled fromValue(String actionDisabled) {
try {
return valueOf(LOWER_CAMEL.to(UPPER_UNDERSCORE, checkNotNull(actionDisabled, "actionDisabled")));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
@SuppressWarnings("unchecked")
public static Builder builder() {
return new Builder();
}
/**
* {@inheritDoc}
*/
@Override
public Builder toBuilder() {
return new Builder().fromAction(this);
}
public static class Builder extends BaseNamedResource.Builder<Action> {
protected ActionDisabled actionDisabled;
/**
* @see Action#getActionDisabled
*/
public Builder actionDisabled(ActionDisabled actionDisabled) {
this.actionDisabled = actionDisabled;
return this;
}
@Override
public Action build() {
return new Action(href, type, name, actionDisabled);
}
public Builder fromAction(Action in) {
return fromNamedResource(in).actionDisabled(in.getActionDisabled());
}
/**
* {@inheritDoc}
*/
@Override
public Builder fromNamedResource(BaseNamedResource<Action> in) {
return Builder.class.cast(super.fromNamedResource(in));
}
/**
* {@inheritDoc}
*/
@Override
public Builder fromAttributes(Map<String, String> attributes) {
super.fromAttributes(attributes);
if (attributes.containsKey("actionDisabled"))
actionDisabled(ActionDisabled.fromValue(attributes.get("actionDisabled")));
return this;
}
}
protected final ActionDisabled actionDisabled;
public Action(URI href, String type, String name, @Nullable ActionDisabled actionDisabled) {
super(href, type, name);
this.actionDisabled = actionDisabled;
}
/**
* The attribute actionDisabled appears only when the example has an action
* disabled for business rules.
*
* @return
*/
@Nullable
public ActionDisabled getActionDisabled() {
return actionDisabled;
}
}

View File

@ -0,0 +1,138 @@
package org.jclouds.trmk.enterprisecloud.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
import org.jclouds.trmk.enterprisecloud.domain.internal.BaseNamedResource;
/**
*
* @author Adrian Cole
*
*/
public class Link extends BaseNamedResource<Link> {
public static enum Relationship {
/**
* The entity in the link owns the entity in the response
*/
UP,
/**
* The entity in the response owns the entity in the link
*/
DOWN,
/**
* The entity in the link is an alternate view of the entity in the
* response
*/
ALTERNATE,
/**
* The link is a path to the first page in the pages of responses
*/
FIRST,
/**
* The link is a path to the previous page in the pages of responses
*/
PREVIOUS,
/**
* The link is a path to the next page in the pages of responses
*/
NEXT,
/**
* The link is a path to the last page in the pages of responses
*/
LAST,
/**
* Relationship was not parsed by jclouds.
*/
UNRECOGNIZED;
public String value() {
return name().toLowerCase();
}
@Override
public String toString() {
return value();
}
public static Relationship fromValue(String rel) {
try {
return valueOf(checkNotNull(rel, "rel").toUpperCase());
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
@SuppressWarnings("unchecked")
public static Builder builder() {
return new Builder();
}
/**
* {@inheritDoc}
*/
@Override
public Builder toBuilder() {
return new Builder().fromLink(this);
}
public static class Builder extends BaseNamedResource.Builder<Link> {
protected Relationship rel;
/**
* @see Link#getRelationship
*/
public Builder rel(Relationship rel) {
this.rel = rel;
return this;
}
@Override
public Link build() {
return new Link(href, name, type, rel);
}
public Builder fromLink(Link in) {
return fromNamedResource(in).rel(in.getRelationship());
}
/**
* {@inheritDoc}
*/
@Override
public Builder fromNamedResource(BaseNamedResource<Link> in) {
return Builder.class.cast(super.fromNamedResource(in));
}
/**
* {@inheritDoc}
*/
@Override
public Builder fromAttributes(Map<String, String> attributes) {
super.fromAttributes(attributes);
if (attributes.containsKey("rel"))
rel(Relationship.fromValue(attributes.get("rel")));
return this;
}
}
protected final Relationship rel;
public Link(URI href, String type, String name, Relationship rel) {
super(href, type, name);
this.rel = checkNotNull(rel, "rel");
}
/**
*
* @return
*/
public Relationship getRelationship() {
return rel;
}
}

View File

@ -0,0 +1,83 @@
package org.jclouds.trmk.enterprisecloud.domain;
import java.net.URI;
import java.util.Map;
import org.jclouds.trmk.enterprisecloud.domain.internal.BaseNamedResource;
/**
*
* @author Adrian Cole
*
*/
public class NamedResource extends BaseNamedResource<NamedResource> {
@SuppressWarnings("unchecked")
public static Builder builder() {
return new Builder();
}
/**
* {@inheritDoc}
*/
@Override
public Builder toBuilder() {
return new Builder().fromNamedResource(this);
}
public static class Builder extends BaseNamedResource.Builder<NamedResource> {
/**
* {@inheritDoc}
*/
@Override
public NamedResource build() {
return new NamedResource(href, type, name);
}
/**
* {@inheritDoc}
*/
@Override
public Builder name(String name) {
return Builder.class.cast(super.name(name));
}
/**
* {@inheritDoc}
*/
@Override
public Builder type(String type) {
return Builder.class.cast(super.type(type));
}
/**
* {@inheritDoc}
*/
@Override
public Builder href(URI href) {
return Builder.class.cast(super.href(href));
}
/**
* {@inheritDoc}
*/
@Override
public Builder fromNamedResource(BaseNamedResource<NamedResource> in) {
return Builder.class.cast(super.fromNamedResource(in));
}
/**
* {@inheritDoc}
*/
@Override
public Builder fromAttributes(Map<String, String> in) {
return Builder.class.cast(super.fromAttributes(in));
}
}
public NamedResource(URI href, String type, String name) {
super(href, type, name);
}
}

View File

@ -0,0 +1,291 @@
package org.jclouds.trmk.enterprisecloud.domain;
import static com.google.common.base.CaseFormat.UPPER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Date;
import java.util.Map;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.trmk.enterprisecloud.domain.internal.BaseResource;
/**
*
* @author Adrian Cole
*
*/
public class Task extends BaseResource<Task> {
public static enum Status {
/**
* the task is queued for execution.
*/
QUEUED,
/**
* the task is running.
*/
RUNNING,
/**
* the task failed.
*/
FAILED,
/**
* the task completed successfully.
*/
SUCCESS,
/**
* the task failed with an error.
*/
ERROR,
/**
* Status was not parsed by jclouds.
*/
UNRECOGNIZED;
public String value() {
return UPPER_UNDERSCORE.to(UPPER_CAMEL, name());
}
@Override
public String toString() {
return value();
}
public static Status fromValue(String status) {
try {
return valueOf(UPPER_CAMEL.to(UPPER_UNDERSCORE, checkNotNull(status, "status")));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
}
@SuppressWarnings("unchecked")
public static Builder builder() {
return new Builder();
}
/**
* {@inheritDoc}
*/
@Override
public Builder toBuilder() {
return new Builder().fromTask(this);
}
public static class Builder extends BaseResource.Builder<Task> {
protected String operation;
protected Status status;
protected NamedResource impactedItem;
protected Date startTime;
protected Date completedTime;
protected String notes;
protected String errorMessage;
protected NamedResource initiatedBy;
/**
* @see Task#getOperation
*/
public Builder operation(String operation) {
this.operation = operation;
return this;
}
/**
* @see Task#getStatus
*/
public Builder status(Status status) {
this.status = status;
return this;
}
/**
* @see Task#getImpactedItem
*/
public Builder impactedItem(NamedResource impactedItem) {
this.impactedItem = impactedItem;
return this;
}
/**
* @see Task#getStartTime
*/
public Builder startTime(Date startTime) {
this.startTime = startTime;
return this;
}
/**
* @see Task#getCompletedTime
*/
public Builder completedTime(Date completedTime) {
this.completedTime = completedTime;
return this;
}
/**
* @see Task#getNotes
*/
public Builder notes(String notes) {
this.notes = notes;
return this;
}
/**
* @see Task#getErrorMessage
*/
public Builder errorMessage(String errorMessage) {
this.errorMessage = errorMessage;
return this;
}
/**
* @see Task#getInitiatedBy
*/
public Builder initiatedBy(NamedResource initiatedBy) {
this.initiatedBy = initiatedBy;
return this;
}
@Override
public Task build() {
return new Task(href, type, operation, status, impactedItem, startTime, completedTime, notes, errorMessage,
initiatedBy);
}
public Builder fromTask(Task in) {
return fromResource(in).operation(in.getOperation()).status(in.getStatus()).impactedItem(in.getImpactedItem())
.startTime(in.getStartTime()).completedTime(in.getCompletedTime()).notes(in.getNotes())
.errorMessage(in.getErrorMessage()).initiatedBy(in.getInitiatedBy());
}
/**
* {@inheritDoc}
*/
@Override
public Builder fromResource(BaseResource<Task> in) {
return Builder.class.cast(super.fromResource(in));
}
/**
* {@inheritDoc}
*/
@Override
public Builder type(String type) {
return Builder.class.cast(super.type(type));
}
/**
* {@inheritDoc}
*/
@Override
public Builder href(URI href) {
return Builder.class.cast(super.href(href));
}
/**
* {@inheritDoc}
*/
@Override
public Builder fromAttributes(Map<String, String> attributes) {
return Builder.class.cast(super.fromAttributes(attributes));
}
}
protected final String operation;
protected final Status status;
protected final NamedResource impactedItem;
protected final Date startTime;
protected final Date completedTime;
protected final String notes;
protected final String errorMessage;
protected final NamedResource initiatedBy;
public Task(URI href, String type, String operation, Status status, NamedResource impactedItem, Date startTime,
@Nullable Date completedTime, @Nullable String notes, @Nullable String errorMessage, NamedResource initiatedBy) {
super(href, type);
this.operation = checkNotNull(operation, "operation");
this.status = checkNotNull(status, "status");
this.impactedItem = checkNotNull(impactedItem, "impactedItem");
this.startTime = checkNotNull(startTime, "startTime");
this.completedTime = completedTime;// null if Queued or Running
this.notes = notes;
this.errorMessage = errorMessage;
this.initiatedBy = checkNotNull(initiatedBy, "initiatedBy");
}
/**
*
*
* @return name of action performed
*/
public String getOperation() {
return operation;
}
/**
*
*
* @return the status of the task
*/
public Status getStatus() {
return status;
}
/**
*
* @return the item acted upon
*/
public NamedResource getImpactedItem() {
return impactedItem;
}
/**
*
* @return time action started
*/
public Date getStartTime() {
return startTime;
}
/**
*
* @return time action completed, or null if Queued or Running
*/
@Nullable
public Date getCompletedTime() {
return completedTime;
}
/**
* @return notes on action
*/
public String getNotes() {
return notes;
}
/**
* @return error message
*/
public String getErrorMessage() {
return errorMessage;
}
/**
*
* @return the item acted upon
*/
public NamedResource getInitiatedBy() {
return initiatedBy;
}
@Override
public String toString() {
return "[type=" + type + ", href=" + href + ", operation=" + operation + ", status=" + status + ", impactedItem="
+ impactedItem + ", startTime=" + startTime + ", completedTime=" + completedTime + ", notes=" + notes
+ ", errorMessage=" + errorMessage + ", initiatedBy=" + initiatedBy + "]";
}
}

View File

@ -0,0 +1,114 @@
package org.jclouds.trmk.enterprisecloud.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
/**
* Location of a Rest resource
*
* @author Adrian Cole
*
*/
public class BaseNamedResource<T extends BaseNamedResource<T>> extends BaseResource<T> {
public static <T extends BaseNamedResource<T>> Builder<T> builder() {
return new Builder<T>();
}
public Builder<T> toBuilder() {
return new Builder<T>().fromNamedResource(this);
}
public static class Builder<T extends BaseNamedResource<T>> extends BaseResource.Builder<T> {
protected String name;
/**
* @see BaseNamedResource#getName
*/
public Builder<T> name(String name) {
this.name = name;
return this;
}
public BaseNamedResource<T> build() {
return new BaseNamedResource<T>(href, type, name);
}
public Builder<T> fromNamedResource(BaseNamedResource<T> in) {
return fromResource(in).name(in.getName());
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public Builder<T> fromAttributes(Map<String, String> attributes) {
return Builder.class.cast(super.fromAttributes(attributes)).name(attributes.get("name"));
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public Builder<T> fromResource(BaseResource<T> in) {
return Builder.class.cast(super.fromResource(in));
}
}
protected final String name;
public BaseNamedResource(URI href, String type, String name) {
super(href, type);
this.name = checkNotNull(name, "name");
}
public String getName() {
return name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((href == null) ? 0 : href.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BaseNamedResource<?> other = (BaseNamedResource<?>) obj;
if (href == null) {
if (other.href != null)
return false;
} else if (!href.equals(other.href))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
@Override
public String toString() {
return "[href=" + href + ", name=" + name + ", type=" + type + "]";
}
}

View File

@ -0,0 +1,118 @@
package org.jclouds.trmk.enterprisecloud.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Map;
/**
* Location of a Rest resource
*
* @author Adrian Cole
*
*/
public class BaseResource<T extends BaseResource<T>> {
public static <T extends BaseResource<T>> Builder<T> builder() {
return new Builder<T>();
}
public Builder<T> toBuilder() {
return new Builder<T>().fromResource(this);
}
public static class Builder<T extends BaseResource<T>> {
protected String type;
protected URI href;
/**
* @see BaseResource#getType
*/
public Builder<T> type(String type) {
this.type = type;
return this;
}
/**
* @see BaseResource#getHref
*/
public Builder<T> href(URI href) {
this.href = href;
return this;
}
public BaseResource<T> build() {
return new BaseResource<T>(href, type);
}
public Builder<T> fromResource(BaseResource<T> in) {
return type(in.getType()).href(in.getHref());
}
public Builder<T> fromAttributes(Map<String, String> attributes) {
return href(URI.create(attributes.get("href"))).type(attributes.get("type"));
}
}
protected final String type;
protected final URI href;
public BaseResource(URI href, String type) {
this.type = checkNotNull(type, "type");
this.href = checkNotNull(href, "href");
}
/**
*
* @return type definition, type, expressed as an HTTP Content-Type
*/
public String getType() {
return type;
}
/**
*
* @return an opaque reference and should never be parsed
*/
public URI getHref() {
return href;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((href == null) ? 0 : href.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BaseResource<?> other = (BaseResource<?>) obj;
if (href == null) {
if (other.href != null)
return false;
} else if (!href.equals(other.href))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
return true;
}
@Override
public String toString() {
return "[href=" + href + ", type=" + type + "]";
}
}

View File

@ -0,0 +1,76 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.features;
import java.net.URI;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.XMLResponseParser;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.trmk.enterprisecloud.domain.Task;
import org.jclouds.trmk.enterprisecloud.xml.TaskHandler;
import org.jclouds.trmk.enterprisecloud.xml.TasksHandler;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides asynchronous access to Task via their REST API.
* <p/>
*
* @see TaskClient
* @see <a href=
* "http://support.theenterprisecloud.com/kb/default.asp?id=984&Lang=1&SID="
* />
* @author Adrian Cole
*/
@RequestFilters(BasicAuthentication.class)
@Headers(keys = "x-trmk-version", values = "{jclouds.api-version}")
public interface TaskAsyncClient {
/**
* @see TaskClient#getTasksInEnvironment
*/
@GET
@Path("/tasks/environments/{environmentId}")
@Consumes("application/vnd.tmrk.cloud.task; type=collection")
@XMLResponseParser(TasksHandler.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
ListenableFuture<Set<Task>> getTasksInEnvironment(@PathParam("environmentId") long environmentId);
/**
* @see TaskClient#getTask
*/
@GET
@Consumes("application/vnd.tmrk.cloud.task")
@XMLResponseParser(TaskHandler.class)
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Task> getTask(@EndpointParam URI taskId);
}

View File

@ -0,0 +1,57 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.features;
import java.net.URI;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.trmk.enterprisecloud.domain.Task;
/**
* Provides synchronous access to Task.
* <p/>
*
* @see TaskAsyncClient
* @see <a href=
* "http://support.theenterprisecloud.com/kb/default.asp?id=984&Lang=1&SID="
* />
* @author Adrian Cole
*/
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
public interface TaskClient {
/**
* The Get Tasks call returns information regarding the tasks in an
* environment. The task list is a history of changes to the environment.
*
* @return a history of changes to the environment.
*/
Set<Task> getTasksInEnvironment(long environmentId);
/**
* The Get Tasks by ID call returns information regarding a specified task in
* an environment.
*
* @return the task or null if not found
*/
Task getTask(URI taskId);
}

View File

@ -0,0 +1,92 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.handlers;
import java.io.IOException;
import javax.inject.Singleton;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.util.Strings2;
import com.google.common.base.Throwables;
import com.google.common.io.Closeables;
/**
* This will parse and set an appropriate exception on the command object.
*
* @author Adrian Cole
*
*/
@Singleton
public class TerremarkEnterpriseCloudErrorHandler implements HttpErrorHandler {
public void handleError(HttpCommand command, HttpResponse response) {
// it is important to always read fully and close streams
String message = parseMessage(response);
Exception exception = message != null ? new HttpResponseException(command, response, message)
: new HttpResponseException(command, response);
try {
message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(),
response.getStatusLine());
switch (response.getStatusCode()) {
case 401:
case 403:
exception = new AuthorizationException(message, exception);
break;
case 404:
if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
exception = new ResourceNotFoundException(message, exception);
}
break;
case 409:
exception = new IllegalStateException(message, exception);
case 500:
if (message != null && message.indexOf("Unable to determine package for") != -1) {
exception = new ResourceNotFoundException(message, exception);
}
}
} finally {
if (response.getPayload() != null)
Closeables.closeQuietly(response.getPayload().getInput());
command.setException(exception);
}
}
public String parseMessage(HttpResponse response) {
if (response.getPayload() == null)
return null;
try {
return Strings2.toStringAndClose(response.getPayload().getInput());
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
response.getPayload().getInput().close();
} catch (IOException e) {
Throwables.propagate(e);
}
}
}
}

View File

@ -0,0 +1,100 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.xml;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.util.SaxUtils.currentOrNull;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import java.util.Map;
import javax.inject.Inject;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.trmk.enterprisecloud.domain.NamedResource;
import org.jclouds.trmk.enterprisecloud.domain.Task;
import org.jclouds.util.SaxUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
/**
* @author Adrian Cole
*/
public class TaskHandler extends ParseSax.HandlerWithResult<Task> {
protected final DateService dateService;
protected StringBuilder currentText = new StringBuilder();
protected Task.Builder builder = Task.builder();
@Inject
public TaskHandler(DateService dateService) {
this.dateService = checkNotNull(dateService, "dateService");
}
public Task getResult() {
try {
return builder.build();
} finally {
builder = Task.builder();
}
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
Map<String, String> attributes = SaxUtils.cleanseAttributes(attrs);
if (equalsOrSuffix(qName, "Task")) {
builder.fromAttributes(attributes);
} else if (equalsOrSuffix(qName, "ImpactedItem")) {
builder.impactedItem(NamedResource.builder().fromAttributes(attributes).build());
} else if (equalsOrSuffix(qName, "InitiatedBy")) {
builder.initiatedBy(NamedResource.builder().fromAttributes(attributes).build());
}
}
@Override
public void endElement(String uri, String localName, String qName) {
if (equalsOrSuffix(qName, "Operation")) {
builder.operation(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "Status")) {
String status = currentOrNull(currentText);
if (status != null)
builder.status(Task.Status.fromValue(status));
} else if (equalsOrSuffix(qName, "StartTime")) {
String date = currentOrNull(currentText);
if (date != null)
builder.startTime(dateService.iso8601DateParse(date));
} else if (equalsOrSuffix(qName, "CompletedTime")) {
String date = currentOrNull(currentText);
if (date != null)
builder.completedTime(dateService.iso8601DateParse(date));
} else if (equalsOrSuffix(qName, "Notes")) {
builder.notes(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "ErrorMessage")) {
builder.errorMessage(currentOrNull(currentText));
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1,95 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.xml;
import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import java.util.Set;
import javax.inject.Inject;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.trmk.enterprisecloud.domain.Task;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
/**
* @author Adrian Cole
*/
public class TasksHandler extends ParseSax.HandlerWithResult<Set<Task>> {
public Set<Task> getResult() {
try {
return builder.build();
} finally {
builder = ImmutableSet.<Task> builder();
}
}
protected final TaskHandler taskHandler;
protected Builder<Task> builder = ImmutableSet.<Task> builder();
@Inject
public TasksHandler(TaskHandler taskHandler) {
this.taskHandler = taskHandler;
}
protected boolean inTask;
protected int depth = 0;
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
depth++;
if (depth == 2) {
if (equalsOrSuffix(qName, "Task")) {
inTask = true;
}
}
if (inTask) {
taskHandler.startElement(uri, localName, qName, attrs);
}
}
@Override
public void endElement(String uri, String localName, String qName) {
depth--;
if (depth == 1) {
if (equalsOrSuffix(qName, "Task")) {
inTask = false;
builder.add(taskHandler.getResult());
}
}
if (inTask) {
taskHandler.endElement(uri, localName, qName);
}
}
@Override
public void characters(char ch[], int start, int length) {
if (inTask) {
taskHandler.characters(ch, start, length);
}
}
}

View File

@ -0,0 +1 @@
org.jclouds.trmk.enterprisecloud.TerremarkEnterpriseCloudProviderMetadata

View File

@ -0,0 +1,72 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.trmk.enterprisecloud.features.BaseTerremarkEnterpriseCloudAsyncClientTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code TerremarkEnterpriseCloudAsyncClient}
*
* @author Adrian Cole
*/
// NOTE:without testName, this will not call @Before* and fail w/NPE during
// surefire
@Test(groups = "unit", testName = "TerremarkEnterpriseCloudAsyncClientTest")
public class TerremarkEnterpriseCloudAsyncClientTest extends
BaseTerremarkEnterpriseCloudAsyncClientTest<TerremarkEnterpriseCloudAsyncClient> {
private TerremarkEnterpriseCloudAsyncClient asyncClient;
private TerremarkEnterpriseCloudClient syncClient;
public void testSync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
assert syncClient.getTaskClient() != null;
}
public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
assert asyncClient.getTaskClient() != null;
}
@Override
protected TypeLiteral<RestAnnotationProcessor<TerremarkEnterpriseCloudAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<TerremarkEnterpriseCloudAsyncClient>>() {
};
}
@BeforeClass
@Override
protected void setupFactory() throws IOException {
super.setupFactory();
asyncClient = injector.getInstance(TerremarkEnterpriseCloudAsyncClient.class);
syncClient = injector.getInstance(TerremarkEnterpriseCloudClient.class);
}
@Override
protected void checkFilters(HttpRequest request) {
}
}

View File

@ -0,0 +1,118 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.reportMatcher;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.easymock.classextension.EasyMock.verify;
import java.net.URI;
import org.easymock.IArgumentMatcher;
import org.jclouds.http.HttpCommand;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payloads;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.ResourceNotFoundException;
import org.jclouds.trmk.enterprisecloud.handlers.TerremarkEnterpriseCloudErrorHandler;
import org.jclouds.util.Strings2;
import org.testng.annotations.Test;
import com.google.inject.Guice;
/**
*
* @author Adrian Cole
*/
@Test(groups = { "unit" })
public class TerremarkEnterpriseCloudErrorHandlerTest {
@Test
public void test401MakesAuthorizationException() {
assertCodeMakes("GET", URI.create("https://api.trmk-enterprisecloud.com/foo"), 401, "", "Unauthorized",
AuthorizationException.class);
}
@Test
public void test404MakesResourceNotFoundException() {
assertCodeMakes("GET", URI.create("https://api.trmk-enterprisecloud.com/foo"), 404, "", "Not Found",
ResourceNotFoundException.class);
}
@Test
public void test409AlreadyExists4MakesIllegalStateExceptionException() {
assertCodeMakes(
"GET",
URI.create("https://api.trmk-enterprisecloud.com/foo"),
409,
"",
"<Error message=\"Catalog item with that name already exists.\" majorErrorCode=\"409\" minorErrorCode=\"CatalogItemAlreadyExists\"/>",
IllegalStateException.class);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content,
Class<? extends Exception> expected) {
assertCodeMakes(method, uri, statusCode, message, "text/xml", content, expected);
}
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
String content, Class<? extends Exception> expected) {
TerremarkEnterpriseCloudErrorHandler function = Guice.createInjector().getInstance(
TerremarkEnterpriseCloudErrorHandler.class);
HttpCommand command = createMock(HttpCommand.class);
HttpRequest request = new HttpRequest(method, uri);
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Strings2
.toInputStream(content)));
response.getPayload().getContentMetadata().setContentType(contentType);
expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
command.setException(classEq(expected));
replay(command);
function.handleError(command, response);
verify(command);
}
public static Exception classEq(final Class<? extends Exception> in) {
reportMatcher(new IArgumentMatcher() {
@Override
public void appendTo(StringBuffer buffer) {
buffer.append("classEq(");
buffer.append(in);
buffer.append(")");
}
@Override
public boolean matches(Object arg) {
return arg.getClass() == in;
}
});
return null;
}
}

View File

@ -0,0 +1,35 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud;
import org.jclouds.providers.BaseProviderMetadataTest;
import org.jclouds.providers.ProviderMetadata;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "TerremarkEnterpriseCloudProviderTest")
public class TerremarkEnterpriseCloudProviderTest extends BaseProviderMetadataTest {
public TerremarkEnterpriseCloudProviderTest() {
super(new TerremarkEnterpriseCloudProviderMetadata(), ProviderMetadata.COMPUTE_TYPE);
}
}

View File

@ -0,0 +1,50 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.features;
import static org.testng.Assert.assertEquals;
import java.util.Properties;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.rest.RestContextSpec;
import org.jclouds.trmk.enterprisecloud.TerremarkEnterpriseCloudAsyncClient;
import org.jclouds.trmk.enterprisecloud.TerremarkEnterpriseCloudClient;
/**
* @author Adrian Cole
*/
public abstract class BaseTerremarkEnterpriseCloudAsyncClientTest<T> extends RestClientTest<T> {
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);
assertEquals(request.getFilters().get(0).getClass(), BasicAuthentication.class);
}
@Override
public RestContextSpec<TerremarkEnterpriseCloudClient, TerremarkEnterpriseCloudAsyncClient> createContextSpec() {
Properties props = new Properties();
return new RestContextFactory().createContextSpec("trmk-enterprisecloud", "apiKey", "secretKey", props);
}
}

View File

@ -0,0 +1,65 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.features;
import java.util.Properties;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.jclouds.trmk.enterprisecloud.TerremarkEnterpriseCloudAsyncClient;
import org.jclouds.trmk.enterprisecloud.TerremarkEnterpriseCloudClient;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
* Tests behavior of {@code TerremarkEnterpriseCloudClient}
*
* @author Adrian Cole
*/
@Test(groups = "live")
public class BaseTerremarkEnterpriseCloudClientLiveTest {
protected RestContext<TerremarkEnterpriseCloudClient, TerremarkEnterpriseCloudAsyncClient> context;
protected Module module;
@BeforeGroups(groups = { "live" })
public void setupClient() {
// TODO organize this like other compute tests
String identity = System.getProperty("test.trmk-enterprisecloud.identity", "readonly@terremark.com");
String credential = System.getProperty("test.trmk-enterprisecloud.credential", "T3rr3m@rk");
Properties props = new Properties();
context = new RestContextFactory().createContext("trmk-enterprisecloud", identity, credential,
ImmutableSet.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()), props);
}
@AfterGroups(groups = "live")
protected void tearDown() {
if (context != null)
context.close();
}
}

View File

@ -0,0 +1,82 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.features;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.trmk.enterprisecloud.xml.TaskHandler;
import org.jclouds.trmk.enterprisecloud.xml.TasksHandler;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests annotation parsing of {@code TaskAsyncClient}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "TaskAsyncClientTest")
public class TaskAsyncClientTest extends BaseTerremarkEnterpriseCloudAsyncClientTest<TaskAsyncClient> {
public void testGetTasksInEnvironment() throws SecurityException, NoSuchMethodException, IOException {
Method method = TaskAsyncClient.class.getMethod("getTasksInEnvironment", long.class);
HttpRequest httpRequest = processor.createRequest(method, 1l);
assertRequestLineEquals(httpRequest, "GET http://209.251.187.125/livespec/tasks/environments/1 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest,
"Accept: application/vnd.tmrk.cloud.task; type=collection\nx-trmk-version: 2011-07-01\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseSax.class);
assertSaxResponseParserClassEquals(method, TasksHandler.class);
assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class);
checkFilters(httpRequest);
}
public void testGetTask() throws SecurityException, NoSuchMethodException, IOException {
Method method = TaskAsyncClient.class.getMethod("getTask", URI.class);
HttpRequest httpRequest = processor.createRequest(method, URI.create("http://209.251.187.125/livespec/tasks/1"));
assertRequestLineEquals(httpRequest, "GET http://209.251.187.125/livespec/tasks/1 HTTP/1.1");
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/vnd.tmrk.cloud.task\nx-trmk-version: 2011-07-01\n");
assertPayloadEquals(httpRequest, null, null, false);
assertResponseParserClassEquals(method, httpRequest, ParseSax.class);
assertSaxResponseParserClassEquals(method, TaskHandler.class);
assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class);
checkFilters(httpRequest);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<TaskAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<TaskAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,59 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.features;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Set;
import org.jclouds.trmk.enterprisecloud.domain.Task;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code TaskClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "TaskClientLiveTest")
public class TaskClientLiveTest extends BaseTerremarkEnterpriseCloudClientLiveTest {
@BeforeGroups(groups = { "live" })
public void setupClient() {
super.setupClient();
client = context.getApi().getTaskClient();
}
private TaskClient client;
@Test
public void testGetTasks() {
// TODO: don't hard-code id
// TODO: docs say don't parse the href, yet no xml includes "identifier",
// I suspect we may need to change to URI args as opposed to long
Set<Task> response = client.getTasksInEnvironment(1);
assert null != response;
assertTrue(response.size() >= 0);
for (Task task : response) {
assertEquals(client.getTask(task.getHref()), task);
assert task.getStatus() != Task.Status.UNRECOGNIZED : response;
}
}
}

View File

@ -0,0 +1,69 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.xml;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.net.URI;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseSax.Factory;
import org.jclouds.http.functions.config.SaxParserModule;
import org.jclouds.trmk.enterprisecloud.domain.NamedResource;
import org.jclouds.trmk.enterprisecloud.domain.Task;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code TaskHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "TaskHandlerTest")
public class TaskHandlerTest {
static SimpleDateFormatDateService dateService = new SimpleDateFormatDateService();
static Task expected = Task
.builder()
.href(URI.create("/livespec/tasks/1002"))
.type("application/vnd.tmrk.cloud.task")
.operation("Add Node Service")
.status(Task.Status.ERROR)
.impactedItem(
NamedResource.builder().href(URI.create("/livespec/nodeservices/1")).name("sample node internet 1")
.type("application/vnd.tmrk.cloud.nodeService").build())
.startTime(dateService.iso8601DateParse("2011-11-07T11:19:13.38225Z"))
.completedTime(dateService.iso8601DateParse("2011-11-07T11:20:13.38225Z"))
.notes("Some notes about the operation.")
.errorMessage("sample error message 1 here")
.initiatedBy(
NamedResource.builder().href(URI.create("/livespec/admin/users/1")).name("User 1")
.type("application/vnd.tmrk.cloud.admin.user").build()).build();
public void test() {
InputStream is = getClass().getResourceAsStream("/task.xml");
Injector injector = Guice.createInjector(new SaxParserModule());
Factory factory = injector.getInstance(ParseSax.Factory.class);
Task result = factory.create(injector.getInstance(TaskHandler.class)).parse(is);
assertEquals(result.toString(), expected.toString());
}
}

View File

@ -0,0 +1,55 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.trmk.enterprisecloud.xml;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import java.util.Set;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseSax.Factory;
import org.jclouds.http.functions.config.SaxParserModule;
import org.jclouds.trmk.enterprisecloud.domain.Task;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* Tests behavior of {@code TasksHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "TasksHandlerTest")
public class TasksHandlerTest {
public void test() {
InputStream is = getClass().getResourceAsStream("/tasks.xml");
Injector injector = Guice.createInjector(new SaxParserModule());
Factory factory = injector.getInstance(ParseSax.Factory.class);
Set<Task> result = factory.create(injector.getInstance(TasksHandler.class)).parse(is);
Set<Task> expected = ImmutableSet.of(TaskHandlerTest.expected);
assertEquals(result.toString(), expected.toString());
}
}

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<!-- A time/date based rolling appender -->
<appender name="SSHFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-ssh.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="ASYNCSSH" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="SSHFILE" />
</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.ssh">
<priority value="DEBUG" />
<appender-ref ref="ASYNCSSH" />
</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>

View File

@ -0,0 +1,10 @@
<Task href="/livespec/tasks/1002" type="application/vnd.tmrk.cloud.task">
<Operation>Add Node Service</Operation>
<Status>Error</Status>
<ImpactedItem href="/livespec/nodeservices/1" name="sample node internet 1" type="application/vnd.tmrk.cloud.nodeService"/>
<StartTime>2011-11-07T11:19:13.38225Z</StartTime>
<CompletedTime>2011-11-07T11:20:13.38225Z</CompletedTime>
<Notes>Some notes about the operation.</Notes>
<ErrorMessage>sample error message 1 here</ErrorMessage>
<InitiatedBy href="/livespec/admin/users/1" name="User 1" type="application/vnd.tmrk.cloud.admin.user"/>
</Task>

View File

@ -0,0 +1,12 @@
<Tasks href="/livespec/tasks/environments/1" type="application/vnd.tmrk.cloud.task; type=collection">
<Task href="/livespec/tasks/1002" type="application/vnd.tmrk.cloud.task">
<Operation>Add Node Service</Operation>
<Status>Error</Status>
<ImpactedItem href="/livespec/nodeservices/1" name="sample node internet 1" type="application/vnd.tmrk.cloud.nodeService"/>
<StartTime>2011-11-07T11:19:13.38225Z</StartTime>
<CompletedTime>2011-11-07T11:20:13.38225Z</CompletedTime>
<Notes>Some notes about the operation.</Notes>
<ErrorMessage>sample error message 1 here</ErrorMessage>
<InitiatedBy href="/livespec/admin/users/1" name="User 1" type="application/vnd.tmrk.cloud.admin.user"/>
</Task>
</Tasks>