Repository: jclouds
Updated Branches:
  refs/heads/1.8.x 9a5983d12 -> dedeb63b0


Adding tenantId/projectId and extended attributes to volume and snapshot


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/dedeb63b
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/dedeb63b
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/dedeb63b

Branch: refs/heads/1.8.x
Commit: dedeb63b0fc280e0653e63ab678505d45feea51c
Parents: 9a5983d
Author: istolber <[email protected]>
Authored: Wed Oct 8 09:19:57 2014 +0300
Committer: Andrew Phillips <[email protected]>
Committed: Mon Nov 10 12:52:17 2014 -0500

----------------------------------------------------------------------
 .../cinder/v1/config/CinderParserModule.java    |  56 ++++++++-
 .../openstack/cinder/v1/domain/Snapshot.java    |  72 +++++++----
 .../v1/domain/SnapshotExtendedAttributes.java   | 124 +++++++++++++++++++
 .../openstack/cinder/v1/domain/Volume.java      |  89 +++++++------
 .../v1/features/SnapshotApiExpectTest.java      |  18 ++-
 .../features/VolumeAndSnapshotApiLiveTest.java  |   8 +-
 .../cinder/v1/features/VolumeApiExpectTest.java |  17 ++-
 .../src/test/resources/volume_list_details.json |   1 +
 8 files changed, 316 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/dedeb63b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/config/CinderParserModule.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/config/CinderParserModule.java
 
b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/config/CinderParserModule.java
index 9859212..da80131 100644
--- 
a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/config/CinderParserModule.java
+++ 
b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/config/CinderParserModule.java
@@ -16,14 +16,68 @@
  */
 package org.jclouds.openstack.cinder.v1.config;
 
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.config.GsonModule;
 import org.jclouds.json.config.GsonModule.DateAdapter;
+import org.jclouds.openstack.cinder.v1.domain.Snapshot;
+import org.jclouds.openstack.cinder.v1.domain.SnapshotExtendedAttributes;
+import org.jclouds.openstack.cinder.v1.domain.Volume;
 
-import com.google.inject.AbstractModule;
+import javax.inject.Singleton;
+import java.beans.ConstructorProperties;
+import java.lang.reflect.Type;
+import java.util.Date;
+import java.util.Map;
 
 public class CinderParserModule extends AbstractModule {
+
+   @Provides
+   @Singleton
+   public Map<Type, Object> provideCustomAdapterBindings() {
+      return ImmutableMap.<Type, Object>of(
+            Snapshot.class, new SnapshotAdapter()
+      );
+   }
+
    @Override
    protected void configure() {
       bind(DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class);
    }
+
+   @Singleton
+   public static class SnapshotAdapter implements JsonDeserializer<Snapshot> {
+      @Override
+      public Snapshot deserialize(JsonElement jsonElement, Type type, 
JsonDeserializationContext context)
+            throws JsonParseException {
+         Snapshot snapshotBase;
+
+         snapshotBase = apply((SnapshotInternal) 
context.deserialize(jsonElement, SnapshotInternal.class));
+
+         Snapshot.Builder result = 
Snapshot.builder().fromSnapshot(snapshotBase);
+         SnapshotExtendedAttributes extendedAttributes = 
context.deserialize(jsonElement, SnapshotExtendedAttributes.class);
+         if (!Objects.equal(extendedAttributes, 
SnapshotExtendedAttributes.builder().build())) {
+            result.extendedAttributes(extendedAttributes);
+         }
+         return result.build();
+      }
+
+      public Snapshot apply(Snapshot in) {
+         return in.toBuilder().build();
+      }
+
+      private static class SnapshotInternal extends Snapshot {
+         @ConstructorProperties({"id", "volume_id", "status", "size", 
"created_at", "display_name", "display_description", "extendedAttributes"})
+         protected SnapshotInternal(String id, String volumeId, Volume.Status 
status, int size, @Nullable Date created, @Nullable String name, @Nullable 
String description, @Nullable SnapshotExtendedAttributes extendedAttributes) {
+            super(id, volumeId, status, size, created, name, description, 
extendedAttributes);
+         }
+      }
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/dedeb63b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Snapshot.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Snapshot.java
 
b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Snapshot.java
index e5e2e48..e601214 100644
--- 
a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Snapshot.java
+++ 
b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Snapshot.java
@@ -23,6 +23,7 @@ import java.util.Date;
 
 import javax.inject.Named;
 
+import com.google.common.base.Optional;
 import org.jclouds.javax.annotation.Nullable;
 
 import com.google.common.base.Objects;
@@ -33,16 +34,15 @@ import com.google.common.base.Objects.ToStringHelper;
  */
 public class Snapshot {
 
-   public static Builder<?> builder() { 
-      return new ConcreteBuilder();
+   public static Builder builder() {
+      return new Builder();
    }
    
-   public Builder<?> toBuilder() { 
-      return new ConcreteBuilder().fromSnapshot(this);
+   public Builder toBuilder() {
+      return new Builder().fromSnapshot(this);
    }
 
-   public abstract static class Builder<T extends Builder<T>>  {
-      protected abstract T self();
+   public static class Builder {
 
       protected String id;
       protected String volumeId;
@@ -51,11 +51,12 @@ public class Snapshot {
       protected Date created;
       protected String name;
       protected String description;
+      protected SnapshotExtendedAttributes extendedAttributes;
    
       /** 
        * @see Snapshot#getId()
        */
-      public T id(String id) {
+      public Builder id(String id) {
          this.id = id;
          return self();
       }
@@ -63,7 +64,7 @@ public class Snapshot {
       /** 
        * @see Snapshot#getVolumeId()
        */
-      public T volumeId(String volumeId) {
+      public Builder volumeId(String volumeId) {
          this.volumeId = volumeId;
          return self();
       }
@@ -71,7 +72,7 @@ public class Snapshot {
       /** 
        * @see Snapshot#getStatus()
        */
-      public T status(Volume.Status status) {
+      public Builder status(Volume.Status status) {
          this.status = status;
          return self();
       }
@@ -79,7 +80,7 @@ public class Snapshot {
       /** 
        * @see Snapshot#getSize()
        */
-      public T size(int size) {
+      public Builder size(int size) {
          this.size = size;
          return self();
       }
@@ -87,7 +88,7 @@ public class Snapshot {
       /** 
        * @see Snapshot#getCreated()
        */
-      public T created(Date created) {
+      public Builder created(Date created) {
          this.created = created;
          return self();
       }
@@ -95,7 +96,7 @@ public class Snapshot {
       /** 
        * @see Snapshot#getName()
        */
-      public T name(String name) {
+      public Builder name(String name) {
          this.name = name;
          return self();
       }
@@ -103,16 +104,24 @@ public class Snapshot {
       /** 
        * @see Snapshot#getDescription()
        */
-      public T description(String description) {
+      public Builder description(String description) {
          this.description = description;
          return self();
       }
 
+      /**
+       * @see Snapshot#getExtendedAttributes()
+       */
+      public Builder extendedAttributes(SnapshotExtendedAttributes 
extendedAttributes) {
+         this.extendedAttributes = extendedAttributes;
+         return self();
+      }
+
       public Snapshot build() {
-         return new Snapshot(id, volumeId, status, size, created, name, 
description);
+         return new Snapshot(id, volumeId, status, size, created, name, 
description, extendedAttributes);
       }
       
-      public T fromSnapshot(Snapshot in) {
+      public Builder fromSnapshot(Snapshot in) {
          return this
                   .id(in.getId())
                   .volumeId(in.getVolumeId())
@@ -120,17 +129,16 @@ public class Snapshot {
                   .size(in.getSize())
                   .created(in.getCreated())
                   .name(in.getName())
-                  .description(in.getDescription());
+                  .description(in.getDescription())
+                  .extendedAttributes(in.getExtendedAttributes().orNull());
       }
-   }
 
-   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
-      @Override
-      protected ConcreteBuilder self() {
+      protected Builder self() {
          return this;
       }
    }
 
+
    private final String id;
    @Named("volume_id")
    private final String volumeId;
@@ -142,11 +150,10 @@ public class Snapshot {
    private final String name;
    @Named("display_description")
    private final String description;
+   private final Optional<SnapshotExtendedAttributes> extendedAttributes;
 
-   @ConstructorProperties({
-      "id", "volume_id", "status", "size", "created_at", "display_name", 
"display_description"
-   })
-   protected Snapshot(String id, String volumeId, Volume.Status status, int 
size, @Nullable Date created, @Nullable String name, @Nullable String 
description) {
+   @ConstructorProperties({"id", "volume_id", "status", "size", "created_at", 
"display_name", "display_description", "extendedAttributes"})
+   protected Snapshot(String id, String volumeId, Volume.Status status, int 
size, @Nullable Date created, @Nullable String name, @Nullable String 
description, @Nullable SnapshotExtendedAttributes extendedAttributes) {
       this.id = checkNotNull(id, "id");
       this.volumeId = checkNotNull(volumeId, "volumeId");
       this.status = checkNotNull(status, "status");
@@ -154,6 +161,7 @@ public class Snapshot {
       this.created = created;
       this.name = name;
       this.description = description;
+      this.extendedAttributes = Optional.fromNullable(extendedAttributes);
    }
 
    /**
@@ -208,9 +216,18 @@ public class Snapshot {
       return this.description;
    }
 
+   /**
+    * @return Extended attributes for this snapshot. Only present when the
+    *         {@code os-extended-snapshot-attributes} extension is installed
+    */
+   @Nullable
+   public Optional<SnapshotExtendedAttributes> getExtendedAttributes() {
+      return this.extendedAttributes;
+   }
+
    @Override
    public int hashCode() {
-      return Objects.hashCode(id, volumeId, status, size, created, name, 
description);
+      return Objects.hashCode(id, volumeId, status, size, created, name, 
description, extendedAttributes);
    }
 
    @Override
@@ -224,12 +241,13 @@ public class Snapshot {
                && Objects.equal(this.size, that.size)
                && Objects.equal(this.created, that.created)
                && Objects.equal(this.name, that.name)
-               && Objects.equal(this.description, that.description);
+               && Objects.equal(this.description, that.description)
+               && Objects.equal(this.extendedAttributes, 
that.extendedAttributes);
    }
    
    protected ToStringHelper string() {
       return Objects.toStringHelper(this)
-            .add("id", id).add("volumeId", volumeId).add("status", 
status).add("size", size).add("created", created).add("name", 
name).add("description", description);
+            .add("id", id).add("volumeId", volumeId).add("status", 
status).add("size", size).add("created", created).add("name", 
name).add("description", description).add("extendedAttributes", 
extendedAttributes);
    }
    
    @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/dedeb63b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/SnapshotExtendedAttributes.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/SnapshotExtendedAttributes.java
 
b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/SnapshotExtendedAttributes.java
new file mode 100644
index 0000000..e6a4103
--- /dev/null
+++ 
b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/SnapshotExtendedAttributes.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.jclouds.openstack.cinder.v1.domain;
+
+import com.google.common.base.Objects;
+import org.jclouds.javax.annotation.Nullable;
+
+import javax.inject.Named;
+import java.beans.ConstructorProperties;
+
+/**
+ * Additional attributes delivered by Extended Snapshot Attributes extensions
+ */
+public class SnapshotExtendedAttributes {
+
+   public static Builder builder() {
+      return new Builder();
+   }
+
+   public Builder toBuilder() {
+      return new Builder().fromExtendedAttributes(this);
+   }
+
+   public static class Builder {
+
+      protected String projectId;
+      protected String progress;
+
+      /**
+       * @see SnapshotExtendedAttributes#getProjectId()
+       */
+      public Builder projectId(String projectId) {
+         this.projectId = projectId;
+         return self();
+      }
+
+      /**
+       * @see SnapshotExtendedAttributes#getProgress()
+       */
+      public Builder progress(String progress) {
+         this.progress = progress;
+         return self();
+      }
+
+      public SnapshotExtendedAttributes build() {
+         return new SnapshotExtendedAttributes(projectId, progress);
+      }
+
+      public Builder fromExtendedAttributes(SnapshotExtendedAttributes in) {
+         return this
+               .projectId(in.getProjectId())
+               .progress(in.getProgress());
+      }
+
+      protected Builder self() {
+         return this;
+      }
+   }
+
+   @Named("os-extended-snapshot-attributes:project_id")
+   private final String projectId;
+   private final String progress;
+
+   @ConstructorProperties({"os-extended-snapshot-attributes:project_id", 
"os-extended-snapshot-attributes:progress"})
+   protected SnapshotExtendedAttributes(@Nullable String projectId, @Nullable 
String progress) {
+      this.projectId = projectId;
+      this.progress = progress;
+   }
+
+   /**
+    * @return the project id of this snapshot
+    */
+   @Nullable
+   public String getProjectId() {
+      return this.projectId;
+   }
+
+   /**
+    * @return the progress of this snapshot
+    */
+   @Nullable
+   public String getProgress() {
+      return this.progress;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(projectId, progress);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      SnapshotExtendedAttributes that = 
SnapshotExtendedAttributes.class.cast(obj);
+      return Objects.equal(this.projectId, that.projectId)
+            && Objects.equal(this.progress, that.progress);
+   }
+
+   protected Objects.ToStringHelper string() {
+      return Objects.toStringHelper(this)
+            .add("projectId", projectId).add("progress", progress);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/dedeb63b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Volume.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Volume.java
 
b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Volume.java
index eed17f8..e75ab06 100644
--- 
a/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Volume.java
+++ 
b/apis/openstack-cinder/src/main/java/org/jclouds/openstack/cinder/v1/domain/Volume.java
@@ -60,16 +60,15 @@ public class Volume {
       }
    }
 
-   public static Builder<?> builder() { 
-      return new ConcreteBuilder();
+   public static Builder builder() {
+      return new Builder();
    }
    
-   public Builder<?> toBuilder() { 
-      return new ConcreteBuilder().fromVolume(this);
+   public Builder toBuilder() {
+      return new Builder().fromVolume(this);
    }
 
-   public abstract static class Builder<T extends Builder<T>>  {
-      protected abstract T self();
+   public static class Builder {
 
       protected String id;
       protected Volume.Status status;
@@ -82,11 +81,12 @@ public class Volume {
       protected String name;
       protected String description;
       protected Map<String, String> metadata = ImmutableMap.of();
+      protected String tenantId;
    
-      /** 
+      /**
        * @see Volume#getId()
        */
-      public T id(String id) {
+      public Builder id(String id) {
          this.id = id;
          return self();
       }
@@ -94,7 +94,7 @@ public class Volume {
       /** 
        * @see Volume#getStatus()
        */
-      public T status(Volume.Status status) {
+      public Builder status(Volume.Status status) {
          this.status = status;
          return self();
       }
@@ -102,7 +102,7 @@ public class Volume {
       /** 
        * @see Volume#getSize()
        */
-      public T size(int size) {
+      public Builder size(int size) {
          this.size = size;
          return self();
       }
@@ -110,7 +110,7 @@ public class Volume {
       /** 
        * @see Volume#getZone()
        */
-      public T zone(String zone) {
+      public Builder zone(String zone) {
          this.zone = zone;
          return self();
       }
@@ -118,7 +118,7 @@ public class Volume {
       /** 
        * @see Volume#getCreated()
        */
-      public T created(Date created) {
+      public Builder created(Date created) {
          this.created = created;
          return self();
       }
@@ -126,19 +126,19 @@ public class Volume {
       /** 
        * @see Volume#getAttachments()
        */
-      public T attachments(Set<VolumeAttachment> attachments) {
+      public Builder attachments(Set<VolumeAttachment> attachments) {
          this.attachments = ImmutableSet.copyOf(checkNotNull(attachments, 
"attachments"));      
          return self();
       }
 
-      public T attachments(VolumeAttachment... in) {
+      public Builder attachments(VolumeAttachment... in) {
          return attachments(ImmutableSet.copyOf(in));
       }
 
       /** 
        * @see Volume#getVolumeType()
        */
-      public T volumeType(String volumeType) {
+      public Builder volumeType(String volumeType) {
          this.volumeType = volumeType;
          return self();
       }
@@ -146,7 +146,7 @@ public class Volume {
       /** 
        * @see Volume#getSnapshotId()
        */
-      public T snapshotId(String snapshotId) {
+      public Builder snapshotId(String snapshotId) {
          this.snapshotId = snapshotId;
          return self();
       }
@@ -154,7 +154,7 @@ public class Volume {
       /** 
        * @see Volume#getName()
        */
-      public T name(String name) {
+      public Builder name(String name) {
          this.name = name;
          return self();
       }
@@ -162,7 +162,7 @@ public class Volume {
       /** 
        * @see Volume#getDescription()
        */
-      public T description(String description) {
+      public Builder description(String description) {
          this.description = description;
          return self();
       }
@@ -170,16 +170,24 @@ public class Volume {
       /** 
        * @see Volume#getMetadata()
        */
-      public T metadata(Map<String, String> metadata) {
+      public Builder metadata(Map<String, String> metadata) {
          this.metadata = ImmutableMap.copyOf(checkNotNull(metadata, 
"metadata"));     
          return self();
       }
 
+      /**
+       * @see Volume#getTenantId()
+       */
+      public Builder tenantId(String tenantId) {
+         this.tenantId = tenantId;
+         return self();
+      }
+
       public Volume build() {
-         return new Volume(id, status, size, zone, created, attachments, 
volumeType, snapshotId, name, description, metadata);
+         return new Volume(id, status, size, zone, created, attachments, 
volumeType, snapshotId, name, description, metadata, tenantId);
       }
       
-      public T fromVolume(Volume in) {
+      public Builder fromVolume(Volume in) {
          return this
                   .id(in.getId())
                   .status(in.getStatus())
@@ -191,17 +199,15 @@ public class Volume {
                   .snapshotId(in.getSnapshotId())
                   .name(in.getName())
                   .description(in.getDescription())
-                  .metadata(in.getMetadata());
+                  .metadata(in.getMetadata())
+                  .tenantId(in.getTenantId());
       }
-   }
 
-   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
-      @Override
-      protected ConcreteBuilder self() {
+      protected Builder self() {
          return this;
       }
    }
-   
+
    /**
     * Creates a dummy Volume when you need a Volume with just the volumeId. 
     * Several fields must be set in the returned Volume:
@@ -231,11 +237,11 @@ public class Volume {
    @Named("display_description")
    private final String description;
    private final Map<String, String> metadata;
+   @Named("os-vol-tenant-attr:tenant_id")
+   private final String tenantId;
 
-   @ConstructorProperties({
-      "id", "status", "size", "availability_zone", "created_at", 
"attachments", "volume_type", "snapshot_id", "display_name", 
"display_description", "metadata"
-   })
-   protected Volume(String id, Volume.Status status, int size, String zone, 
Date created, @Nullable Set<VolumeAttachment> attachments, @Nullable String 
volumeType, @Nullable String snapshotId, @Nullable String name, @Nullable 
String description, @Nullable Map<String, String> metadata) {
+   @ConstructorProperties({"id", "status", "size", "availability_zone", 
"created_at", "attachments", "volume_type", "snapshot_id", "display_name", 
"display_description", "metadata", "os-vol-tenant-attr:tenant_id"})
+   protected Volume(String id, Volume.Status status, int size, String zone, 
Date created, @Nullable Set<VolumeAttachment> attachments, @Nullable String 
volumeType, @Nullable String snapshotId, @Nullable String name, @Nullable 
String description, @Nullable Map<String, String> metadata, @Nullable String 
tenantId) {
       this.id = checkNotNull(id, "id");
       this.status = checkNotNull(status, "status");
       this.size = size;
@@ -246,7 +252,8 @@ public class Volume {
       this.snapshotId = snapshotId;
       this.name = name;
       this.description = description;
-      this.metadata = metadata == null ? ImmutableMap.<String, String>of() : 
ImmutableMap.copyOf(metadata);      
+      this.metadata = metadata == null ? ImmutableMap.<String, String>of() : 
ImmutableMap.copyOf(metadata);
+      this.tenantId = tenantId;
    }
 
    /**
@@ -324,10 +331,18 @@ public class Volume {
    public Map<String, String> getMetadata() {
       return this.metadata;
    }
-   
+
+   /**
+    * @return the tenant id of this volume
+    */
+   @Nullable
+   public String getTenantId() {
+      return this.tenantId;
+   }
+
    @Override
    public int hashCode() {
-      return Objects.hashCode(id, status, size, zone, created, attachments, 
volumeType, snapshotId, name, description, metadata);
+      return Objects.hashCode(id, status, size, zone, created, attachments, 
volumeType, snapshotId, name, description, metadata, tenantId);
    }
 
    @Override
@@ -345,12 +360,14 @@ public class Volume {
                && Objects.equal(this.snapshotId, that.snapshotId)
                && Objects.equal(this.name, that.name)
                && Objects.equal(this.description, that.description)
-               && Objects.equal(this.metadata, that.metadata);
+               && Objects.equal(this.metadata, that.metadata)
+               && Objects.equal(this.tenantId, that.tenantId);
+
    }
    
    protected ToStringHelper string() {
       return Objects.toStringHelper(this)
-            .add("id", id).add("status", status).add("size", size).add("zone", 
zone).add("created", created).add("attachments", attachments).add("volumeType", 
volumeType).add("snapshotId", snapshotId).add("name", name).add("description", 
description).add("metadata", metadata);
+            .add("id", id).add("status", status).add("size", size).add("zone", 
zone).add("created", created).add("attachments", attachments).add("volumeType", 
volumeType).add("snapshotId", snapshotId).add("name", name).add("description", 
description).add("metadata", metadata).add("extendedAttributes", tenantId);
    }
    
    @Override

http://git-wip-us.apache.org/repos/asf/jclouds/blob/dedeb63b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/SnapshotApiExpectTest.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/SnapshotApiExpectTest.java
 
b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/SnapshotApiExpectTest.java
index 48d5ed7..d053c0f 100644
--- 
a/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/SnapshotApiExpectTest.java
+++ 
b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/SnapshotApiExpectTest.java
@@ -30,6 +30,7 @@ import org.jclouds.date.DateService;
 import org.jclouds.date.internal.SimpleDateFormatDateService;
 import org.jclouds.http.HttpResponse;
 import org.jclouds.openstack.cinder.v1.domain.Snapshot;
+import org.jclouds.openstack.cinder.v1.domain.SnapshotExtendedAttributes;
 import org.jclouds.openstack.cinder.v1.domain.Volume;
 import org.jclouds.openstack.cinder.v1.internal.BaseCinderApiExpectTest;
 import org.jclouds.openstack.cinder.v1.options.CreateSnapshotOptions;
@@ -83,7 +84,7 @@ public class SnapshotApiExpectTest extends 
BaseCinderApiExpectTest {
       ).getSnapshotApiForZone("RegionOne");
 
       Set<? extends Snapshot> snapshots = api.listInDetail().toSet();
-      assertEquals(snapshots, ImmutableSet.of(testSnapshot()));
+      assertEquals(snapshots, ImmutableSet.of(testSnapshotDetailed()));
 
       // double-check individual fields
       Snapshot snappy = Iterables.getOnlyElement(snapshots);
@@ -118,7 +119,7 @@ public class SnapshotApiExpectTest extends 
BaseCinderApiExpectTest {
       ).getSnapshotApiForZone("RegionOne");
 
       Snapshot snapshot = api.get("67d03df1-ce5d-4ba7-adbe-492ceb80170b");
-      assertEquals(snapshot, testSnapshot());
+      assertEquals(snapshot, testSnapshotDetailed());
    }
 
    public void testGetSnapshotFail() {
@@ -296,4 +297,17 @@ public class SnapshotApiExpectTest extends 
BaseCinderApiExpectTest {
             
.created(dateService.iso8601DateParse("2012-11-02T16:23:27.000000"))
             .build();
    }
+
+   protected Snapshot testSnapshotDetailed() {
+      return Snapshot.builder()
+            .id("67d03df1-ce5d-4ba7-adbe-492ceb80170b")
+            .volumeId("ea6f70ef-2784-40b9-9d14-d7f33c507c3f")
+            .description("jclouds test snapshot")
+            .status(Volume.Status.AVAILABLE)
+            .name("jclouds-test-snapshot")
+            .size(1)
+            
.created(dateService.iso8601DateParse("2012-11-02T16:23:27.000000"))
+            
.extendedAttributes(SnapshotExtendedAttributes.builder().projectId("cc03fd4f503f4d9c986b381b8abe6af5").progress("100%").build())
+            .build();
+   }
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/dedeb63b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeAndSnapshotApiLiveTest.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeAndSnapshotApiLiveTest.java
 
b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeAndSnapshotApiLiveTest.java
index 050253b..dbea59d 100644
--- 
a/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeAndSnapshotApiLiveTest.java
+++ 
b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeAndSnapshotApiLiveTest.java
@@ -95,6 +95,7 @@ public class VolumeAndSnapshotApiLiveTest extends 
BaseCinderApiLiveTest {
          assertNotNull(details);
          if (Objects.equal(details.getId(), testVolume.getId())) {
             foundIt = true;
+            break;
          }
       }
       assertTrue(foundIt, "Failed to find the volume we created in list() 
response");
@@ -117,8 +118,10 @@ public class VolumeAndSnapshotApiLiveTest extends 
BaseCinderApiLiveTest {
          assertEquals(details.getName(), vol.getName());
          assertEquals(details.getDescription(), vol.getDescription());
          assertEquals(details.getCreated(), vol.getCreated());
+         assertEquals(details.getTenantId(), vol.getTenantId());
          if (Objects.equal(details.getId(), testVolume.getId())) {
             foundIt = true;
+            break;
          }
       }
       assertTrue(foundIt, "Failed to find the volume we previously created in 
listInDetail() response");
@@ -141,7 +144,7 @@ public class VolumeAndSnapshotApiLiveTest extends 
BaseCinderApiLiveTest {
 
    @Test(dependsOnMethods = "testCreateSnapshot")
    public void testListSnapshots() {
-      Set<? extends Snapshot> snapshots = snapshotApi.list().toSet();
+      Set<? extends Snapshot> snapshots = snapshotApi.listInDetail().toSet();
       assertNotNull(snapshots);
       boolean foundIt = false;
       for (Snapshot snap : snapshots) {
@@ -152,8 +155,9 @@ public class VolumeAndSnapshotApiLiveTest extends 
BaseCinderApiLiveTest {
          assertNotNull(details);
          assertEquals(details.getId(), snap.getId());
          assertEquals(details.getVolumeId(), snap.getVolumeId());
+         assertEquals(details.getExtendedAttributes(), 
snap.getExtendedAttributes());
       }
-      assertTrue(foundIt, "Failed to find the snapshot we previously created 
in listSnapshots() response");
+     assertTrue(foundIt, "Failed to find the snapshot we previously created in 
listSnapshots() response");
    }
 
    @Test(dependsOnMethods = "testCreateSnapshot")

http://git-wip-us.apache.org/repos/asf/jclouds/blob/dedeb63b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeApiExpectTest.java
----------------------------------------------------------------------
diff --git 
a/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeApiExpectTest.java
 
b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeApiExpectTest.java
index 336d09b..f748599 100644
--- 
a/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeApiExpectTest.java
+++ 
b/apis/openstack-cinder/src/test/java/org/jclouds/openstack/cinder/v1/features/VolumeApiExpectTest.java
@@ -82,7 +82,7 @@ public class VolumeApiExpectTest extends 
BaseCinderApiExpectTest {
       ).getVolumeApiForZone("RegionOne");
 
       Set<? extends Volume> volumes = api.listInDetail().toSet();
-      assertEquals(volumes, ImmutableSet.of(testVolume()));
+      assertEquals(volumes, ImmutableSet.of(testVolumeDetailed()));
    }
 
    public void testListVolumesInDetailFail() {
@@ -219,6 +219,21 @@ public class VolumeApiExpectTest extends 
BaseCinderApiExpectTest {
             .build();
    }
 
+   protected Volume testVolumeDetailed() {
+      return Volume.builder()
+            .id("60761c60-0f56-4499-b522-ff13e120af10")
+            .size(1)
+            .name("test")
+            .zone("nova")
+            .status(Volume.Status.IN_USE)
+            .volumeType("None")
+            .description("This is a test volume")
+            .attachments(ImmutableSet.of(testAttachment()))
+            
.created(dateService.iso8601DateParse("2012-10-29T20:53:28.000000"))
+            .tenantId("0ad7eca25ff847b2947a7865b82b851c")
+            .build();
+   }
+
    protected VolumeAttachment testAttachment() {
       return VolumeAttachment.builder()
             .id("60761c60-0f56-4499-b522-ff13e120af10")

http://git-wip-us.apache.org/repos/asf/jclouds/blob/dedeb63b/apis/openstack-cinder/src/test/resources/volume_list_details.json
----------------------------------------------------------------------
diff --git a/apis/openstack-cinder/src/test/resources/volume_list_details.json 
b/apis/openstack-cinder/src/test/resources/volume_list_details.json
index e1a8dc8..c07d4af 100644
--- a/apis/openstack-cinder/src/test/resources/volume_list_details.json
+++ b/apis/openstack-cinder/src/test/resources/volume_list_details.json
@@ -13,6 +13,7 @@
             ],
             "availability_zone": "nova",
             "created_at": "2012-10-29T20:53:28.000000",
+            "os-vol-tenant-attr:tenant_id": "0ad7eca25ff847b2947a7865b82b851c",
             "display_description": "This is a test volume",
             "volume_type": "None",
             "snapshot_id": null,

Reply via email to