Issue 955:introduce NodeMetadata/Image.backendStatus

This commit is contained in:
Adrian Cole 2012-06-04 12:50:54 -07:00
parent 7203286a90
commit 9bf92e0403
17 changed files with 164 additions and 161 deletions

View File

@ -18,6 +18,7 @@
*/ */
package org.jclouds.tools.ant.taskdefs.compute; package org.jclouds.tools.ant.taskdefs.compute;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.buildComputeMap; import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.buildComputeMap;
import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.createTemplateFromElement; import static org.jclouds.tools.ant.taskdefs.compute.ComputeTaskUtils.createTemplateFromElement;
@ -253,8 +254,7 @@ public class ComputeTask extends Task {
NodeMetadata metadata = node instanceof NodeMetadata ? NodeMetadata.class.cast(node) : computeService NodeMetadata metadata = node instanceof NodeMetadata ? NodeMetadata.class.cast(node) : computeService
.getNodeMetadata(node.getId()); .getNodeMetadata(node.getId());
log(String.format(" node id=%s, name=%s, group=%s, location=%s, state=%s, publicIp=%s, privateIp=%s, hardware=%s", log(String.format(" node id=%s, name=%s, group=%s, location=%s, state=%s, publicIp=%s, privateIp=%s, hardware=%s",
metadata.getProviderId(), metadata.getName(), metadata.getGroup(), metadata.getLocation(), metadata metadata.getProviderId(), metadata.getName(), metadata.getGroup(), metadata.getLocation(), formatStatus(metadata), ComputeTaskUtils.ipOrEmptyString(metadata.getPublicAddresses()),
.getState(), ComputeTaskUtils.ipOrEmptyString(metadata.getPublicAddresses()),
ipOrEmptyString(metadata.getPrivateAddresses()), metadata.getHardware())); ipOrEmptyString(metadata.getPrivateAddresses()), metadata.getHardware()));
} }

View File

@ -18,15 +18,26 @@
*/ */
package org.jclouds.compute.domain; package org.jclouds.compute.domain;
import org.jclouds.javax.annotation.Nullable;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
public interface ComputeMetadataIncludingStatus<S extends Enum<S>> extends ComputeMetadata { public interface ComputeMetadataIncludingStatus<S extends Enum<S>> extends ComputeMetadata {
/** /**
* status of the resource * portable status of the resource
*
* @since 1.5 * @since 1.5
*/ */
public S getStatus(); public S getStatus();
/**
* status of the resource, as supplied literally from the backend api.
*
* @return status or null, if the backend api has no concept of status
* @since 1.5
*/
@Nullable
public String getBackendStatus();
} }

View File

@ -35,6 +35,7 @@ import org.jclouds.javax.annotation.Nullable;
public class ImageBuilder extends ComputeMetadataBuilder { public class ImageBuilder extends ComputeMetadataBuilder {
private OperatingSystem operatingSystem; private OperatingSystem operatingSystem;
private Status status; private Status status;
private String backendStatus;
private String version; private String version;
private String description; private String description;
private LoginCredentials defaultLoginCredentials; private LoginCredentials defaultLoginCredentials;
@ -53,6 +54,11 @@ public class ImageBuilder extends ComputeMetadataBuilder {
return this; return this;
} }
public ImageBuilder backendStatus(@Nullable String backendStatus) {
this.backendStatus = backendStatus;
return this;
}
public ImageBuilder version(@Nullable String version) { public ImageBuilder version(@Nullable String version) {
this.version = version; this.version = version;
return this; return this;
@ -110,14 +116,14 @@ public class ImageBuilder extends ComputeMetadataBuilder {
@Override @Override
public Image build() { public Image build() {
return new ImageImpl(providerId, name, id, location, uri, userMetadata, tags, operatingSystem, status, return new ImageImpl(providerId, name, id, location, uri, userMetadata, tags, operatingSystem, status,
description, version, defaultLoginCredentials); backendStatus, description, version, defaultLoginCredentials);
} }
public static ImageBuilder fromImage(Image image) { public static ImageBuilder fromImage(Image image) {
return new ImageBuilder().providerId(image.getProviderId()).name(image.getName()).id(image.getId()) return new ImageBuilder().providerId(image.getProviderId()).name(image.getName()).id(image.getId()).location(
.location(image.getLocation()).uri(image.getUri()).userMetadata(image.getUserMetadata()) image.getLocation()).uri(image.getUri()).userMetadata(image.getUserMetadata()).tags(image.getTags())
.tags(image.getTags()).version(image.getVersion()).description(image.getDescription()) .version(image.getVersion()).description(image.getDescription()).operatingSystem(
.operatingSystem(image.getOperatingSystem()).status(image.getStatus()) image.getOperatingSystem()).status(image.getStatus()).backendStatus(image.getBackendStatus())
.defaultCredentials(image.getDefaultCredentials()); .defaultCredentials(image.getDefaultCredentials());
} }

View File

@ -38,6 +38,7 @@ import com.google.common.collect.Sets;
*/ */
public class NodeMetadataBuilder extends ComputeMetadataBuilder { public class NodeMetadataBuilder extends ComputeMetadataBuilder {
private Status status; private Status status;
private String backendStatus;
private Set<String> publicAddresses = Sets.newLinkedHashSet(); private Set<String> publicAddresses = Sets.newLinkedHashSet();
private Set<String> privateAddresses = Sets.newLinkedHashSet(); private Set<String> privateAddresses = Sets.newLinkedHashSet();
@Nullable @Nullable
@ -68,6 +69,11 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
return this; return this;
} }
public NodeMetadataBuilder backendStatus(@Nullable String backendStatus) {
this.backendStatus = backendStatus;
return this;
}
/** /**
* <h3>Note</h3> * <h3>Note</h3>
* will be removed in jclouds 1.6! * will be removed in jclouds 1.6!
@ -162,15 +168,16 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder {
@Override @Override
public NodeMetadata build() { public NodeMetadata build() {
return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, tags, group, hardware, imageId, return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, tags, group, hardware, imageId,
os, status, loginPort, publicAddresses, privateAddresses, credentials, hostname); os, status, backendStatus, loginPort, publicAddresses, privateAddresses, credentials, hostname);
} }
public static NodeMetadataBuilder fromNodeMetadata(NodeMetadata node) { public static NodeMetadataBuilder fromNodeMetadata(NodeMetadata node) {
return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId()).location( return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId()).location(
node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).tags(node.getTags()).group( node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).tags(node.getTags()).group(
node.getGroup()).hardware(node.getHardware()).imageId(node.getImageId()).operatingSystem( node.getGroup()).hardware(node.getHardware()).imageId(node.getImageId()).operatingSystem(
node.getOperatingSystem()).status(node.getStatus()).loginPort(node.getLoginPort()).publicAddresses( node.getOperatingSystem()).status(node.getStatus()).backendStatus(node.getBackendStatus()).loginPort(
node.getPublicAddresses()).privateAddresses(node.getPrivateAddresses()).credentials(node.getCredentials()).hostname(node.getHostname()); node.getLoginPort()).publicAddresses(node.getPublicAddresses()).privateAddresses(
node.getPrivateAddresses()).credentials(node.getCredentials()).hostname(node.getHostname());
} }
} }

View File

@ -84,8 +84,12 @@ public class ComputeMetadataImpl extends ResourceMetadataImpl<ComputeType> imple
if (o == null || getClass() != o.getClass()) if (o == null || getClass() != o.getClass())
return false; return false;
ComputeMetadataImpl that = ComputeMetadataImpl.class.cast(o); ComputeMetadataImpl that = ComputeMetadataImpl.class.cast(o);
return super.equals(that) && return super.equals(that) && equal(this.id, that.id);
equal(this.id, that.id); }
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), id);
} }
protected ToStringHelper string() { protected ToStringHelper string() {

View File

@ -19,6 +19,7 @@
package org.jclouds.compute.domain.internal; package org.jclouds.compute.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
@ -31,6 +32,9 @@ import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials; import org.jclouds.domain.LoginCredentials;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
@ -41,17 +45,19 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
private final OperatingSystem operatingSystem; private final OperatingSystem operatingSystem;
private final Status status; private final Status status;
private final String backendStatus;
private final String version; private final String version;
private final String description; private final String description;
private final LoginCredentials defaultCredentials; private final LoginCredentials defaultCredentials;
public ImageImpl(String providerId, String name, String id, Location location, URI uri, public ImageImpl(String providerId, String name, String id, Location location, URI uri,
Map<String, String> userMetadata, Set<String> tags, OperatingSystem operatingSystem, Image.Status status, String description, Map<String, String> userMetadata, Set<String> tags, OperatingSystem operatingSystem, Image.Status status,
@Nullable String version, @Nullable LoginCredentials defaultCredentials) { @Nullable String backendStatus, String description, @Nullable String version,
@Nullable LoginCredentials defaultCredentials) {
super(ComputeType.IMAGE, providerId, name, id, location, uri, userMetadata, tags); super(ComputeType.IMAGE, providerId, name, id, location, uri, userMetadata, tags);
this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem"); this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem");
this.status = checkNotNull(status, "status"); this.status = checkNotNull(status, "status");
this.backendStatus = backendStatus;
this.version = version; this.version = version;
this.description = checkNotNull(description, "description"); this.description = checkNotNull(description, "description");
this.defaultCredentials = defaultCredentials; this.defaultCredentials = defaultCredentials;
@ -73,6 +79,14 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
return status; return status;
} }
/**
* {@inheritDoc}
*/
@Override
public String getBackendStatus() {
return backendStatus;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -107,57 +121,14 @@ public class ImageImpl extends ComputeMetadataImpl implements Image {
.getPassword() : null; .getPassword() : null;
} }
@Override // equals and toString from super are sufficient to establish identity equivalence
public String toString() {
return "[id=" + getId() + ", name=" + getName() + ", operatingSystem=" + operatingSystem + ", description=" protected ToStringHelper string() {
+ description + ", version=" + version + ", location=" + getLocation() + ", loginUser=" return Objects.toStringHelper("").add("id", getId()).add("providerId", getProviderId()).add("name", getName())
+ ((defaultCredentials != null) ? defaultCredentials.identity : null) + ", userMetadata=" .add("os", getOperatingSystem()).add("description", getDescription()).add("version", getVersion()).add(
+ getUserMetadata() + ", tags=" + tags + "]"; "location", getLocation()).add("status", formatStatus(this)).add("loginUser",
((defaultCredentials != null) ? defaultCredentials.identity : null)).add("tags", getTags())
.add("userMetadata", getUserMetadata());
} }
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((defaultCredentials == null) ? 0 : defaultCredentials.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
ImageImpl other = (ImageImpl) obj;
if (defaultCredentials == null) {
if (other.defaultCredentials != null)
return false;
} else if (!defaultCredentials.equals(other.defaultCredentials))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
} }

View File

@ -19,6 +19,7 @@
package org.jclouds.compute.domain.internal; package org.jclouds.compute.domain.internal;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
@ -32,6 +33,8 @@ import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials; import org.jclouds.domain.LoginCredentials;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
/** /**
@ -44,6 +47,7 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
private static final long serialVersionUID = 7924307572338157887L; private static final long serialVersionUID = 7924307572338157887L;
private final Status status; private final Status status;
private final String backendStatus;
private final int loginPort; private final int loginPort;
private final Set<String> publicAddresses; private final Set<String> publicAddresses;
private final Set<String> privateAddresses; private final Set<String> privateAddresses;
@ -62,15 +66,16 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri, public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri,
Map<String, String> userMetadata, Set<String> tags, @Nullable String group, @Nullable Hardware hardware, Map<String, String> userMetadata, Set<String> tags, @Nullable String group, @Nullable Hardware hardware,
@Nullable String imageId, @Nullable OperatingSystem os, Status status, int loginPort, @Nullable String imageId, @Nullable OperatingSystem os, Status status, @Nullable String backendStatus,
Iterable<String> publicAddresses, Iterable<String> privateAddresses, @Nullable LoginCredentials credentials, int loginPort, Iterable<String> publicAddresses, Iterable<String> privateAddresses,
String hostname) { @Nullable LoginCredentials credentials, String hostname) {
super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata, tags); super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata, tags);
this.group = group; this.group = group;
this.hardware = hardware; this.hardware = hardware;
this.imageId = imageId; this.imageId = imageId;
this.os = os; this.os = os;
this.status = checkNotNull(status, "status"); this.status = checkNotNull(status, "status");
this.backendStatus = backendStatus;
this.loginPort = loginPort; this.loginPort = loginPort;
this.publicAddresses = ImmutableSet.copyOf(checkNotNull(publicAddresses, "publicAddresses")); this.publicAddresses = ImmutableSet.copyOf(checkNotNull(publicAddresses, "publicAddresses"));
this.privateAddresses = ImmutableSet.copyOf(checkNotNull(privateAddresses, "privateAddresses")); this.privateAddresses = ImmutableSet.copyOf(checkNotNull(privateAddresses, "privateAddresses"));
@ -144,6 +149,14 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
return status; return status;
} }
/**
* {@inheritDoc}
*/
@Override
public String getBackendStatus() {
return backendStatus;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -176,78 +189,16 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat
return hostname; return hostname;
} }
@Override
public String toString() {
return "[id=" + getId() + ", providerId=" + getProviderId() + ", group=" + getGroup() + ", name=" + getName()
+ ", location=" + getLocation() + ", uri=" + getUri() + ", imageId=" + getImageId() + ", os="
+ getOperatingSystem() + ", status=" + getStatus() + ", loginPort=" + getLoginPort() + ", hostname="
+ getHostname() + ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses
+ ", hardware=" + getHardware() + ", loginUser=" + ((credentials != null) ? credentials.identity : null)
+ ", userMetadata=" + getUserMetadata() + ", tags=" + tags + "]";
}
@Override // equals and toString from super are sufficient to establish identity equivalence
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + loginPort;
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
result = prime * result + ((group == null) ? 0 : group.hashCode());
result = prime * result + ((hostname == null) ? 0 : hostname.hashCode());
result = prime * result + ((imageId == null) ? 0 : imageId.hashCode());
result = prime * result + ((hardware == null) ? 0 : hardware.hashCode());
result = prime * result + ((os == null) ? 0 : os.hashCode());
return result;
}
@Override protected ToStringHelper string() {
public boolean equals(Object obj) { return Objects.toStringHelper("").add("id", getId()).add("providerId", getProviderId()).add("group", getGroup())
if (this == obj) .add("name", getName()).add("location", getLocation()).add("uri", getUri()).add("imageId", getImageId())
return true; .add("os", getOperatingSystem()).add("status", formatStatus(this)).add("loginPort", getLoginPort()).add(
if (!super.equals(obj)) "hostname", getHostname()).add("privateAddresses", getPrivateAddresses()).add(
return false; "publicAddresses", getPublicAddresses()).add("hardware", getHardware()).add("loginUser",
if (getClass() != obj.getClass()) ((credentials != null) ? credentials.identity : null)).add("tags", getTags()).add(
return false; "userMetadata", getUserMetadata());
NodeMetadataImpl other = (NodeMetadataImpl) obj;
if (loginPort != other.loginPort)
return false;
if (privateAddresses == null) {
if (other.privateAddresses != null)
return false;
} else if (!privateAddresses.equals(other.privateAddresses))
return false;
if (publicAddresses == null) {
if (other.publicAddresses != null)
return false;
} else if (!publicAddresses.equals(other.publicAddresses))
return false;
if (hostname == null) {
if (other.hostname != null)
return false;
} else if (!hostname.equals(other.hostname))
return false;
if (group == null) {
if (other.group != null)
return false;
} else if (!group.equals(other.group))
return false;
if (imageId == null) {
if (other.imageId != null)
return false;
} else if (!imageId.equals(other.imageId))
return false;
if (hardware == null) {
if (other.hardware != null)
return false;
} else if (!hardware.equals(other.hardware))
return false;
if (os == null) {
if (other.os != null)
return false;
} else if (!os.equals(other.os))
return false;
return true;
} }
} }

View File

@ -29,6 +29,7 @@ import static com.google.common.collect.Sets.newLinkedHashSet;
import static com.google.common.util.concurrent.Futures.immediateFuture; import static com.google.common.util.concurrent.Futures.immediateFuture;
import static org.jclouds.compute.predicates.NodePredicates.TERMINATED; import static org.jclouds.compute.predicates.NodePredicates.TERMINATED;
import static org.jclouds.compute.predicates.NodePredicates.all; import static org.jclouds.compute.predicates.NodePredicates.all;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import static org.jclouds.concurrent.FutureIterables.awaitCompletion; import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
import static org.jclouds.concurrent.FutureIterables.transformParallel; import static org.jclouds.concurrent.FutureIterables.transformParallel;
@ -578,7 +579,7 @@ public class BaseComputeService implements ComputeService {
throw new NoSuchElementException(id); throw new NoSuchElementException(id);
if (node.getStatus() != Status.RUNNING) if (node.getStatus() != Status.RUNNING)
throw new IllegalStateException("node " + id throw new IllegalStateException("node " + id
+ " needs to be running before executing a script on it. current state: " + node.getStatus()); + " needs to be running before executing a script on it. current state: " + formatStatus(node));
initAdminAccess.visit(runScript); initAdminAccess.visit(runScript);
node = updateNodeWithCredentialsIfPresent(node, options); node = updateNodeWithCredentialsIfPresent(node, options);
ExecResponse response = runScriptOnNodeFactory.create(node, runScript, options).init().call(); ExecResponse response = runScriptOnNodeFactory.create(node, runScript, options).init().call();
@ -597,7 +598,7 @@ public class BaseComputeService implements ComputeService {
throw new NoSuchElementException(id); throw new NoSuchElementException(id);
if (node.getStatus() != Status.RUNNING) if (node.getStatus() != Status.RUNNING)
throw new IllegalStateException("node " + id throw new IllegalStateException("node " + id
+ " needs to be running before executing a script on it. current state: " + node.getStatus()); + " needs to be running before executing a script on it. current state: " + formatStatus(node));
initAdminAccess.visit(runScript); initAdminAccess.visit(runScript);
final NodeMetadata node1 = updateNodeWithCredentialsIfPresent(node, options); final NodeMetadata node1 = updateNodeWithCredentialsIfPresent(node, options);
ListenableFuture<ExecResponse> response = runScriptOnNodeFactory.submit(node1, runScript, options); ListenableFuture<ExecResponse> response = runScriptOnNodeFactory.submit(node1, runScript, options);

View File

@ -19,6 +19,7 @@
package org.jclouds.compute.predicates.internal; package org.jclouds.compute.predicates.internal;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@ -66,10 +67,10 @@ public abstract class RefreshAndDoubleCheckOnFailUnlessStatusInvalid<S extends E
public boolean checkStatus(C resource) { public boolean checkStatus(C resource) {
if (resource == null) if (resource == null)
return false; return false;
logger.trace("%s: looking for resource state %s: currently: %s", resource.getId(), intended, resource.getStatus()); logger.trace("%s: looking for resource state %s: currently: %s", resource.getId(), intended, formatStatus(resource));
if (invalids.contains(resource.getStatus())) if (invalids.contains(resource.getStatus()))
throw new IllegalStateException("resource " + resource.getId() + " in location " + resource.getLocation() throw new IllegalStateException("resource " + resource.getId() + " in location " + resource.getLocation()
+ " is in invalid status " + resource.getStatus()); + " is in invalid status " + formatStatus(resource));
return resource.getStatus() == intended; return resource.getStatus() == intended;
} }

View File

@ -19,6 +19,7 @@
package org.jclouds.compute.predicates.internal; package org.jclouds.compute.predicates.internal;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@ -57,8 +58,7 @@ public abstract class TrueIfNullOrDeletedRefreshAndDoubleCheckOnFalse<S extends
public boolean checkStatus(C resource) { public boolean checkStatus(C resource) {
if (resource == null) if (resource == null)
return true; return true;
logger.trace("%s: looking for resource status %s: currently: %s", resource.getId(), deletedStatus, resource logger.trace("%s: looking for resource status %s: currently: %s", resource.getId(), deletedStatus, formatStatus(resource));
.getStatus());
return resource.getStatus() == deletedStatus; return resource.getStatus() == deletedStatus;
} }

View File

@ -22,6 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Throwables.getRootCause; import static com.google.common.base.Throwables.getRootCause;
import static java.lang.String.format; import static java.lang.String.format;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -141,12 +142,12 @@ public class CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap implements Cal
throw new IllegalStateException( throw new IllegalStateException(
format( format(
"node(%s) didn't achieve the status running, so we couldn't customize; aborting prematurely after %d seconds with final status: %s", "node(%s) didn't achieve the status running, so we couldn't customize; aborting prematurely after %d seconds with final status: %s",
originalId, timeWaited / 1000, node.get().getStatus())); originalId, timeWaited / 1000, formatStatus(node.get())));
} else { } else {
throw new IllegalStateException( throw new IllegalStateException(
format( format(
"node(%s) didn't achieve the status running within %d seconds, so we couldn't customize; final status: %s", "node(%s) didn't achieve the status running within %d seconds, so we couldn't customize; final status: %s",
originalId, timeouts.nodeRunning / 1000, node.get().getStatus())); originalId, timeouts.nodeRunning / 1000, formatStatus(node.get())));
} }
} }
} catch (IllegalStateException e) { } catch (IllegalStateException e) {

View File

@ -20,6 +20,7 @@ package org.jclouds.compute.strategy.impl;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import java.util.Map; import java.util.Map;
@ -127,7 +128,8 @@ public class AdaptingComputeServiceStrategies<N, H, I, L> implements CreateNodeW
} }
private void checkStateAvailable(NodeMetadata node) { private void checkStateAvailable(NodeMetadata node) {
checkState(node != null && node.getStatus() != Status.TERMINATED, "node %s terminated or unavailable!", node); checkState(node != null && node.getStatus() != Status.TERMINATED,
"node %s terminated or unavailable! current status: %s", node, formatStatus(node));
} }
@Override @Override

View File

@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.any; import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Maps.newLinkedHashMap; import static com.google.common.collect.Maps.newLinkedHashMap;
import static com.google.common.collect.Sets.newLinkedHashSet; import static com.google.common.collect.Sets.newLinkedHashSet;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import static org.jclouds.concurrent.Futures.compose; import static org.jclouds.concurrent.Futures.compose;
import java.util.Map; import java.util.Map;
@ -79,7 +80,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNo
logger.debug(">> adding node location(%s) name(%s) image(%s) hardware(%s)", template.getLocation().getId(), logger.debug(">> adding node location(%s) name(%s) image(%s) hardware(%s)", template.getLocation().getId(),
name, template.getImage().getProviderId(), template.getHardware().getProviderId()); name, template.getImage().getProviderId(), template.getHardware().getProviderId());
node = addNodeWithGroupStrategy.createNodeWithGroupEncodedIntoName(group, name, template); node = addNodeWithGroupStrategy.createNodeWithGroupEncodedIntoName(group, name, template);
logger.debug("<< %s node(%s)", node.getStatus(), node.getId()); logger.debug("<< %s node(%s)", formatStatus(node), node.getId());
return new AtomicReference<NodeMetadata>(node); return new AtomicReference<NodeMetadata>(node);
} }

View File

@ -18,6 +18,8 @@
*/ */
package org.jclouds.compute.stub.config; package org.jclouds.compute.stub.config;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -211,7 +213,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
if (node.getStatus() == Status.RUNNING) if (node.getStatus() == Status.RUNNING)
return; return;
if (node.getStatus() != Status.SUSPENDED) if (node.getStatus() != Status.SUSPENDED)
throw new IllegalStateException("to resume a node, it must be in suspended status, not: " + node.getStatus()); throw new IllegalStateException("to resume a node, it must be in suspended status, not: " + formatStatus(node));
setStateOnNode(Status.PENDING, node); setStateOnNode(Status.PENDING, node);
setStateOnNodeAfterDelay(Status.RUNNING, node, 50); setStateOnNodeAfterDelay(Status.RUNNING, node, 50);
} }
@ -224,7 +226,7 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
if (node.getStatus() == Status.SUSPENDED) if (node.getStatus() == Status.SUSPENDED)
return; return;
if (node.getStatus() != Status.RUNNING) if (node.getStatus() != Status.RUNNING)
throw new IllegalStateException("to suspend a node, it must be in running status, not: " + node.getStatus()); throw new IllegalStateException("to suspend a node, it must be in running status, not: " + formatStatus(node));
setStateOnNode(Status.PENDING, node); setStateOnNode(Status.PENDING, node);
setStateOnNodeAfterDelay(Status.SUSPENDED, node, 50); setStateOnNodeAfterDelay(Status.SUSPENDED, node, 50);
} }

View File

@ -34,6 +34,7 @@ import java.util.regex.Pattern;
import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeMetadataIncludingStatus;
import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.NodeMetadataBuilder;
@ -58,6 +59,16 @@ import com.google.common.reflect.TypeToken;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class ComputeServiceUtils { public class ComputeServiceUtils {
/**
* status as a string which optionally includes the backend status
*/
public static String formatStatus(ComputeMetadataIncludingStatus<?> resource) {
if (resource.getBackendStatus() == null)
return resource.getStatus().toString();
return String.format("%s[%s]", resource.getStatus(), resource.getBackendStatus());
}
public static final Pattern DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX = Pattern.compile("(.+)-[0-9a-f]+"); public static final Pattern DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX = Pattern.compile("(.+)-[0-9a-f]+");
/** /**

View File

@ -134,6 +134,7 @@ public class AtomicNodePredicatesTest {
@Test @Test
public void testNodeRunningReturnsTrueWhenRunning() { public void testNodeRunningReturnsTrueWhenRunning() {
expect(node.getStatus()).andReturn(Status.RUNNING).atLeastOnce(); expect(node.getStatus()).andReturn(Status.RUNNING).atLeastOnce();
expect(node.getBackendStatus()).andReturn(null).atLeastOnce();
replay(node); replay(node);
replay(computeService); replay(computeService);
@ -146,6 +147,7 @@ public class AtomicNodePredicatesTest {
@Test(expectedExceptions = IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void testNodeRunningFailsOnTerminated() { public void testNodeRunningFailsOnTerminated() {
expect(node.getStatus()).andReturn(Status.TERMINATED).atLeastOnce(); expect(node.getStatus()).andReturn(Status.TERMINATED).atLeastOnce();
expect(node.getBackendStatus()).andReturn(null).atLeastOnce();
replay(node); replay(node);
replay(computeService); replay(computeService);
@ -158,6 +160,7 @@ public class AtomicNodePredicatesTest {
@Test(expectedExceptions = IllegalStateException.class) @Test(expectedExceptions = IllegalStateException.class)
public void testNodeRunningFailsOnError() { public void testNodeRunningFailsOnError() {
expect(node.getStatus()).andReturn(Status.ERROR).atLeastOnce(); expect(node.getStatus()).andReturn(Status.ERROR).atLeastOnce();
expect(node.getBackendStatus()).andReturn(null).atLeastOnce();
replay(node); replay(node);
replay(computeService); replay(computeService);

View File

@ -18,14 +18,22 @@
*/ */
package org.jclouds.compute.util; package org.jclouds.compute.util;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus;
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue;
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsValuesOfEmptyString;
import static org.jclouds.compute.util.ComputeServiceUtils.parseVersionOrReturnEmptyString; import static org.jclouds.compute.util.ComputeServiceUtils.parseVersionOrReturnEmptyString;
import static org.jclouds.compute.util.ComputeServiceUtils.*;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
import org.jclouds.compute.config.BaseComputeServiceContextModule; import org.jclouds.compute.config.BaseComputeServiceContextModule;
import org.jclouds.compute.domain.ComputeMetadataIncludingStatus;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.OsFamily;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
@ -45,8 +53,31 @@ import com.google.inject.Guice;
* @author Adrian Cole * @author Adrian Cole
* *
*/ */
@Test(groups = "unit") @Test(groups = "unit", testName = "ComputeServiceUtilsTest")
public class ComputeServiceUtilsTest { public class ComputeServiceUtilsTest {
@SuppressWarnings("unchecked")
@Test
public void testFormatStatusWithBackendStatus() {
ComputeMetadataIncludingStatus<Image.Status> resource = createMock(ComputeMetadataIncludingStatus.class);
expect(resource.getStatus()).andReturn(Image.Status.PENDING);
expect(resource.getBackendStatus()).andReturn("queued").anyTimes();
replay(resource);
assertEquals(formatStatus(resource), "PENDING[queued]");
verify(resource);
}
@SuppressWarnings("unchecked")
@Test
public void testFormatStatusWithoutBackendStatus() {
ComputeMetadataIncludingStatus<Image.Status> resource = createMock(ComputeMetadataIncludingStatus.class);
expect(resource.getStatus()).andReturn(Image.Status.PENDING);
expect(resource.getBackendStatus()).andReturn(null).anyTimes();
replay(resource);
assertEquals(formatStatus(resource), "PENDING");
verify(resource);
}
Map<OsFamily, Map<String, String>> map = new BaseComputeServiceContextModule() { Map<OsFamily, Map<String, String>> map = new BaseComputeServiceContextModule() {
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule()) }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
.getInstance(Json.class)); .getInstance(Json.class));