diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/EntityType.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/EntityType.java index b66b2f8163..cc034da5f4 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/EntityType.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/EntityType.java @@ -18,9 +18,9 @@ */ package org.jclouds.vcloud.director.v1_5.domain; -import static com.google.common.base.Objects.*; -import static com.google.common.base.Preconditions.*; -import static org.jclouds.vcloud.director.v1_5.VCloudDirectorConstants.*; +import static com.google.common.base.Objects.equal; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorConstants.VCLOUD_1_5_NS; import java.net.URI; import java.util.Set; @@ -216,6 +216,10 @@ public class EntityType> extends ResourceType { public String getName() { return name; } + + public void setName(String name) { + this.name = name; + } @Override public boolean equals(Object o) { diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/FilesList.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/FilesList.java index 57825ab852..6a196bde57 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/FilesList.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/FilesList.java @@ -75,7 +75,7 @@ public class FilesList { private List files; /** - * @see FilesList#getFile() + * @see FilesList#getFiles() */ public Builder file(List file) { this.files = file; @@ -90,7 +90,7 @@ public class FilesList { public Builder fromFilesList(FilesList in) { - return file(in.getFile()); + return file(in.getFiles()); } } @@ -128,7 +128,7 @@ public class FilesList { * * */ - public List getFile() { + public List getFiles() { if (files == null) { files = new ArrayList(); } diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/Media.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/Media.java index 2c9077b665..e00b2da2c9 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/Media.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/Media.java @@ -23,6 +23,8 @@ import static com.google.common.base.Objects.equal; import static org.jclouds.vcloud.director.v1_5.VCloudDirectorConstants.VCLOUD_1_5_NS; import java.net.URI; +import java.util.Arrays; +import java.util.List; import java.util.Set; import javax.xml.bind.annotation.XmlAccessType; @@ -68,6 +70,15 @@ public class Media extends ResourceEntityType { + public static final class ImageType { + public static final String ISO = "iso"; + public static final String FLOPPY = "floppy"; + + public static final List ALL = Arrays.asList( + ISO, ISO + ); + } + @SuppressWarnings("unchecked") public static Builder builder() { return new Builder(); diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/Metadata.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/Metadata.java index 11fab28010..dbe22982b9 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/Metadata.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/domain/Metadata.java @@ -66,7 +66,7 @@ public class Metadata extends ResourceType { /** * @see Metadata#getMetadata() */ - public Builder metadata(Set metadataEntries) { + public Builder entries(Set metadataEntries) { this.metadataEntries = Sets.newLinkedHashSet(checkNotNull(metadataEntries, "metadataEntries")); return this; } @@ -78,7 +78,7 @@ public class Metadata extends ResourceType { metadataEntries.add(checkNotNull(metadataEntry, "metadataEntry")); return this; } - + @Override public Metadata build() { Metadata metadata = new Metadata(href, metadataEntries); @@ -124,7 +124,7 @@ public class Metadata extends ResourceType { } public Builder fromMetadata(Metadata in) { - return fromResourceType(in).metadata(in.getMetadataEntries()); + return fromResourceType(in).entries(in.getMetadataEntries()); } /** diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/MediaAsyncClient.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/MediaAsyncClient.java index 39ef53d650..3a1a0420f8 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/MediaAsyncClient.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/MediaAsyncClient.java @@ -36,7 +36,6 @@ import org.jclouds.rest.binders.BindToXMLPayload; import org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType; import org.jclouds.vcloud.director.v1_5.domain.Media; import org.jclouds.vcloud.director.v1_5.domain.Metadata; -import org.jclouds.vcloud.director.v1_5.domain.MetadataEntry; import org.jclouds.vcloud.director.v1_5.domain.MetadataValue; import org.jclouds.vcloud.director.v1_5.domain.Owner; import org.jclouds.vcloud.director.v1_5.domain.Reference; @@ -123,7 +122,7 @@ public interface MediaAsyncClient { @Consumes @JAXBResponseParser @ExceptionParser(ThrowVCloudErrorOn4xx.class) - ListenableFuture getMetadataEntry(@EndpointParam(parser = ReferenceToEndpoint.class) Reference mediaRef, + ListenableFuture getMetadataValue(@EndpointParam(parser = ReferenceToEndpoint.class) Reference mediaRef, @PathParam("key") String key); /** diff --git a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/MediaClient.java b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/MediaClient.java index 92d539a019..70efcab0d5 100644 --- a/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/MediaClient.java +++ b/labs/vcloud-director/src/main/java/org/jclouds/vcloud/director/v1_5/features/MediaClient.java @@ -23,7 +23,6 @@ import java.util.concurrent.TimeUnit; import org.jclouds.concurrent.Timeout; import org.jclouds.vcloud.director.v1_5.domain.Media; import org.jclouds.vcloud.director.v1_5.domain.Metadata; -import org.jclouds.vcloud.director.v1_5.domain.MetadataEntry; import org.jclouds.vcloud.director.v1_5.domain.MetadataValue; import org.jclouds.vcloud.director.v1_5.domain.Owner; import org.jclouds.vcloud.director.v1_5.domain.Reference; @@ -82,11 +81,11 @@ public interface MediaClient { Task mergeMetadata(Reference mediaRef, Metadata metadata); /** - * Retrieves a metadata entry + * Retrieves a metadata value * - * @return the metadata entry, or null if not found + * @return the metadata value, or null if not found */ - MetadataEntry getMetadataEntry(Reference mediaRef, String key); + MetadataValue getMetadataValue(Reference mediaRef, String key); /** * Sets the metadata for the particular key for the media to the value provided. @@ -95,7 +94,7 @@ public interface MediaClient { * @return a task. This operation is asynchronous and the user should monitor the returned * task status in order to check when it is completed. */ - Task setMetadata(Reference mediaRef, String key, MetadataValue metadataEntry); + Task setMetadata(Reference mediaRef, String key, MetadataValue metadataValue); /** * Deletes a metadata entry. diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorLiveTestConstants.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorLiveTestConstants.java index 709183d374..c58b863299 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorLiveTestConstants.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/VCloudDirectorLiveTestConstants.java @@ -23,6 +23,21 @@ package org.jclouds.vcloud.director.v1_5; */ public class VCloudDirectorLiveTestConstants { + public static final String REF_REQ_LIVE = "%s reference required to perform live tests"; + public static final String OBJ_REQ_LIVE = "%s instance required to perform live tests"; + public static final String OBJ_FIELD_REQ_LIVE = "%s must have a non-null \"%s\" to perform live tests"; + public static final String OBJ_FIELD_REQ = "%s must always have a non-null field \"%s\""; + public static final String OBJ_FIELD_ATTRB_REQ = "%s %s (%s) must always have a non-null field \"%s\""; + public static final String OBJ_FIELD_EQ = "%s %s must have the value \"%s\" (%s)"; + public static final String OBJ_FIELD_CONTAINS = "%s %s must contain the values \"%s\" (%s)"; + public static final String OBJ_FIELD_GTE_0 = "%s field %s must be greater than to equal to 0 (%d)"; + public static final String GETTER_RETURNS_SAME_OBJ = "%s should return the same %s as %s (%s, %s)"; + public static final String OBJ_FIELD_UPDATABLE = "%s field %s should be updatable"; + public static final String OBJ_FIELD_ATTRB_DEL = "%s %s (%s) should have deleted field \"%s\" (%s)"; + public static final String OBJ_DEL = "%s (%s) should have been deleted"; + public static final String TASK_COMPLETE_TIMELY = "Task %s should complete in a timely fashion"; + + @Deprecated public static final String FIELD_NOT_NULL_FMT = "The %s field of the %s must not be null"; } diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java index 1bf7b70fae..7f39cd9484 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/domain/Checks.java @@ -37,6 +37,18 @@ import com.google.common.collect.Iterables; */ public class Checks { + public static void checkResourceEntityType(ResourceEntityType resourceEntity) { + // Check optional fields + // NOTE status cannot be checked (TODO: doesn't status have a range of valid values?) + FilesList files = resourceEntity.getFiles(); + if (files != null && files.getFiles() != null && !files.getFiles().isEmpty()) { + for (File file : files.getFiles()) checkFile(file); + } + + // Check parent type + checkEntityType(resourceEntity); + } + public static void checkEntityType(EntityType entity) { // Check required fields assertNotNull(entity.getName(), "The Name attribute of an EntityType must be set"); @@ -75,7 +87,7 @@ public class Checks { for (Link link : links) checkLink(link); } } - + public static void checkId(String id) { Iterable parts = Splitter.on(':').split(id); assertEquals(Iterables.size(parts), 4, "The Id must be well formed"); @@ -145,6 +157,22 @@ public class Checks { // Check parent type checkEntityType(task); } + + public static void checkFile(File file) { + // Check optional fields + // NOTE checksum be checked + Long size = file.getSize(); + if(size != null) { + assertTrue(file.size >= 0, "File size must be greater than or equal to 0"); + } + Long bytesTransferred = file.getBytesTransferred(); + if(bytesTransferred != null) { + assertTrue(bytesTransferred >= 0, "Bytes transferred must be greater than or equal to 0"); + } + + // Check parent type + checkEntityType(file); + } public static void checkProgress(Integer progress) { assertTrue(progress >= 0 && progress <= 100, "The Progress attribute must be between 0 and 100"); @@ -159,4 +187,9 @@ public class Checks { // NOTE vendorSpecificErrorCode cannot be checked // NOTE stackTrace cannot be checked } + + public static void checkImageType(String imageType) { + assertTrue(Media.ImageType.ALL.contains(imageType), + "The Image type of a Media must be one of the allowed list"); + } } diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/CatalogClientExpectTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/CatalogClientExpectTest.java index 5a192b3b8f..9bf2121484 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/CatalogClientExpectTest.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/CatalogClientExpectTest.java @@ -146,7 +146,7 @@ public class CatalogClientExpectTest extends BaseVCloudDirectorRestClientExpectT .type("application/vnd.vmware.vcloud.catalog+xml") .href(URI.create("https://vcloudbeta.bluelock.com/api/catalog/7212e451-76e1-4631-b2de-ba1dfd8080e4")) .build()) - .metadata(ImmutableSet.of(metadataEntry())) + .entries(ImmutableSet.of(metadataEntry())) .build(); assertEquals(client.getCatalogClient().getCatalogMetadata(catalogRef), expected); @@ -298,7 +298,7 @@ public class CatalogClientExpectTest extends BaseVCloudDirectorRestClientExpectT .type("application/vnd.vmware.vcloud.catalogItem+xml") .href(URI.create("https://vcloudbeta.bluelock.com/api/catalogItem/a36fdac9-b8c2-43e2-9a4c-2ffaf3ee13df")) .build()) - .metadata(ImmutableSet.of(itemMetadataEntry())) + .entries(ImmutableSet.of(itemMetadataEntry())) .build(); assertEquals(client.getCatalogClient().getCatalogItemMetadata(catalogItemReference), expected); diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/MediaClientExpectTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/MediaClientExpectTest.java index cddac2c6c7..8fb0b40a25 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/MediaClientExpectTest.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/MediaClientExpectTest.java @@ -251,11 +251,11 @@ public class MediaClientExpectTest extends BaseVCloudDirectorRestClientExpectTes .xmlFilePayload("/media/metadataEntry.xml", VCloudDirectorMediaType.METADATA_ENTRY) .httpResponseBuilder().build()); - MetadataEntry expected = metadataEntry(); + MetadataValue expected = metadataValue(); Reference mediaRef = Reference.builder().href(mediaUri).build(); - assertEquals(client.getMediaClient().getMetadataEntry(mediaRef, "key"), expected); + assertEquals(client.getMediaClient().getMetadataValue(mediaRef, "key"), expected); } @Test @@ -465,15 +465,15 @@ public class MediaClientExpectTest extends BaseVCloudDirectorRestClientExpectTes .build(); } - private static MetadataEntry metadataEntry() { - return MetadataEntry.builder() + private static MetadataValue metadataValue() { + return MetadataValue.builder() .href(URI.create("https://vcloudbeta.bluelock.com/api/cmedia/794eb334-754e-4917-b5a0-5df85cbd61d1/metadata/key")) .link(Link.builder() .rel("up") .type("application/vnd.vmware.vcloud.metadata+xml") .href(URI.create("https://vcloudbeta.bluelock.com/api/media/794eb334-754e-4917-b5a0-5df85cbd61d1/metadata")) .build()) - .key("key").value("value").build(); + .value("value").build(); } private Task mergeMetadataTask() { diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/MediaClientLiveTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/MediaClientLiveTest.java new file mode 100644 index 0000000000..f2bb585c63 --- /dev/null +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/MediaClientLiveTest.java @@ -0,0 +1,348 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + *(Link.builder().regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless(Link.builder().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.vcloud.director.v1_5.features; + +import static com.google.common.base.Objects.equal; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.GETTER_RETURNS_SAME_OBJ; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_DEL; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_ATTRB_DEL; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_ATTRB_REQ; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_CONTAINS; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_EQ; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_GTE_0; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_REQ; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_REQ_LIVE; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_UPDATABLE; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_REQ_LIVE; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.REF_REQ_LIVE; +import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.TASK_COMPLETE_TIMELY; +import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkResourceType; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.net.URI; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.vcloud.director.v1_5.VCloudDirectorException; +import org.jclouds.vcloud.director.v1_5.domain.Checks; +import org.jclouds.vcloud.director.v1_5.domain.Error; +import org.jclouds.vcloud.director.v1_5.domain.Media; +import org.jclouds.vcloud.director.v1_5.domain.Metadata; +import org.jclouds.vcloud.director.v1_5.domain.MetadataEntry; +import org.jclouds.vcloud.director.v1_5.domain.MetadataValue; +import org.jclouds.vcloud.director.v1_5.domain.Owner; +import org.jclouds.vcloud.director.v1_5.domain.Reference; +import org.jclouds.vcloud.director.v1_5.domain.Task; +import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorClientLiveTest; +import org.jclouds.vcloud.director.v1_5.predicates.TaskSuccess; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * Tests behavior of {@code MediaClient} + * + * @author danikov + */ +@Test(groups = { "live", "apitests", "User" }, testName = "MediaClientLiveTest") +public class MediaClientLiveTest extends BaseVCloudDirectorClientLiveTest { + public static final String MEDIA = "media"; + public static Predicate taskTester; + + /* + * Convenience references to API clients. + */ + protected MediaClient mediaClient; + + /* + * Shared state between dependent tests. + */ + private Reference mediaRef; + private Media media; + private Owner owner; + private Metadata metadata; + private MetadataValue metadataValue; + private String metadataEntryValue = "value"; + + @BeforeGroups(groups = { "live" }, dependsOnMethods = { "setupClient" }) + public void before() { + String mediaId = "68dc01a4-6c76-4177-9f19-ec12bf94287c"; // TODO: inject + mediaRef = Reference.builder() + .type("application/vnd.vmware.vcloud.media+xml") + .name("") + .href(URI.create(endpoint+"/media/"+mediaId)) + .id(mediaId) + .build(); + mediaClient = context.getApi().getMediaClient(); + taskTester = new RetryablePredicate(new TaskSuccess(context), 10, 1, TimeUnit.SECONDS); + mediaClient.setMetadata(mediaRef, "key", MetadataValue.builder().value("value").build()); + } + + @Test(testName = "GET /media/{id}") + public void testWhenResponseIs2xxLoginReturnsValidMedia() { + // required for testing + assertNotNull(mediaRef, String.format(REF_REQ_LIVE, MEDIA)); + + media = mediaClient.getMedia(mediaRef); + assertNotNull(media, String.format(OBJ_REQ_LIVE, MEDIA)); + assertTrue(!media.getDescription().equals("DO NOT USE"), "Media isn't to be used for testing"); + + owner = media.getOwner(); + assertNotNull(owner, String.format(OBJ_FIELD_REQ_LIVE, MEDIA, "owner")); + Checks.checkResourceType(media.getOwner()); + + // parent type + Checks.checkResourceEntityType(media); + + // required + String imageType = media.getImageType(); + Checks.checkImageType(imageType); + Long size = media.getSize(); + assertNotNull(size, String.format(OBJ_FIELD_REQ, MEDIA, "size")); + assertTrue(size >= 0, String.format(OBJ_FIELD_GTE_0, MEDIA, "size", size)); + } + + @Test(testName = "GET /media/{id}/owner", + dependsOnMethods = { "testWhenResponseIs2xxLoginReturnsValidMedia" }) + public void testWhenResponseIs2xxLoginReturnsValidMediaOwner() { + Owner directOwner = mediaClient.getOwner(mediaRef); + assertEquals(owner, directOwner, String.format(GETTER_RETURNS_SAME_OBJ, + "getOwner()", "owner", "media.getOwner()", owner.toString(), directOwner.toString())); + + // parent type + Checks.checkResourceType(directOwner); + + // required + assertNotNull(directOwner.getUser(), String.format(OBJ_FIELD_REQ, "Owner", "user")); + Checks.checkReferenceType(directOwner.getUser()); + } + + @Test(testName = "PUT /media/{id}", + dependsOnMethods = { "testWhenResponseIs2xxLoginReturnsValidMedia" }) + public void testWhenResponseIs2xxLoginReturnsValidNetwork() { + String oldName = media.getName(); + String newName = "new "+oldName; + String oldDescription = media.getDescription(); + String newDescription = "new "+oldDescription; + media.setName(newName); + media.setDescription(newDescription); + + Task updateMedia = mediaClient.updateMedia(mediaRef, media); + Checks.checkTask(updateMedia); + assertTrue(taskTester.apply(updateMedia.getHref()), String.format(TASK_COMPLETE_TIMELY, "updateMedia")); + media = mediaClient.getMedia(mediaRef); + + assertTrue(equal(media.getName(), newName), String.format(OBJ_FIELD_UPDATABLE, MEDIA, "name")); + assertTrue(equal(media.getDescription(), newDescription), + String.format(OBJ_FIELD_UPDATABLE, MEDIA, "description")); + + //TODO negative tests? + + // ensure media remains valid + testWhenResponseIs2xxLoginReturnsValidMedia(); + + media.setName(newName); + media.setDescription(newDescription); + + updateMedia = mediaClient.updateMedia(mediaRef, media); + Checks.checkTask(updateMedia); + assertTrue(taskTester.apply(updateMedia.getHref()), String.format(TASK_COMPLETE_TIMELY, "updateMedia")); + media = mediaClient.getMedia(mediaRef); + } + + @Test(testName = "GET /media/{id}/metadata", + dependsOnMethods = { "testWhenResponseIs2xxLoginReturnsValidMedia" }) + public void testWhenResponseIs2xxLoginReturnsValidMetadata() { + metadata = mediaClient.getMetadata(mediaRef); + // required for testing + assertFalse(Iterables.isEmpty(metadata.getMetadataEntries()), + String.format(OBJ_FIELD_REQ_LIVE, MEDIA, "metadata.entries")); + + // parent type + checkResourceType(metadata); + + for (MetadataEntry entry : metadata.getMetadataEntries()) { + // required elements and attributes + assertNotNull(entry.getKey(), + String.format(OBJ_FIELD_ATTRB_REQ, MEDIA, "MetadataEntry", metadataValue, "key")); + assertNotNull(entry.getValue(), + String.format(OBJ_FIELD_ATTRB_REQ, MEDIA, "MetadataEntry", metadataValue, "value")); + + // parent type + checkResourceType(entry); + } + } + + @Test(testName = "POST /media/{id}/metadata", + dependsOnMethods = { "testWhenResponseIs2xxLoginReturnsValidMetadata" }) + public void testWhenResponseIs2xxLoginMergedMetadata() { + // test new + Set inputEntries = ImmutableSet.of(MetadataEntry.builder().entry("testKey", "testValue").build()); + Metadata inputMetadata = Metadata.builder() + .entries(inputEntries) + .build(); + + Task mergeMetadata = mediaClient.mergeMetadata(mediaRef, inputMetadata); + Checks.checkTask(mergeMetadata); + assertTrue(taskTester.apply(mergeMetadata.getHref()), String.format(TASK_COMPLETE_TIMELY, "mergeMetadata(new)")); + metadata = mediaClient.getMetadata(mediaRef); + checkMetadataContainsEntries(metadata, inputEntries); + + testWhenResponseIs2xxLoginReturnsValidMetadata(); + + // test modify + inputEntries = ImmutableSet.of(MetadataEntry.builder().entry("testKey", "new testValue").build()); + inputMetadata = Metadata.builder() + .entries(inputEntries) + .build(); + + mergeMetadata = mediaClient.mergeMetadata(mediaRef, inputMetadata); + Checks.checkTask(mergeMetadata); + assertTrue(taskTester.apply(mergeMetadata.getHref()), String.format(TASK_COMPLETE_TIMELY, "mergeMetadata(modify)")); + metadata = mediaClient.getMetadata(mediaRef); + checkMetadataContainsEntries(metadata, inputEntries); + + testWhenResponseIs2xxLoginReturnsValidMetadata(); + } + + private void checkMetadataContainsEntries(Metadata metadata, Set entries) { + for (MetadataEntry inputEntry : entries) { + boolean found = false; + for (MetadataEntry entry : metadata.getMetadataEntries()) { + if (equal(inputEntry.getKey(), entry.getKey())) { + found = true; break; + } + } + + if (!found) { + String.format(OBJ_FIELD_CONTAINS, MEDIA, "metadata", + Iterables.toString(metadata.getMetadataEntries()), + Iterables.toString(entries)); + } + } + } + + @Test(testName = "GET /media/{id}/metadata/{key}", + dependsOnMethods = { "testWhenResponseIs2xxLoginMergedMetadata" }) + public void testWhenResponseIs2xxLoginReturnsValidMetadataValue() { + metadataValue = mediaClient.getMetadataValue(mediaRef, "key"); + + // Check parent type + checkResourceType(metadataValue); + + // Check required elements and attributes + String value = metadataValue.getValue(); + assertNotNull(value, + String.format(OBJ_FIELD_ATTRB_REQ, MEDIA, "MetadataEntry", + metadataValue.toString(), metadataEntryValue.toString())); + assertEquals(value, metadataEntryValue, + String.format(OBJ_FIELD_EQ, MEDIA, "metadataEntry.value", metadataEntryValue, value)); + } + + @Test(testName = "PUT /media/{id}/metadata/{key}", + dependsOnMethods = { "testWhenResponseIs2xxLoginReturnsValidMetadataValue" }) + public void testWhenResponseIs2xxLoginUpdatesMetadataEntry() { + metadataEntryValue = "newValue"; + MetadataValue newValue = MetadataValue.builder().value(metadataEntryValue).build(); + + Task setMetadataEntry = mediaClient.setMetadata(mediaRef, "key", newValue); + Checks.checkTask(setMetadataEntry); + assertTrue(taskTester.apply(setMetadataEntry.getHref()), + String.format(TASK_COMPLETE_TIMELY, "setMetadataEntry")); + metadataValue = mediaClient.getMetadataValue(mediaRef, "key"); + + // ensure metadataEntry remains valid + testWhenResponseIs2xxLoginReturnsValidMetadataValue(); + } + + @Test(testName = "DELETE /media/{id}/metadata/{key}", + dependsOnMethods = { "testWhenResponseIs2xxLoginUpdatesMetadataEntry" } ) + public void testWhenResponseIs2xxLoginDeletesMetadataEntry() { + Task deleteMetadataEntry = mediaClient.deleteMetadataEntry(mediaRef, "testKey"); + Checks.checkTask(deleteMetadataEntry); + assertTrue(taskTester.apply(deleteMetadataEntry.getHref()), + String.format(TASK_COMPLETE_TIMELY, "deleteMetadataEntry")); + + Error expected = Error.builder() + .message("The access to the resource metadata_item with id testKey is forbidden") + .majorErrorCode(403) + .minorErrorCode("ACCESS_TO_RESOURCE_IS_FORBIDDEN") + .build(); + + try { + metadataValue = mediaClient.getMetadataValue(mediaRef, "testKey"); + fail("Should give HTTP 403 error"); + } catch (VCloudDirectorException vde) { + assertEquals(vde.getError(), expected); + metadataValue = null; + } catch (Exception e) { + fail("Should have thrown a VCloudDirectorException"); + } + + if (metadataValue != null) { // guard against NPE on the .toStrings + assertNull(metadataValue, String.format(OBJ_FIELD_ATTRB_DEL, MEDIA, + "Metadata", metadataValue.toString(), + "metadataEntry", metadataValue.toString())); + } + + // ensure metadata and media remains valid + testWhenResponseIs2xxLoginReturnsValidMetadata(); + testWhenResponseIs2xxLoginReturnsValidMedia(); + } + @Test(testName = "DELETE /media/{id}", + dependsOnMethods = { "testWhenResponseIs2xxLoginDeletesMetadataEntry" } ) + public void testWhenResponseIs2xxLoginDeletesMedia() { + + Task deleteMedia = mediaClient.deleteMedia(mediaRef); + Checks.checkTask(deleteMedia); + assertTrue(taskTester.apply(deleteMedia.getHref()), + String.format(TASK_COMPLETE_TIMELY, "deleteMedia")); + + Error expected = Error.builder() + .message(String.format( + "No access to entity \"(com.vmware.vcloud.entity.media:%s)\".", + mediaRef.getId())) + .majorErrorCode(403) + .minorErrorCode("ACCESS_TO_RESOURCE_IS_FORBIDDEN") + .build(); + + try { + media = mediaClient.getMedia(mediaRef); + fail("Should give HTTP 403 error"); + } catch (VCloudDirectorException vde) { + assertEquals(vde.getError(), expected); + media = null; + } catch (Exception e) { + fail("Should have thrown a VCloudDirectorException"); + } + + if (media != null) { // guard against NPE on the .toStrings + assertNull(metadataValue, String.format(OBJ_DEL, MEDIA, media.toString())); + } + } +} diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/NetworkClientExpectTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/NetworkClientExpectTest.java index 1ade66a6ca..6b8c76d413 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/NetworkClientExpectTest.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/NetworkClientExpectTest.java @@ -159,7 +159,7 @@ public class NetworkClientExpectTest extends BaseVCloudDirectorRestClientExpectT .type("application/vnd.vmware.vcloud.network+xml") .href(URI.create("https://vcloudbeta.bluelock.com/api/network/55a677cf-ab3f-48ae-b880-fab90421980c")) .build()) - .metadata(ImmutableSet.of(MetadataEntry.builder().entry("key", "value").build())) + .entries(ImmutableSet.of(MetadataEntry.builder().entry("key", "value").build())) .build(); Reference networkRef = Reference.builder().href(networkUri).build(); diff --git a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/OrgClientExpectTest.java b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/OrgClientExpectTest.java index 5e5b9119f5..541a37134e 100644 --- a/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/OrgClientExpectTest.java +++ b/labs/vcloud-director/src/test/java/org/jclouds/vcloud/director/v1_5/features/OrgClientExpectTest.java @@ -188,7 +188,7 @@ public class OrgClientExpectTest extends BaseVCloudDirectorRestClientExpectTest .type("application/vnd.vmware.vcloud.org+xml") .href(URI.create("https://vcloudbeta.bluelock.com/api/org/6f312e42-cd2b-488d-a2bb-97519cd57ed0")) .build()) - .metadata(ImmutableSet.of(metadataEntry())) + .entries(ImmutableSet.of(metadataEntry())) .build(); Reference orgRef = Reference.builder().href(orgUri).build();