You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/09 04:55:27 UTC

[20/28] incubator-brooklyn git commit: brooklyn-rest-api: add org.apache package prefix

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicyConfigSummary.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicyConfigSummary.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicyConfigSummary.java
new file mode 100644
index 0000000..91bd2f1
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicyConfigSummary.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+import com.google.common.collect.ImmutableMap;
+
+public class PolicyConfigSummary extends ConfigSummary {
+
+    private static final long serialVersionUID = 4339330833863794513L;
+    
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    private final Map<String, URI> links;
+
+    public PolicyConfigSummary(
+            @JsonProperty("name") String name,
+            @JsonProperty("type") String type,
+            @JsonProperty("description") String description,
+            @JsonProperty("defaultValue") Object defaultValue,
+            @JsonProperty("reconfigurable") boolean reconfigurable,
+            @JsonProperty("links") Map<String, URI> links) {
+        super(name, type, description, defaultValue, reconfigurable, null, null, null);
+        this.links = (links == null) ? ImmutableMap.<String, URI>of() : ImmutableMap.copyOf(links);
+    }
+
+    @Override
+    public Map<String, URI> getLinks() {
+        return links;
+    }
+
+    @Override
+    public String toString() {
+        return "PolicyConfigSummary{"
+                + "name='" + getName() + '\''
+                + ", type='" + getType() + '\''
+                + '}';
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicySummary.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicySummary.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicySummary.java
new file mode 100644
index 0000000..df6c722
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/PolicySummary.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Map;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+import com.google.common.collect.ImmutableMap;
+
+public class PolicySummary implements HasName, HasId, Serializable {
+
+    private static final long serialVersionUID = -5086680835225136768L;
+    
+    private final String id;
+    private final String name;
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    private final String catalogItemId;
+    private final Status state;
+    private final Map<String, URI> links;
+
+    public PolicySummary(
+            @JsonProperty("id") String id,
+            @JsonProperty("name") String name,
+            @JsonProperty("catalogItemId") String catalogItemId,
+            @JsonProperty("state") Status state,
+            @JsonProperty("links") Map<String, URI> links) {
+        this.id = id;
+        this.name = name;
+        this.catalogItemId = catalogItemId;
+        this.state = state;
+        this.links = (links == null) ? ImmutableMap.<String, URI> of() : ImmutableMap.copyOf(links);
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public String getCatalogItemId() {
+        return catalogItemId;
+    }
+
+    public Status getState() {
+        return state;
+    }
+
+    public Map<String, URI> getLinks() {
+        return links;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        PolicySummary that = (PolicySummary) o;
+
+        if (id != null ? !id.equals(that.id) : that.id != null)
+            return false;
+        if (name != null ? !name.equals(that.name) : that.name != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (id != null ? id.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "ConfigSummary{"
+                + "name='" + name + '\''
+                + ", id='" + id + '\''
+                + ", catalogItemId='" + catalogItemId + '\''
+                + ", links=" + links
+                + '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/ScriptExecutionSummary.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/ScriptExecutionSummary.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/ScriptExecutionSummary.java
new file mode 100644
index 0000000..9f7d5d5
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/ScriptExecutionSummary.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import java.io.Serializable;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+public class ScriptExecutionSummary implements Serializable {
+
+    private static final long serialVersionUID = -7707936602991185960L;
+    
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    private final Object result;
+    @JsonSerialize(include = Inclusion.NON_EMPTY)
+    private final String problem;
+    @JsonSerialize(include = Inclusion.NON_EMPTY)
+    private final String stdout;
+    @JsonSerialize(include = Inclusion.NON_EMPTY)
+    private final String stderr;
+
+    public ScriptExecutionSummary(
+            @JsonProperty("result") Object result, 
+            @JsonProperty("problem") String problem, 
+            @JsonProperty("stdout") String stdout, 
+            @JsonProperty("stderr") String stderr) {
+        super();
+        this.result = result;
+        this.problem = problem;
+        this.stdout = stdout;
+        this.stderr = stderr;
+    }
+
+    public Object getResult() {
+        return result;
+    }
+
+    public String getProblem() {
+        return problem;
+    }
+
+    public String getStderr() {
+        return stderr;
+    }
+
+    public String getStdout() {
+        return stdout;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/SensorSummary.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/SensorSummary.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/SensorSummary.java
new file mode 100644
index 0000000..890030e
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/SensorSummary.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Map;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+import com.google.common.collect.ImmutableMap;
+
+public class SensorSummary implements HasName, Serializable {
+
+    private static final long serialVersionUID = 1154308408351165426L;
+    
+    private final String name;
+    private final String type;
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    private final String description;
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    private final Map<String, URI> links;
+
+    public SensorSummary(
+            @JsonProperty("name") String name,
+            @JsonProperty("type") String type,
+            @JsonProperty("description") String description,
+            @JsonProperty("links") Map<String, URI> links) {
+        this.name = name;
+        this.type = type;
+        this.description = description;
+        this.links = (links == null) ? ImmutableMap.<String, URI> of() : ImmutableMap.copyOf(links);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public Map<String, URI> getLinks() {
+        return links;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        SensorSummary that = (SensorSummary) o;
+
+        if (description != null ? !description.equals(that.description) : that.description != null)
+            return false;
+        if (links != null ? !links.equals(that.links) : that.links != null)
+            return false;
+        if (name != null ? !name.equals(that.name) : that.name != null)
+            return false;
+        if (type != null ? !type.equals(that.type) : that.type != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (type != null ? type.hashCode() : 0);
+        result = 31 * result + (description != null ? description.hashCode() : 0);
+        result = 31 * result + (links != null ? links.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "SensorSummary{"
+                + "name='" + name + '\''
+                + ", type='" + type + '\''
+                + ", description='" + description + '\''
+                + ", links=" + links
+                + '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/Status.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/Status.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/Status.java
new file mode 100644
index 0000000..e2b2ce4
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/Status.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+/**
+ * @author Adam Lowe
+ */
+public enum Status {
+    ACCEPTED,
+    STARTING,
+    RUNNING,
+    STOPPING,
+    STOPPED,
+    DESTROYED,
+    ERROR,
+    UNKNOWN
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/SummaryComparators.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/SummaryComparators.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/SummaryComparators.java
new file mode 100644
index 0000000..857716a
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/SummaryComparators.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import java.util.Comparator;
+
+import javax.annotation.Nonnull;
+
+import brooklyn.basic.BrooklynObject;
+import brooklyn.util.text.NaturalOrderComparator;
+import brooklyn.util.text.Strings;
+
+/**
+ * Useful comparators for domain objects
+ */
+public class SummaryComparators {
+    
+    private SummaryComparators() {}
+    
+    private static NaturalOrderComparator COMPARATOR = new NaturalOrderComparator();
+    
+    @Nonnull
+    static String getDisplayNameOrName(HasName o1) {
+        String n1 = null;
+        if (o1 instanceof BrooklynObject)
+            n1 = ((BrooklynObject)o1).getDisplayName();
+        if (Strings.isEmpty(n1) && o1 instanceof HasConfig && ((HasConfig)o1).getConfig()!=null)
+            n1 = Strings.toString(((HasConfig)o1).getConfig().get("displayName"));
+        // prefer display name if set
+        if (Strings.isEmpty(n1))
+            n1 = o1.getName();
+        if (n1==null) {
+            // put last
+            return "~~~";
+        }
+        return n1;
+    }
+    
+    public static Comparator<HasName> displayNameComparator() {
+        return new Comparator<HasName>() {
+            @Override
+            public int compare(HasName o1, HasName o2) {
+                return COMPARATOR.compare(getDisplayNameOrName(o1).toLowerCase(), getDisplayNameOrName(o2).toLowerCase());
+            }
+        };
+    }
+
+    public static Comparator<HasName> nameComparator() {
+        return new Comparator<HasName>() {
+            @Override
+            public int compare(HasName o1, HasName o2) {
+                return COMPARATOR.compare(o1.getName(), o2.getName());
+            }
+        };
+    }
+
+    public static Comparator<HasId> idComparator() {
+        return new Comparator<HasId>() {
+            @Override
+            public int compare(HasId o1, HasId o2) {
+                return o1.getId().compareTo(o2.getId());
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TaskSummary.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TaskSummary.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TaskSummary.java
new file mode 100644
index 0000000..7ab796f
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TaskSummary.java
@@ -0,0 +1,232 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+import brooklyn.util.collections.Jsonya;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class TaskSummary implements HasId, Serializable {
+
+    private static final long serialVersionUID = 4637850742127078158L;
+    
+    private final String id;
+    private final String displayName;
+    private final String entityId;
+    private final String entityDisplayName;
+    private final String description;
+    private final Collection<Object> tags;
+
+    private final Long submitTimeUtc;
+    private final Long startTimeUtc;
+    private final Long endTimeUtc;
+
+    private final String currentStatus;
+    private final Object result;
+    private final boolean isError;
+    private final boolean isCancelled;
+
+    private final List<LinkWithMetadata> children;
+    private final LinkWithMetadata submittedByTask;
+
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    private final LinkWithMetadata blockingTask;
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    private final String blockingDetails;
+
+    private final String detailedStatus;
+
+    @JsonSerialize(include = Inclusion.NON_NULL)
+    private final Map<String, LinkWithMetadata> streams;
+
+    private final Map<String, URI> links;
+
+    public TaskSummary(
+            @JsonProperty("id") String id, 
+            @JsonProperty("displayName") String displayName, 
+            @JsonProperty("description") String description, 
+            @JsonProperty("entityId") String entityId, 
+            @JsonProperty("entityDisplayName") String entityDisplayName, 
+            @JsonProperty("tags") Set<Object> tags,
+            @JsonProperty("submitTimeUtc") Long submitTimeUtc, 
+            @JsonProperty("startTimeUtc") Long startTimeUtc, 
+            @JsonProperty("endTimeUtc") Long endTimeUtc, 
+            @JsonProperty("currentStatus") String currentStatus, 
+            @JsonProperty("result") Object result, 
+            @JsonProperty("isError") boolean isError, 
+            @JsonProperty("isCancelled") boolean isCancelled, 
+            @JsonProperty("children") List<LinkWithMetadata> children,
+            @JsonProperty("submittedByTask") LinkWithMetadata submittedByTask,
+            @JsonProperty("blockingTask") LinkWithMetadata blockingTask,
+            @JsonProperty("blockingDetails") String blockingDetails,
+            @JsonProperty("detailedStatus") String detailedStatus,
+            @JsonProperty("streams") Map<String, LinkWithMetadata> streams,
+            @JsonProperty("links") Map<String, URI> links) {
+        this.id = id;
+        this.displayName = displayName;
+        this.description = description;
+        this.entityId = entityId;
+        this.entityDisplayName = entityDisplayName;
+        this.tags = (tags == null) ? ImmutableList.of() : ImmutableList.<Object> copyOf(tags);
+        this.submitTimeUtc = submitTimeUtc;
+        this.startTimeUtc = startTimeUtc;
+        this.endTimeUtc = endTimeUtc;
+        this.currentStatus = currentStatus;
+        this.result = result;
+        this.isError = isError;
+        this.isCancelled = isCancelled;
+        this.children = children;
+        this.blockingDetails = blockingDetails;
+        this.blockingTask = blockingTask;
+        this.submittedByTask = submittedByTask;
+        this.detailedStatus = detailedStatus;
+        this.streams = streams;
+        this.links = (links == null) ? ImmutableMap.<String, URI> of() : ImmutableMap.copyOf(links);
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getEntityId() {
+        return entityId;
+    }
+
+    public String getEntityDisplayName() {
+        return entityDisplayName;
+    }
+
+    public Collection<Object> getTags() {
+        List<Object> result = new ArrayList<Object>();
+        for (Object t : tags) {
+            // TODO if we had access to a mapper we could use it to give better json
+            result.add(Jsonya.convertToJsonPrimitive(t));
+        }
+        return result;
+    }
+
+    @JsonIgnore
+    public Collection<Object> getRawTags() {
+        return tags;
+    }
+
+    public Long getSubmitTimeUtc() {
+        return submitTimeUtc;
+    }
+
+    public Long getStartTimeUtc() {
+        return startTimeUtc;
+    }
+
+    public Long getEndTimeUtc() {
+        return endTimeUtc;
+    }
+
+    public String getCurrentStatus() {
+        return currentStatus;
+    }
+
+    public Object getResult() {
+        return result;
+    }
+
+    /** @deprecated since 0.7.0 use {@link #isError} instead. */
+    @Deprecated
+    @JsonIgnore
+    public boolean getIsError() {
+        return isError;
+    }
+
+    /** @deprecated since 0.7.0 use {@link #isCancelled} instead. */
+    @Deprecated
+    @JsonIgnore
+    public boolean getIsCancelled() {
+        return isCancelled;
+    }
+
+    public boolean isError() {
+        return isError;
+    }
+
+    public boolean isCancelled() {
+        return isCancelled;
+    }
+
+    public List<LinkWithMetadata> getChildren() {
+        return children;
+    }
+
+    public LinkWithMetadata getSubmittedByTask() {
+        return submittedByTask;
+    }
+
+    public LinkWithMetadata getBlockingTask() {
+        return blockingTask;
+    }
+
+    public String getBlockingDetails() {
+        return blockingDetails;
+    }
+
+    public String getDetailedStatus() {
+        return detailedStatus;
+    }
+
+    public Map<String, LinkWithMetadata> getStreams() {
+        return streams;
+    }
+
+    public Map<String, URI> getLinks() {
+        return links;
+    }
+
+    @Override
+    public String toString() {
+        return "TaskSummary{"
+                + "id='" + id + '\''
+                + ", displayName='" + displayName + '\''
+                + ", currentStatus='" + currentStatus + '\''
+                + ", startTimeUtc='" + startTimeUtc + '\''
+                + ", endTimeUtc='" + endTimeUtc + '\''
+                + '}';
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/UsageStatistic.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/UsageStatistic.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/UsageStatistic.java
new file mode 100644
index 0000000..258bb93
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/UsageStatistic.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.Map;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * @author Adam Lowe
+ */
+public class UsageStatistic implements HasId, Serializable {
+    
+    private static final long serialVersionUID = 5701414937003064442L;
+    
+    private final Status status;
+    private final String id;
+    private final String applicationId;
+    private final String start;
+    private final String end;
+    private final long duration;
+    private final Map<String,String> metadata;
+
+    public UsageStatistic(
+            @JsonProperty("status") Status status, 
+            @JsonProperty("id") String id, 
+            @JsonProperty("applicationId") String applicationId,
+            @JsonProperty("start") String start,
+            @JsonProperty("end") String end,
+            @JsonProperty("duration") long duration, 
+            @JsonProperty("metadata") Map<String, String> metadata) {
+        this.status = checkNotNull(status, "status");
+        this.id = checkNotNull(id, "id");
+        this.applicationId = applicationId;
+        this.start = start;
+        this.end = end;
+        this.duration = duration;
+        this.metadata = (metadata == null) ? ImmutableMap.<String, String>of() : metadata;
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    public String getApplicationId() {
+        return applicationId;
+    }
+
+    public String getStart() {
+        return start;
+    }
+
+    public String getEnd() {
+        return end;
+    }
+
+    public long getDuration() {
+        return duration;
+    }
+
+    public Map<String, String> getMetadata() {
+        return metadata;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        UsageStatistic statistic = (UsageStatistic) o;
+
+        return Objects.equal(status, statistic.status) &&
+                Objects.equal(id, statistic.id) &&
+                Objects.equal(applicationId, statistic.applicationId) &&
+                Objects.equal(start, statistic.start) &&
+                Objects.equal(end, statistic.end) &&
+                Objects.equal(metadata, statistic.metadata);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(status, id, applicationId, start, end, metadata);
+    }
+
+    @Override
+    public String toString() {
+        return "UsageStatistic{" +
+                "status=" + status +
+                ", id='" + id + '\'' +
+                ", applicationId='" + applicationId + '\'' +
+                ", start='" + start + '\'' +
+                ", end='" + end + '\'' +
+                ", duration=" + duration +
+                ", metadata=" + metadata +
+                '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/UsageStatistics.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/UsageStatistics.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/UsageStatistics.java
new file mode 100644
index 0000000..97b09cd
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/UsageStatistics.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import java.io.Serializable;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * @author Aled Sage
+ */
+public class UsageStatistics implements Serializable {
+
+    private static final long serialVersionUID = -1842301852728290967L;
+    
+    // TODO populate links with /apps endpoint to link to /usage/applications/{id}, to make it more
+    // RESTy
+
+    private final List<UsageStatistic> statistics;
+    private final Map<String, URI> links;
+
+    public UsageStatistics(@JsonProperty("statistics") List<UsageStatistic> statistics,
+                           @JsonProperty("links") Map<String, URI> links) {
+        this.statistics = statistics == null ? ImmutableList.<UsageStatistic> of() : ImmutableList.copyOf(statistics);
+        this.links = (links == null) ? ImmutableMap.<String, URI> of() : ImmutableMap.copyOf(links);
+    }
+
+    public List<UsageStatistic> getStatistics() {
+        return statistics;
+    }
+
+    public Map<String, URI> getLinks() {
+        return links;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof UsageStatistics))
+            return false;
+        UsageStatistics other = (UsageStatistics) o;
+        return Objects.equal(statistics, other.statistics);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(statistics);
+    }
+
+    @Override
+    public String toString() {
+        return "UsageStatistics{" + "statistics=" + statistics + ", links=" + links + '}';
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/VersionSummary.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/VersionSummary.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/VersionSummary.java
new file mode 100644
index 0000000..a6368b5
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/domain/VersionSummary.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class VersionSummary implements Serializable {
+
+    private static final long serialVersionUID = 7275038546963638540L;
+    
+    private final String version;
+    private final String buildSha1;
+    private final String buildBranch;
+    private final List<BrooklynFeatureSummary> features;
+
+    public VersionSummary(String version) {
+        this(version, null, null);
+    }
+
+    public VersionSummary(String version, String buildSha1, String buildBranch) {
+        this(version, buildSha1, buildBranch, Collections.<BrooklynFeatureSummary>emptyList());
+    }
+
+    public VersionSummary(
+            @JsonProperty("version") String version,
+            @JsonProperty("buildSha1") String buildSha1,
+            @JsonProperty("buildBranch") String buildBranch,
+            @JsonProperty("features") List<BrooklynFeatureSummary> features) {
+        this.version = checkNotNull(version, "version");
+        this.buildSha1 = buildSha1;
+        this.buildBranch = buildBranch;
+        this.features = checkNotNull(features, "features");
+    }
+
+    @Nonnull
+    public String getVersion() {
+        return version;
+    }
+
+    @Nullable
+    public String getBuildSha1() {
+        return buildSha1;
+    }
+
+    @Nullable
+    public String getBuildBranch() {
+        return buildBranch;
+    }
+
+    @Nonnull
+    public List<BrooklynFeatureSummary> getFeatures() {
+        return features;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/brooklyn/rest/domain/ApiErrorTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/brooklyn/rest/domain/ApiErrorTest.java b/usage/rest-api/src/test/java/brooklyn/rest/domain/ApiErrorTest.java
deleted file mode 100644
index b2af670..0000000
--- a/usage/rest-api/src/test/java/brooklyn/rest/domain/ApiErrorTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.domain;
-
-import static brooklyn.rest.util.RestApiTestUtils.asJson;
-import static brooklyn.rest.util.RestApiTestUtils.fromJson;
-import static brooklyn.rest.util.RestApiTestUtils.jsonFixture;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-
-import java.io.IOException;
-
-import org.testng.annotations.Test;
-import org.testng.util.Strings;
-
-public class ApiErrorTest {
-
-    @Test
-    public void testSerializeApiError() throws IOException {
-        ApiError error = ApiError.builder()
-                .message("explanatory message")
-                .details("accompanying details")
-                .build();
-        assertEquals(asJson(error), jsonFixture("fixtures/api-error-basic.json"));
-    }
-
-    @Test
-    public void testSerializeApiErrorFromThrowable() throws IOException {
-        Exception e = new Exception("error");
-        e.setStackTrace(Thread.currentThread().getStackTrace());
-
-        ApiError error = ApiError.builderFromThrowable(e).build();
-        ApiError deserialised = fromJson(asJson(error), ApiError.class);
-
-        assertFalse(Strings.isNullOrEmpty(deserialised.getDetails()), "Expected details to contain exception stack trace");
-        assertEquals(deserialised, error);
-    }
-
-    @Test
-    public void testSerializeApiErrorWithoutDetails() throws IOException {
-        ApiError error = ApiError.builder()
-                .message("explanatory message")
-                .build();
-        assertEquals(asJson(error), jsonFixture("fixtures/api-error-no-details.json"));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/brooklyn/rest/domain/ApplicationSpecTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/brooklyn/rest/domain/ApplicationSpecTest.java b/usage/rest-api/src/test/java/brooklyn/rest/domain/ApplicationSpecTest.java
deleted file mode 100644
index 6a4c540..0000000
--- a/usage/rest-api/src/test/java/brooklyn/rest/domain/ApplicationSpecTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.domain;
-
-import static brooklyn.rest.util.RestApiTestUtils.asJson;
-import static brooklyn.rest.util.RestApiTestUtils.fromJson;
-import static brooklyn.rest.util.RestApiTestUtils.jsonFixture;
-import static org.testng.Assert.assertEquals;
-
-import java.io.IOException;
-
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-public class ApplicationSpecTest {
-
-    final EntitySpec entitySpec = new EntitySpec("Vanilla Java App", "brooklyn.entity.java.VanillaJavaApp",
-            ImmutableMap.<String, String>of(
-                    "initialSize", "1",
-                    "creationScriptUrl", "http://my.brooklyn.io/storage/foo.sql"));
-
-    final ApplicationSpec applicationSpec = ApplicationSpec.builder().name("myapp")
-            .entities(ImmutableSet.of(entitySpec)).locations(ImmutableSet.of("/v1/locations/1"))
-            .build();
-
-    @Test
-    public void testSerializeToJSON() throws IOException {
-        assertEquals(asJson(applicationSpec), jsonFixture("fixtures/application-spec.json"));
-    }
-
-    @Test
-    public void testDeserializeFromJSON() throws IOException {
-        assertEquals(fromJson(jsonFixture("fixtures/application-spec.json"), ApplicationSpec.class), applicationSpec);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/brooklyn/rest/domain/EffectorSummaryTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/brooklyn/rest/domain/EffectorSummaryTest.java b/usage/rest-api/src/test/java/brooklyn/rest/domain/EffectorSummaryTest.java
deleted file mode 100644
index e2821ef..0000000
--- a/usage/rest-api/src/test/java/brooklyn/rest/domain/EffectorSummaryTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.domain;
-
-import static brooklyn.rest.util.RestApiTestUtils.asJson;
-import static brooklyn.rest.util.RestApiTestUtils.fromJson;
-import static brooklyn.rest.util.RestApiTestUtils.jsonFixture;
-import static org.testng.Assert.assertEquals;
-
-import java.io.IOException;
-import java.net.URI;
-
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-public class EffectorSummaryTest {
-
-    final EffectorSummary effectorSummary = new EffectorSummary(
-            "stop",
-            "void",
-            ImmutableSet.<EffectorSummary.ParameterSummary<?>>of(),
-            "Effector description",
-            ImmutableMap.of(
-                    "self", URI.create("/v1/applications/redis-app/entities/redis-ent/effectors/stop")));
-
-    @Test
-    public void testSerializeToJSON() throws IOException {
-        assertEquals(asJson(effectorSummary), jsonFixture("fixtures/effector-summary.json"));
-    }
-
-    @Test
-    public void testDeserializeFromJSON() throws IOException {
-        assertEquals(fromJson(jsonFixture("fixtures/effector-summary.json"), EffectorSummary.class), effectorSummary);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/brooklyn/rest/domain/EntitySpecTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/brooklyn/rest/domain/EntitySpecTest.java b/usage/rest-api/src/test/java/brooklyn/rest/domain/EntitySpecTest.java
deleted file mode 100644
index 08b47e5..0000000
--- a/usage/rest-api/src/test/java/brooklyn/rest/domain/EntitySpecTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.domain;
-
-import static brooklyn.rest.util.RestApiTestUtils.asJson;
-import static brooklyn.rest.util.RestApiTestUtils.fromJson;
-import static brooklyn.rest.util.RestApiTestUtils.jsonFixture;
-import static org.testng.Assert.assertEquals;
-
-import java.io.IOException;
-
-import org.testng.annotations.Test;
-
-public class EntitySpecTest {
-
-    final EntitySpec entitySpec = new EntitySpec("Vanilla Java App", "brooklyn.entity.java.VanillaJavaApp");
-
-    @Test
-    public void testSerializeToJSON() throws IOException {
-        assertEquals(asJson(new EntitySpec[] { entitySpec }), jsonFixture("fixtures/entity.json"));
-    }
-
-    @Test
-    public void testDeserializeFromJSON() throws IOException {
-        assertEquals(fromJson(jsonFixture("fixtures/entity.json"), EntitySpec[].class), new EntitySpec[] { entitySpec });
-    }
-
-    @Test
-    public void testDeserializeFromJSONOnlyWithType() throws IOException {
-        EntitySpec actual = fromJson(jsonFixture("fixtures/entity-only-type.json"), EntitySpec.class);
-        assertEquals(actual.getName(), actual.getType());
-        assertEquals(actual.getConfig().size(), 0);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/brooklyn/rest/domain/EntitySummaryTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/brooklyn/rest/domain/EntitySummaryTest.java b/usage/rest-api/src/test/java/brooklyn/rest/domain/EntitySummaryTest.java
deleted file mode 100644
index fb976e1..0000000
--- a/usage/rest-api/src/test/java/brooklyn/rest/domain/EntitySummaryTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.domain;
-
-import static brooklyn.rest.util.RestApiTestUtils.asJson;
-import static brooklyn.rest.util.RestApiTestUtils.fromJson;
-import static brooklyn.rest.util.RestApiTestUtils.jsonFixture;
-import static org.testng.Assert.assertEquals;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.Map;
-
-import org.testng.annotations.Test;
-
-import com.google.common.collect.Maps;
-
-public class EntitySummaryTest {
-
-    static final Map<String, URI> links;
-    static {
-        links = Maps.newLinkedHashMap();
-        links.put("self", URI.create("/v1/applications/tesr/entities/zQsqdXzi"));
-        links.put("catalog", URI.create("/v1/catalog/entities/brooklyn.entity.webapp.tomcat.TomcatServer"));
-        links.put("application", URI.create("/v1/applications/tesr"));
-        links.put("children", URI.create("/v1/applications/tesr/entities/zQsqdXzi/children"));
-        links.put("effectors", URI.create("fixtures/effector-summary-list.json"));
-        links.put("sensors", URI.create("fixtures/sensor-summary-list.json"));
-        links.put("activities", URI.create("fixtures/task-summary-list.json"));
-    }
-
-    static final EntitySummary entitySummary = new EntitySummary("zQsqdXzi", "MyTomcat",
-            "brooklyn.entity.webapp.tomcat.TomcatServer", null, links);
-
-    @Test
-    public void testSerializeToJSON() throws IOException {
-        assertEquals(asJson(entitySummary), jsonFixture("fixtures/entity-summary.json"));
-    }
-
-    @Test
-    public void testDeserializeFromJSON() throws IOException {
-        assertEquals(fromJson(jsonFixture("fixtures/entity-summary.json"), EntitySummary.class), entitySummary);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/brooklyn/rest/domain/LocationSpecTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/brooklyn/rest/domain/LocationSpecTest.java b/usage/rest-api/src/test/java/brooklyn/rest/domain/LocationSpecTest.java
deleted file mode 100644
index 84ac29f..0000000
--- a/usage/rest-api/src/test/java/brooklyn/rest/domain/LocationSpecTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.domain;
-
-import static brooklyn.rest.util.RestApiTestUtils.asJson;
-import static brooklyn.rest.util.RestApiTestUtils.fromJson;
-import static brooklyn.rest.util.RestApiTestUtils.jsonFixture;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNull;
-
-import java.io.IOException;
-
-import org.testng.annotations.Test;
-
-@Deprecated
-public class LocationSpecTest {
-
-    // TODO when removing the deprecated class this tests, change the tests here to point at LocationSummary
-    
-    final LocationSpec locationSpec = LocationSpec.localhost();
-
-    @Test
-    public void testSerializeToJSON() throws IOException {
-        assertEquals(asJson(locationSpec), jsonFixture("fixtures/location.json"));
-    }
-
-    @Test
-    public void testDeserializeFromJSON() throws IOException {
-        assertEquals(fromJson(jsonFixture("fixtures/location.json"), LocationSpec.class), locationSpec);
-    }
-
-    @Test
-    public void testDeserializeFromJSONWithNoCredential() throws IOException {
-        LocationSpec loaded = fromJson(jsonFixture("fixtures/location-without-credential.json"), LocationSpec.class);
-
-        assertEquals(loaded.getSpec(), locationSpec.getSpec());
-
-        assertEquals(loaded.getConfig().size(), 1);
-        assertEquals(loaded.getConfig().get("identity"), "bob");
-        assertNull(loaded.getConfig().get("credential"));
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/brooklyn/rest/domain/VersionSummaryTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/brooklyn/rest/domain/VersionSummaryTest.java b/usage/rest-api/src/test/java/brooklyn/rest/domain/VersionSummaryTest.java
deleted file mode 100644
index eea0249..0000000
--- a/usage/rest-api/src/test/java/brooklyn/rest/domain/VersionSummaryTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package brooklyn.rest.domain;
-
-import static brooklyn.rest.util.RestApiTestUtils.asJson;
-import static brooklyn.rest.util.RestApiTestUtils.fromJson;
-import static brooklyn.rest.util.RestApiTestUtils.jsonFixture;
-import static org.testng.Assert.assertEquals;
-
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class VersionSummaryTest {
-
-    BrooklynFeatureSummary features = new BrooklynFeatureSummary(
-            "Sample Brooklyn Project com.acme.sample:brooklyn-sample v0.1.0-SNAPSHOT",
-            "com.acme.sample.brooklyn-sample",
-            "0.1.0.SNAPSHOT",
-            "523305000",
-            ImmutableMap.of("Brooklyn-Feature-Build-Id", "e0fee1adf795c84eec4735f039503eb18d9c35cc")
-    );
-    VersionSummary summary = new VersionSummary(
-            "0.7.0-SNAPSHOT",
-            "cb4f0a3af2f5042222dd176edc102bfa64e7e0b5",
-            "versions",
-            ImmutableList.of(features)
-    );
-
-    @Test
-    public void testSerialize() {
-        assertEquals(asJson(summary), jsonFixture("fixtures/server-version.json"));
-    }
-
-    @Test
-    public void testDeserialize() {
-        VersionSummary deserialized = fromJson(jsonFixture("fixtures/server-version.json"), VersionSummary.class);
-        assertEquals(deserialized.getBuildSha1(), summary.getBuildSha1());
-        assertEquals(deserialized.getFeatures().size(), 1);
-        assertEquals(deserialized.getFeatures().get(0).getSymbolicName(), features.getSymbolicName());
-        assertEquals(deserialized.getFeatures().get(0).getAdditionalData().get("Brooklyn-Feature-Build-Id"), "e0fee1adf795c84eec4735f039503eb18d9c35cc");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/brooklyn/rest/util/RestApiTestUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/brooklyn/rest/util/RestApiTestUtils.java b/usage/rest-api/src/test/java/brooklyn/rest/util/RestApiTestUtils.java
deleted file mode 100644
index 9f6d7f1..0000000
--- a/usage/rest-api/src/test/java/brooklyn/rest/util/RestApiTestUtils.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.util;
-
-import java.io.InputStream;
-
-import org.codehaus.jackson.map.ObjectMapper;
-import org.codehaus.jackson.type.TypeReference;
-
-import brooklyn.util.exceptions.Exceptions;
-import brooklyn.util.stream.Streams;
-
-public class RestApiTestUtils {
-
-    public static <T> T fromJson(String text, Class<T> type) {
-        try {
-            return new ObjectMapper().readValue(text, type);
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-    public static String asJson(Object x) {
-        try {
-            return new ObjectMapper().writeValueAsString(x);
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-    public static String jsonFixture(String path) {
-        InputStream stream = RestApiTestUtils.class.getClassLoader().getResourceAsStream(path);
-        if (stream==null) throw new IllegalStateException("Cannot find resource: "+path);
-        return asJson(fromJson(Streams.readFullyString(stream), Object.class));
-    }
-
-    public static <T> T fromJson(String text, TypeReference<T> type) {
-        try {
-            return new ObjectMapper().readValue(text, type);
-        } catch (Exception e) {
-            throw Exceptions.propagate(e);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApiErrorTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApiErrorTest.java b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApiErrorTest.java
new file mode 100644
index 0000000..3b370a0
--- /dev/null
+++ b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApiErrorTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.asJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.fromJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.jsonFixture;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+
+import java.io.IOException;
+
+import org.testng.annotations.Test;
+import org.testng.util.Strings;
+
+public class ApiErrorTest {
+
+    @Test
+    public void testSerializeApiError() throws IOException {
+        ApiError error = ApiError.builder()
+                .message("explanatory message")
+                .details("accompanying details")
+                .build();
+        assertEquals(asJson(error), jsonFixture("fixtures/api-error-basic.json"));
+    }
+
+    @Test
+    public void testSerializeApiErrorFromThrowable() throws IOException {
+        Exception e = new Exception("error");
+        e.setStackTrace(Thread.currentThread().getStackTrace());
+
+        ApiError error = ApiError.builderFromThrowable(e).build();
+        ApiError deserialised = fromJson(asJson(error), ApiError.class);
+
+        assertFalse(Strings.isNullOrEmpty(deserialised.getDetails()), "Expected details to contain exception stack trace");
+        assertEquals(deserialised, error);
+    }
+
+    @Test
+    public void testSerializeApiErrorWithoutDetails() throws IOException {
+        ApiError error = ApiError.builder()
+                .message("explanatory message")
+                .build();
+        assertEquals(asJson(error), jsonFixture("fixtures/api-error-no-details.json"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java
new file mode 100644
index 0000000..43c95cc
--- /dev/null
+++ b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.asJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.fromJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.jsonFixture;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class ApplicationSpecTest {
+
+    final EntitySpec entitySpec = new EntitySpec("Vanilla Java App", "brooklyn.entity.java.VanillaJavaApp",
+            ImmutableMap.<String, String>of(
+                    "initialSize", "1",
+                    "creationScriptUrl", "http://my.brooklyn.io/storage/foo.sql"));
+
+    final ApplicationSpec applicationSpec = ApplicationSpec.builder().name("myapp")
+            .entities(ImmutableSet.of(entitySpec)).locations(ImmutableSet.of("/v1/locations/1"))
+            .build();
+
+    @Test
+    public void testSerializeToJSON() throws IOException {
+        assertEquals(asJson(applicationSpec), jsonFixture("fixtures/application-spec.json"));
+    }
+
+    @Test
+    public void testDeserializeFromJSON() throws IOException {
+        assertEquals(fromJson(jsonFixture("fixtures/application-spec.json"), ApplicationSpec.class), applicationSpec);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java
new file mode 100644
index 0000000..affce4e
--- /dev/null
+++ b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.asJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.fromJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.jsonFixture;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class EffectorSummaryTest {
+
+    final EffectorSummary effectorSummary = new EffectorSummary(
+            "stop",
+            "void",
+            ImmutableSet.<EffectorSummary.ParameterSummary<?>>of(),
+            "Effector description",
+            ImmutableMap.of(
+                    "self", URI.create("/v1/applications/redis-app/entities/redis-ent/effectors/stop")));
+
+    @Test
+    public void testSerializeToJSON() throws IOException {
+        assertEquals(asJson(effectorSummary), jsonFixture("fixtures/effector-summary.json"));
+    }
+
+    @Test
+    public void testDeserializeFromJSON() throws IOException {
+        assertEquals(fromJson(jsonFixture("fixtures/effector-summary.json"), EffectorSummary.class), effectorSummary);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySpecTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySpecTest.java b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySpecTest.java
new file mode 100644
index 0000000..74159d1
--- /dev/null
+++ b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySpecTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.asJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.fromJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.jsonFixture;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.testng.annotations.Test;
+
+public class EntitySpecTest {
+
+    final EntitySpec entitySpec = new EntitySpec("Vanilla Java App", "brooklyn.entity.java.VanillaJavaApp");
+
+    @Test
+    public void testSerializeToJSON() throws IOException {
+        assertEquals(asJson(new EntitySpec[] { entitySpec }), jsonFixture("fixtures/entity.json"));
+    }
+
+    @Test
+    public void testDeserializeFromJSON() throws IOException {
+        assertEquals(fromJson(jsonFixture("fixtures/entity.json"), EntitySpec[].class), new EntitySpec[] { entitySpec });
+    }
+
+    @Test
+    public void testDeserializeFromJSONOnlyWithType() throws IOException {
+        EntitySpec actual = fromJson(jsonFixture("fixtures/entity-only-type.json"), EntitySpec.class);
+        assertEquals(actual.getName(), actual.getType());
+        assertEquals(actual.getConfig().size(), 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java
new file mode 100644
index 0000000..54f82cb
--- /dev/null
+++ b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.asJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.fromJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.jsonFixture;
+import static org.testng.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Maps;
+
+public class EntitySummaryTest {
+
+    static final Map<String, URI> links;
+    static {
+        links = Maps.newLinkedHashMap();
+        links.put("self", URI.create("/v1/applications/tesr/entities/zQsqdXzi"));
+        links.put("catalog", URI.create("/v1/catalog/entities/brooklyn.entity.webapp.tomcat.TomcatServer"));
+        links.put("application", URI.create("/v1/applications/tesr"));
+        links.put("children", URI.create("/v1/applications/tesr/entities/zQsqdXzi/children"));
+        links.put("effectors", URI.create("fixtures/effector-summary-list.json"));
+        links.put("sensors", URI.create("fixtures/sensor-summary-list.json"));
+        links.put("activities", URI.create("fixtures/task-summary-list.json"));
+    }
+
+    static final EntitySummary entitySummary = new EntitySummary("zQsqdXzi", "MyTomcat",
+            "brooklyn.entity.webapp.tomcat.TomcatServer", null, links);
+
+    @Test
+    public void testSerializeToJSON() throws IOException {
+        assertEquals(asJson(entitySummary), jsonFixture("fixtures/entity-summary.json"));
+    }
+
+    @Test
+    public void testDeserializeFromJSON() throws IOException {
+        assertEquals(fromJson(jsonFixture("fixtures/entity-summary.json"), EntitySummary.class), entitySummary);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSpecTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSpecTest.java b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSpecTest.java
new file mode 100644
index 0000000..0e653c5
--- /dev/null
+++ b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSpecTest.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.domain;
+
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.asJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.fromJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.jsonFixture;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+
+import java.io.IOException;
+
+import org.testng.annotations.Test;
+
+@Deprecated
+public class LocationSpecTest {
+
+    // TODO when removing the deprecated class this tests, change the tests here to point at LocationSummary
+    
+    final LocationSpec locationSpec = LocationSpec.localhost();
+
+    @Test
+    public void testSerializeToJSON() throws IOException {
+        assertEquals(asJson(locationSpec), jsonFixture("fixtures/location.json"));
+    }
+
+    @Test
+    public void testDeserializeFromJSON() throws IOException {
+        assertEquals(fromJson(jsonFixture("fixtures/location.json"), LocationSpec.class), locationSpec);
+    }
+
+    @Test
+    public void testDeserializeFromJSONWithNoCredential() throws IOException {
+        LocationSpec loaded = fromJson(jsonFixture("fixtures/location-without-credential.json"), LocationSpec.class);
+
+        assertEquals(loaded.getSpec(), locationSpec.getSpec());
+
+        assertEquals(loaded.getConfig().size(), 1);
+        assertEquals(loaded.getConfig().get("identity"), "bob");
+        assertNull(loaded.getConfig().get("credential"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/VersionSummaryTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/VersionSummaryTest.java b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/VersionSummaryTest.java
new file mode 100644
index 0000000..bd4c2f0
--- /dev/null
+++ b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/domain/VersionSummaryTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.brooklyn.rest.domain;
+
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.asJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.fromJson;
+import static org.apache.brooklyn.rest.util.RestApiTestUtils.jsonFixture;
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class VersionSummaryTest {
+
+    BrooklynFeatureSummary features = new BrooklynFeatureSummary(
+            "Sample Brooklyn Project com.acme.sample:brooklyn-sample v0.1.0-SNAPSHOT",
+            "com.acme.sample.brooklyn-sample",
+            "0.1.0.SNAPSHOT",
+            "523305000",
+            ImmutableMap.of("Brooklyn-Feature-Build-Id", "e0fee1adf795c84eec4735f039503eb18d9c35cc")
+    );
+    VersionSummary summary = new VersionSummary(
+            "0.7.0-SNAPSHOT",
+            "cb4f0a3af2f5042222dd176edc102bfa64e7e0b5",
+            "versions",
+            ImmutableList.of(features)
+    );
+
+    @Test
+    public void testSerialize() {
+        assertEquals(asJson(summary), jsonFixture("fixtures/server-version.json"));
+    }
+
+    @Test
+    public void testDeserialize() {
+        VersionSummary deserialized = fromJson(jsonFixture("fixtures/server-version.json"), VersionSummary.class);
+        assertEquals(deserialized.getBuildSha1(), summary.getBuildSha1());
+        assertEquals(deserialized.getFeatures().size(), 1);
+        assertEquals(deserialized.getFeatures().get(0).getSymbolicName(), features.getSymbolicName());
+        assertEquals(deserialized.getFeatures().get(0).getAdditionalData().get("Brooklyn-Feature-Build-Id"), "e0fee1adf795c84eec4735f039503eb18d9c35cc");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/test/java/org/apache/brooklyn/rest/util/RestApiTestUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/java/org/apache/brooklyn/rest/util/RestApiTestUtils.java b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/util/RestApiTestUtils.java
new file mode 100644
index 0000000..6023c02
--- /dev/null
+++ b/usage/rest-api/src/test/java/org/apache/brooklyn/rest/util/RestApiTestUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.util;
+
+import java.io.InputStream;
+
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.type.TypeReference;
+
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.stream.Streams;
+
+public class RestApiTestUtils {
+
+    public static <T> T fromJson(String text, Class<T> type) {
+        try {
+            return new ObjectMapper().readValue(text, type);
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+    public static String asJson(Object x) {
+        try {
+            return new ObjectMapper().writeValueAsString(x);
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+    public static String jsonFixture(String path) {
+        InputStream stream = RestApiTestUtils.class.getClassLoader().getResourceAsStream(path);
+        if (stream==null) throw new IllegalStateException("Cannot find resource: "+path);
+        return asJson(fromJson(Streams.readFullyString(stream), Object.class));
+    }
+
+    public static <T> T fromJson(String text, TypeReference<T> type) {
+        try {
+            return new ObjectMapper().readValue(text, type);
+        } catch (Exception e) {
+            throw Exceptions.propagate(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-client/src/main/java/org/apache/brooklyn/rest/client/BrooklynApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-client/src/main/java/org/apache/brooklyn/rest/client/BrooklynApi.java b/usage/rest-client/src/main/java/org/apache/brooklyn/rest/client/BrooklynApi.java
index f4b47e6..416958f 100644
--- a/usage/rest-client/src/main/java/org/apache/brooklyn/rest/client/BrooklynApi.java
+++ b/usage/rest-client/src/main/java/org/apache/brooklyn/rest/client/BrooklynApi.java
@@ -46,21 +46,21 @@ import org.slf4j.LoggerFactory;
 
 import com.google.gson.Gson;
 
-import brooklyn.rest.api.AccessApi;
-import brooklyn.rest.api.ActivityApi;
-import brooklyn.rest.api.ApplicationApi;
-import brooklyn.rest.api.CatalogApi;
-import brooklyn.rest.api.EffectorApi;
-import brooklyn.rest.api.EntityApi;
-import brooklyn.rest.api.EntityConfigApi;
-import brooklyn.rest.api.LocationApi;
-import brooklyn.rest.api.PolicyApi;
-import brooklyn.rest.api.PolicyConfigApi;
-import brooklyn.rest.api.ScriptApi;
-import brooklyn.rest.api.SensorApi;
-import brooklyn.rest.api.ServerApi;
-import brooklyn.rest.api.UsageApi;
-import brooklyn.rest.api.VersionApi;
+import org.apache.brooklyn.rest.api.AccessApi;
+import org.apache.brooklyn.rest.api.ActivityApi;
+import org.apache.brooklyn.rest.api.ApplicationApi;
+import org.apache.brooklyn.rest.api.CatalogApi;
+import org.apache.brooklyn.rest.api.EffectorApi;
+import org.apache.brooklyn.rest.api.EntityApi;
+import org.apache.brooklyn.rest.api.EntityConfigApi;
+import org.apache.brooklyn.rest.api.LocationApi;
+import org.apache.brooklyn.rest.api.PolicyApi;
+import org.apache.brooklyn.rest.api.PolicyConfigApi;
+import org.apache.brooklyn.rest.api.ScriptApi;
+import org.apache.brooklyn.rest.api.SensorApi;
+import org.apache.brooklyn.rest.api.ServerApi;
+import org.apache.brooklyn.rest.api.UsageApi;
+import org.apache.brooklyn.rest.api.VersionApi;
 import brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.http.BuiltResponsePreservingError;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java b/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java
index 3bfa8c2..ff947c3 100644
--- a/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java
+++ b/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/ApplicationResourceIntegrationTest.java
@@ -42,11 +42,11 @@ import brooklyn.management.ManagementContext;
 import brooklyn.management.internal.LocalManagementContext;
 import org.apache.brooklyn.rest.BrooklynRestApiLauncher;
 import org.apache.brooklyn.rest.BrooklynRestApiLauncherTest;
-import brooklyn.rest.domain.ApplicationSpec;
-import brooklyn.rest.domain.ApplicationSummary;
-import brooklyn.rest.domain.EntitySpec;
-import brooklyn.rest.domain.EntitySummary;
-import brooklyn.rest.domain.SensorSummary;
+import org.apache.brooklyn.rest.domain.ApplicationSpec;
+import org.apache.brooklyn.rest.domain.ApplicationSummary;
+import org.apache.brooklyn.rest.domain.EntitySpec;
+import org.apache.brooklyn.rest.domain.EntitySummary;
+import org.apache.brooklyn.rest.domain.SensorSummary;
 import brooklyn.test.Asserts;
 import brooklyn.util.time.Duration;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java b/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
index 5b5bab2..f23d721 100644
--- a/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
+++ b/usage/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
@@ -39,8 +39,8 @@ import brooklyn.management.ManagementContext;
 import brooklyn.management.internal.LocalManagementContext;
 import org.apache.brooklyn.rest.BrooklynRestApiLauncher;
 import org.apache.brooklyn.rest.BrooklynRestApiLauncherTest;
-import brooklyn.rest.domain.ApplicationSummary;
-import brooklyn.rest.domain.CatalogLocationSummary;
+import org.apache.brooklyn.rest.domain.ApplicationSummary;
+import org.apache.brooklyn.rest.domain.CatalogLocationSummary;
 import org.apache.brooklyn.rest.security.provider.TestSecurityProvider;
 import brooklyn.test.HttpTestUtils;
 import brooklyn.test.entity.TestEntity;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-server/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java
index 592a354..ab0598e 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java
@@ -31,7 +31,7 @@ import org.slf4j.LoggerFactory;
 
 import brooklyn.management.ManagementContext;
 import brooklyn.management.ha.ManagementNodeState;
-import brooklyn.rest.domain.ApiError;
+import org.apache.brooklyn.rest.domain.ApiError;
 import brooklyn.util.text.Strings;
 
 import com.google.common.annotations.VisibleForTesting;