From c078cb21704c56b2dfe1b70350df657fcbd2c34e Mon Sep 17 00:00:00 2001 From: Jeremy Daggett Date: Sun, 16 Sep 2012 15:43:18 -0700 Subject: [PATCH] Initial contribution to metadata APIs --- .../nova/v2_0/features/ImageApi.java | 67 ++++ .../nova/v2_0/features/ImageAsyncApi.java | 75 +++++ .../nova/v2_0/features/ServerApi.java | 67 ++++ .../nova/v2_0/features/ServerAsyncApi.java | 70 ++++ .../v2_0/features/ImageApiExpectTest.java | 285 ++++++++++++++++ .../v2_0/features/ServerApiExpectTest.java | 307 ++++++++++++++++++ .../v2_0/parse/ParseMetadataItemTest.java | 60 ++++ .../v2_0/parse/ParseMetadataListTest.java | 65 ++++ .../v2_0/parse/ParseMetadataUpdateTest.java | 66 ++++ .../src/test/resources/metadata_item.json | 5 + .../src/test/resources/metadata_list.json | 6 + .../src/test/resources/metadata_updated.json | 7 + 12 files changed, 1080 insertions(+) create mode 100644 apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataItemTest.java create mode 100644 apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataListTest.java create mode 100644 apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataUpdateTest.java create mode 100644 apis/openstack-nova/src/test/resources/metadata_item.json create mode 100644 apis/openstack-nova/src/test/resources/metadata_list.json create mode 100644 apis/openstack-nova/src/test/resources/metadata_updated.json diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageApi.java index a6ccf4d17b..24dee30e05 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageApi.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageApi.java @@ -18,6 +18,7 @@ */ package org.jclouds.openstack.nova.v2_0.features; +import java.util.Map; import java.util.concurrent.TimeUnit; import org.jclouds.collect.PagedIterable; @@ -75,5 +76,71 @@ public interface ImageApi { * @return server or null if not found */ void delete(String id); + + /** + * List all metadata for an image. + * + * @param id + * id of the image + * @return the metadata as a Map + */ + Map listMetadata(String id); + + /** + * Sets the metadata for an image. + * + * @param id + * id of the image + * @param metadata + * a Map containing the metadata + * @return the metadata as a Map + */ + Map setMetadata(String id, Map metadata); + + /** + * Update the metadata for a server. + * + * @param id + * id of the image + * @param metadata + * a Map containing the metadata + * @return the metadata as a Map + */ + Map updateMetadata(String id, Map metadata); + + /** + * Update the metadata for an image. + * + * @param id + * id of the image + * @param metadata + * a Map containing the metadata + * @return the metadata as a Map + */ + Map getMetadataItem(String id, String key); + + + /** + * Set a metadata item for an image. + * + * @param id + * id of the image + * @param key + * the name of the metadata item + * @param value + * the value of the metadata item + * @return the metadata as a Map + */ + Map setMetadataItem(String id, String key, String value); + + /** + * Delete a metadata item from an image. + * + * @param id + * id of the image + * @param key + * the name of the metadata item + */ + void deleteMetadataItem(String id, String key); } diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageAsyncApi.java index c68fb74149..79dfef9f8a 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageAsyncApi.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ImageAsyncApi.java @@ -18,11 +18,16 @@ */ package org.jclouds.openstack.nova.v2_0.features; +import java.util.Map; + import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.jclouds.collect.PagedIterable; @@ -35,11 +40,16 @@ import org.jclouds.openstack.nova.v2_0.functions.internal.ParseImages; import org.jclouds.openstack.v2_0.domain.Resource; import org.jclouds.openstack.v2_0.options.PaginationOptions; import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.Payload; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SkipEncoding; import org.jclouds.rest.annotations.Transform; +import org.jclouds.rest.binders.BindToJsonPayload; +import org.jclouds.rest.functions.ReturnEmptyMapOnNotFoundOr404; import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; @@ -117,5 +127,70 @@ public interface ImageAsyncApi { @Path("/images/{id}") @ExceptionParser(ReturnVoidOnNotFoundOr404.class) ListenableFuture delete(@PathParam("id") String id); + + /** + * @see ImageApi#listMetadata + */ + @GET + @SelectJson("metadata") + @Path("/images/{id}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class) + ListenableFuture> listMetadata(@PathParam("id") String id); + /** + * @see ImageApi#setMetadata + */ + @PUT + @SelectJson("metadata") + @Path("/images/{id}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class) + @MapBinder(BindToJsonPayload.class) + ListenableFuture> setMetadata(@PathParam("id") String id, @PayloadParam("metadata") Map metadata); + + /** + * @see ImageApi#updateMetadata + */ + @POST + @SelectJson("metadata") + @Path("/images/{id}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class) + @MapBinder(BindToJsonPayload.class) + ListenableFuture> updateMetadata(@PathParam("id") String id, @PayloadParam("metadata") Map metadata); + + /** + * @see ImageApi#getMetadataItem + */ + @GET + @SelectJson("metadata") + @Path("/images/{id}/metadata/{key}") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture> getMetadataItem(@PathParam("id") String id, @PathParam("key") String key); + + /** + * @see ImageApi#setMetadataItem + */ + @PUT + @SelectJson("metadata") + @Path("/images/{id}/metadata/{key}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class) + @Payload("%7B\"metadata\":%7B\"{key}\":\"{value}\"%7D%7D") + ListenableFuture> setMetadataItem(@PathParam("id") String id, @PathParam("key") String key, @PathParam("value") String value); + + + /** + * @see ImageApi#deleteMetadataItem + */ + @DELETE + @Consumes + @Path("/images/{id}/metadata/{key}") + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture deleteMetadataItem(@PathParam("id") String id, @PathParam("key") String key); } diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerApi.java index 6e95bf39e1..f8454004a3 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerApi.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerApi.java @@ -18,6 +18,7 @@ */ package org.jclouds.openstack.nova.v2_0.features; +import java.util.Map; import java.util.concurrent.TimeUnit; import org.jclouds.collect.PagedIterable; @@ -191,5 +192,71 @@ public interface ServerApi { * @return ID of the new / updated image */ String createImageFromServer(String name, String id); + + /** + * List all metadata for a server. + * + * @param id + * id of the server + * + * @return the metadata as a Map + */ + Map listMetadata(String id); + + /** + * Set the metadata for a server. + * + * @param id + * id of the server + * @param metadata + * a Map containing the metadata + * @return the metadata as a Map + */ + Map setMetadata(String id, Map metadata); + + /** + * Update the metadata for a server. + * + * @param id + * id of the server + * @param metadata + * a Map containing the metadata + * @return the metadata as a Map + */ + Map updateMetadata(String id, Map metadata); + + /** + * Update the metadata for a server. + * + * @param id + * id of the image + * @param metadata + * a Map containing the metadata + * @return the metadata as a Map + */ + Map getMetadataItem(String id, String key); + + /** + * Set a metadata item for a server. + * + * @param id + * id of the image + * @param key + * the name of the metadata item + * @param value + * the value of the metadata item + * @return the metadata as a Map + */ + Map setMetadataItem(String id, String key, String value); + + /** + * Delete a metadata item from a server. + * + * @param id + * id of the image + * @param key + * the name of the metadata item + */ + void deleteMetadataItem(String id, String key); } diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerAsyncApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerAsyncApi.java index 848a57ddeb..e58e879baf 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerAsyncApi.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/features/ServerAsyncApi.java @@ -18,6 +18,8 @@ */ package org.jclouds.openstack.nova.v2_0.features; +import java.util.Map; + import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -52,10 +54,13 @@ import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.annotations.SkipEncoding; import org.jclouds.rest.annotations.Transform; import org.jclouds.rest.annotations.Unwrap; +import org.jclouds.rest.binders.BindToJsonPayload; import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; +import org.jclouds.rest.functions.ReturnEmptyMapOnNotFoundOr404; import org.jclouds.rest.functions.ReturnEmptyPagedIterableOnNotFoundOr404; import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import com.google.common.util.concurrent.ListenableFuture; @@ -247,4 +252,69 @@ public interface ServerAsyncApi { @ResponseParser(ParseImageIdFromLocationHeader.class) ListenableFuture createImageFromServer(@PayloadParam("name") String name, @PathParam("id") String id); + /** + * @see ServerApi#listMetadata + */ + @GET + @SelectJson("metadata") + @Path("/servers/{id}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class) + ListenableFuture> listMetadata(@PathParam("id") String id); + + /** + * @see ServerApi#setMetadata + */ + @PUT + @SelectJson("metadata") + @Path("/servers/{id}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class) + @MapBinder(BindToJsonPayload.class) + ListenableFuture> setMetadata(@PathParam("id") String id, @PayloadParam("metadata") Map metadata); + + /** + * @see ServerApi#updateMetadata + */ + @POST + @SelectJson("metadata") + @Path("/servers/{id}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class) + @MapBinder(BindToJsonPayload.class) + ListenableFuture> updateMetadata(@PathParam("id") String id, @PayloadParam("metadata") Map metadata); + + /** + * @see ServerApi#getMetadataItem + */ + @GET + @SelectJson("metadata") + @Path("/servers/{id}/metadata/{key}") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture> getMetadataItem(@PathParam("id") String id, @PathParam("key") String key); + + /** + * @see ServerApi#setMetadataItem + */ + @PUT + @SelectJson("metadata") + @Path("/servers/{id}/metadata/{key}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptyMapOnNotFoundOr404.class) + @Payload("%7B\"metadata\":%7B\"{key}\":\"{value}\"%7D%7D") + ListenableFuture> setMetadataItem(@PathParam("id") String id, @PathParam("key") String key, @PathParam("value") String value); + + /** + * @see ServerApi#deleteMetadataItem + */ + @DELETE + @Consumes + @Path("/servers/{id}/metadata/{key}") + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture deleteMetadataItem(@PathParam("id") String id, @PathParam("key") String key); + } diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ImageApiExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ImageApiExpectTest.java index 705cf2a280..aea70f0496 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ImageApiExpectTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ImageApiExpectTest.java @@ -21,6 +21,7 @@ package org.jclouds.openstack.nova.v2_0.features; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; @@ -28,8 +29,11 @@ import org.jclouds.openstack.nova.v2_0.NovaApi; import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest; import org.jclouds.openstack.nova.v2_0.parse.ParseImageListTest; import org.jclouds.openstack.nova.v2_0.parse.ParseImageTest; +import org.jclouds.openstack.nova.v2_0.parse.ParseMetadataListTest; +import org.jclouds.openstack.nova.v2_0.parse.ParseMetadataUpdateTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; /** @@ -113,4 +117,285 @@ public class ImageApiExpectTest extends BaseNovaApiExpectTest { } + public void testListMetadataWhenResponseIs2xx() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + HttpRequest listMetadata = HttpRequest + .builder() + .method("GET") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" + imageId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken).build(); + + HttpResponse listMetadataResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/metadata_list.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, listMetadata, listMetadataResponse); + + assertEquals(apiWhenServerExists.getImageApiForZone("az-1.region-a.geo-1").listMetadata(imageId).toString(), + new ParseMetadataListTest().expected().toString()); + } + + public void testListMetadataWhenResponseIs404() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + HttpRequest listMetadata = HttpRequest + .builder() + .method("GET") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" + imageId + "/metadata") + .addHeader("Accept", "*/*") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse listMetadataResponse = HttpResponse.builder().statusCode(404).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, listMetadata, listMetadataResponse); + + try { + apiWhenServerExists.getImageApiForZone("az-1.region-a.geo-1").listMetadata(imageId); + fail("Expected an exception."); + } catch (Exception e) { + ; + } + } + + public void testSetMetadataWhenResponseIs2xx() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 1") + .put("Image Version", "2.1") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("PUT") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" + imageId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 1\",\"Image Version\":\"2.1\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/metadata_list.json")).build(); + + NovaApi apiWhenImageExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + assertEquals(apiWhenImageExists.getImageApiForZone("az-1.region-a.geo-1").setMetadata(imageId, metadata).toString(), + new ParseMetadataListTest().expected().toString()); + } + + public void testSetMetadataWhenResponseIs404() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 1") + .put("Image Version", "2.1") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("PUT") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" +imageId + "/metadata") + .addHeader("Accept", "*/*") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 1\",\"Image Version\":\"2.1\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(404).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + try { + apiWhenServerExists.getImageApiForZone("az-1.region-a.geo-1").setMetadata(imageId, metadata); + fail("Expected an exception."); + } catch (Exception e) { + ; + } + } + + public void testUpdateMetadataWhenResponseIs2xx() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 2") + .put("Server Description", "Simple Server") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("POST") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + imageId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 2\",\"Server Description\":\"Simple Server\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/metadata_updated.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + assertEquals(apiWhenServerExists.getImageApiForZone("az-1.region-a.geo-1").updateMetadata(imageId, metadata).toString(), + new ParseMetadataUpdateTest().expected().toString()); + } + + public void testUpdateMetadataWhenResponseIs404() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 2") + .put("Server Description", "Simple Server") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("POST") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + imageId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 2\",\"Server Description\":\"Simple Server\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(404) + .payload(payloadFromResource("/metadata_updated.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + try { + apiWhenServerExists.getImageApiForZone("az-1.region-a.geo-1").setMetadata(imageId, metadata); + fail("Expected an exception."); + } catch (Exception e) { + ; + } + } + + public void testGetMetadataItemWhenResponseIs2xx() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + String key = "Image%20Version"; + + HttpRequest getMetadataItem = HttpRequest + .builder() + .method("GET") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" + imageId + "/metadata/" + key) + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse getMetadataItemResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromString("{\"metadata\":{\"Image Version\":\"2.5\"}}")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, getMetadataItem, getMetadataItemResponse); + + System.out.println(apiWhenServerExists.getImageApiForZone("az-1.region-a.geo-1").getMetadataItem(imageId, "Image Version").toString()); + assertEquals(apiWhenServerExists.getImageApiForZone("az-1.region-a.geo-1").getMetadataItem(imageId, "Image Version").toString(), + "{Image Version=2.5}"); + } + + public void testGetMetadataItemWhenResponseIs404() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + String key = "Image%20Version"; + + HttpRequest getMetadata = HttpRequest + .builder() + .method("GET") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" + imageId + "/metadata/" + key) + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse getMetadataResponse = HttpResponse.builder().statusCode(404) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Image Version\":\"2.5\"}}", "application/json")).build(); + + NovaApi apiWhenImageExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, getMetadata, getMetadataResponse); + + assertNull(apiWhenImageExists.getImageApiForZone("az-1.region-a.geo-1").getMetadataItem(imageId, key)); + } + + public void testSetMetadataItemWhenResponseIs2xx() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + String key = "Image%20Version"; + + HttpRequest setMetadataItem = HttpRequest + .builder() + .method("PUT") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" + imageId + "/metadata/" + key) + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Image Version\":\"2.5\"}}", "application/json")) + .build(); + + HttpResponse setMetadataItemResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Image Version\":\"2.5\"}}", "application/json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadataItem, setMetadataItemResponse); + + assertEquals(apiWhenServerExists.getImageApiForZone("az-1.region-a.geo-1").setMetadataItem(imageId, key, "2.5").toString(), + "Image Version=2.5"); + } + + public void testSetMetadataItemWhenResponseIs404() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + String key = "Image%20Version"; + + HttpRequest setMetadataItem = HttpRequest + .builder() + .method("PUT") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" + imageId + "/metadata/" + key) + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse setMetadataItemResponse = HttpResponse.builder().statusCode(404).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadataItem, setMetadataItemResponse); + + assertNull(apiWhenServerExists.getImageApiForZone("az-1.region-a.geo-1").setMetadataItem(imageId, key, "2.5")); + + } + + public void testDeleteMetadataItemWhenResponseIs2xx() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + String key = "Image%20Version"; + + HttpRequest deleteMetadataItem = HttpRequest + .builder() + .method("DELETE") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" + imageId + "/metadata/" + key) + .addHeader("Accept", "*/*") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse deleteMetadataItemResponse = HttpResponse.builder().statusCode(204).build(); + + NovaApi apiWhenImageExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, deleteMetadataItem, deleteMetadataItemResponse); + + apiWhenImageExists.getImageApiForZone("az-1.region-a.geo-1").deleteMetadataItem(imageId, key); + } + + public void testDeleteMetadataItemWhenResponseIs404() throws Exception { + String imageId = "52415800-8b69-11e0-9b19-734f5736d2a2"; + String key = "Image%20Version"; + + HttpRequest deleteMetadataItem = HttpRequest + .builder() + .method("DELETE") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/images/" + imageId + "/metadata/" + key) + .addHeader("Accept", "*/*") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse deleteMetadataItemResponse = HttpResponse.builder().statusCode(404).build(); + + NovaApi apiWhenImageExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, deleteMetadataItem, deleteMetadataItemResponse); + + apiWhenImageExists.getImageApiForZone("az-1.region-a.geo-1").deleteMetadataItem(imageId, key); + + } } diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java index 967aeea409..0292c75e4d 100644 --- a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/features/ServerApiExpectTest.java @@ -28,9 +28,13 @@ import org.jclouds.openstack.nova.v2_0.NovaApi; import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiExpectTest; import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions; import org.jclouds.openstack.nova.v2_0.parse.ParseCreatedServerTest; +import org.jclouds.openstack.nova.v2_0.parse.ParseMetadataItemTest; +import org.jclouds.openstack.nova.v2_0.parse.ParseMetadataListTest; +import org.jclouds.openstack.nova.v2_0.parse.ParseMetadataUpdateTest; import org.jclouds.openstack.nova.v2_0.parse.ParseServerListTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; @@ -271,4 +275,307 @@ public class ServerApiExpectTest extends BaseNovaApiExpectTest { } } + public void testListMetadataWhenResponseIs2xx() throws Exception { + String serverId = "123"; + + HttpRequest listMetadata = HttpRequest + .builder() + .method("GET") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken).build(); + + HttpResponse listMetadataResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/metadata_list.json")).build(); + + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, listMetadata, listMetadataResponse); + + assertEquals(apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").listMetadata(serverId).toString(), + new ParseMetadataListTest().expected().toString()); + } + + public void testListMetadataWhenResponseIs404() throws Exception { + String serverId = "123"; + HttpRequest listMetadata = HttpRequest + .builder() + .method("GET") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata") + .addHeader("Accept", "*/*") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse listMetadataResponse = HttpResponse.builder().statusCode(404).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, listMetadata, listMetadataResponse); + + try { + apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").listMetadata(serverId); + fail("Expected an exception."); + } catch (Exception e) { + ; + } + } + + public void testSetMetadataWhenResponseIs2xx() throws Exception { + String serverId = "123"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 1") + .put("Image Version", "2.1") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("PUT") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 1\",\"Image Version\":\"2.1\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/metadata_list.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + assertEquals(apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").setMetadata(serverId, metadata).toString(), + new ParseMetadataListTest().expected().toString()); + } + + public void testSetMetadataWhenResponseIs404() throws Exception { + String serverId = "123"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 1") + .put("Image Version", "2.1") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("PUT") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata") + .addHeader("Accept", "*/*") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 1\",\"Image Version\":\"2.1\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(404).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + try { + apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").setMetadata(serverId, metadata); + fail("Expected an exception."); + } catch (Exception e) { + ; + } + } + + public void testUpdateMetadataWhenResponseIs2xx() throws Exception { + String serverId = "123"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 2") + .put("Server Description", "Simple Server") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("POST") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 2\",\"Server Description\":\"Simple Server\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/metadata_updated.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + assertEquals(apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").updateMetadata(serverId, metadata).toString(), + new ParseMetadataUpdateTest().expected().toString()); + } + + public void testUpdateMetadataWhenResponseIs404() throws Exception { + String serverId = "123"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 2") + .put("Server Description", "Simple Server") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("POST") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 2\",\"Server Description\":\"Simple Server\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(404) + .payload(payloadFromResource("/metadata_updated.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + try { + apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").setMetadata(serverId, metadata); + fail("Expected an exception."); + } catch (Exception e) { + ; + } + } + + public void testGetMetadataItemWhenResponseIs2xx() throws Exception { + String serverId = "123"; + String key = "Server%20Label"; + + HttpRequest getMetadataItem = HttpRequest + .builder() + .method("GET") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata/" + key) + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse getMetadataItemResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/metadata_item.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, getMetadataItem, getMetadataItemResponse); + + assertEquals(apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").getMetadataItem(serverId, "Server Label").toString(), + new ParseMetadataItemTest().expected().toString()); + } + + public void testGetMetadataItemWhenResponseIs404() throws Exception { + String serverId = "123"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 1") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("GET") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 2\",\"Server Description\":\"Simple Server\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(404) + .payload(payloadFromResource("/metadata_updated.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + try { + apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").setMetadata(serverId, metadata); + fail("Expected an exception."); + } catch (Exception e) { + ; + } + } + + public void testSetMetadataItemWhenResponseIs2xx() throws Exception { + String serverId = "123"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 2") + .put("Server Description", "Simple Server") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("POST") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 2\",\"Server Description\":\"Simple Server\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResource("/metadata_updated.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + assertEquals(apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").updateMetadata(serverId, metadata).toString(), + new ParseMetadataUpdateTest().expected().toString()); + } + + public void testSetMetadataItemWhenResponseIs404() throws Exception { + String serverId = "123"; + ImmutableMap metadata = new ImmutableMap.Builder() + .put("Server Label", "Web Head 2") + .put("Server Description", "Simple Server") + .build(); + + HttpRequest setMetadata = HttpRequest + .builder() + .method("POST") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata") + .addHeader("Accept", "application/json") + .addHeader("X-Auth-Token", authToken) + .payload(payloadFromStringWithContentType("{\"metadata\":{\"Server Label\":\"Web Head 2\",\"Server Description\":\"Simple Server\"}}","application/json")) + .build(); + + HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(404) + .payload(payloadFromResource("/metadata_updated.json")).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadata, setMetadataResponse); + + try { + apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").setMetadata(serverId, metadata); + fail("Expected an exception."); + } catch (Exception e) { + ; + } + } + + public void testDeleteMetadataItemWhenResponseIs2xx() throws Exception { + String serverId = "123"; + String key = "Server%20Label"; + + HttpRequest setMetadataItem = HttpRequest + .builder() + .method("DELETE") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata/" + key) + .addHeader("Accept", "*/*") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse setMetadataItemResponse = HttpResponse.builder().statusCode(204).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, setMetadataItem, setMetadataItemResponse); + + apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").deleteMetadataItem(serverId, key); + + } + + public void testDeleteMetadataItemWhenResponseIs404() throws Exception { + String serverId = "123"; + String key = "Server%20Label"; + + HttpRequest deleteMetadataItem = HttpRequest + .builder() + .method("DELETE") + .endpoint("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/3456/servers/" + serverId + "/metadata/" + key) + .addHeader("Accept", "*/*") + .addHeader("X-Auth-Token", authToken) + .build(); + + HttpResponse deleteMetadataItemResponse = HttpResponse.builder().statusCode(404).build(); + + NovaApi apiWhenServerExists = requestsSendResponses(keystoneAuthWithUsernameAndPasswordAndTenantName, + responseWithKeystoneAccess, deleteMetadataItem, deleteMetadataItemResponse); + + apiWhenServerExists.getServerApiForZone("az-1.region-a.geo-1").deleteMetadataItem(serverId, key); + + } } diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataItemTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataItemTest.java new file mode 100644 index 0000000000..d99709a879 --- /dev/null +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataItemTest.java @@ -0,0 +1,60 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.openstack.nova.v2_0.parse; + +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; + +import org.jclouds.json.BaseItemParserTest; +import org.jclouds.json.config.GsonModule; +import org.jclouds.openstack.nova.v2_0.config.NovaParserModule; +import org.jclouds.rest.annotations.SelectJson; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * + * @author Jeremy Daggett + */ +@Test(groups = "unit", testName = "ParseMetadataItemTest") +public class ParseMetadataItemTest extends BaseItemParserTest> { + + @Override + public String resource() { + return "/metadata_item.json"; + } + + @Override + @SelectJson("metadata") + @Consumes(MediaType.APPLICATION_JSON) + public Map expected() { + ImmutableMap metadata = ImmutableMap.of("Server Label", "Web Head 1"); + return metadata; + } + + protected Injector injector() { + return Guice.createInjector(new NovaParserModule(), new GsonModule()); + } + +} diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataListTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataListTest.java new file mode 100644 index 0000000000..db195fcf23 --- /dev/null +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataListTest.java @@ -0,0 +1,65 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.openstack.nova.v2_0.parse; + +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; + +import org.jclouds.json.BaseItemParserTest; +import org.jclouds.json.config.GsonModule; +import org.jclouds.openstack.nova.v2_0.config.NovaParserModule; +import org.jclouds.rest.annotations.SelectJson; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * + * @author Jeremy Daggett + */ +@Test(groups = "unit", testName = "ParseMetadataListTest") +public class ParseMetadataListTest extends BaseItemParserTest> { + + @Override + public String resource() { + return "/metadata_list.json"; + } + + @Override + @SelectJson("metadata") + @Consumes(MediaType.APPLICATION_JSON) + public Map expected() { + ImmutableMap metadata = + new ImmutableMap.Builder() + .put("Server Label", "Web Head 1") + .put("Image Version", "2.1") + .build(); + + return metadata; + } + + protected Injector injector() { + return Guice.createInjector(new NovaParserModule(), new GsonModule()); + } + +} diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataUpdateTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataUpdateTest.java new file mode 100644 index 0000000000..dc08093ab2 --- /dev/null +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseMetadataUpdateTest.java @@ -0,0 +1,66 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.openstack.nova.v2_0.parse; + +import java.util.Map; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; + +import org.jclouds.json.BaseItemParserTest; +import org.jclouds.json.config.GsonModule; +import org.jclouds.openstack.nova.v2_0.config.NovaParserModule; +import org.jclouds.rest.annotations.SelectJson; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * + * @author Jeremy Daggett + */ +@Test(groups = "unit", testName = "ParseMetadataUpdateTest") +public class ParseMetadataUpdateTest extends BaseItemParserTest> { + + @Override + public String resource() { + return "/metadata_updated.json"; + } + + @Override + @SelectJson("metadata") + @Consumes(MediaType.APPLICATION_JSON) + public Map expected() { + ImmutableMap metadata = + new ImmutableMap.Builder() + .put("Server Label", "Web Head 2") + .put("Image Version", "2.1") + .put("Server Description", "Simple Server") + .build(); + + return metadata; + } + + protected Injector injector() { + return Guice.createInjector(new NovaParserModule(), new GsonModule()); + } + +} diff --git a/apis/openstack-nova/src/test/resources/metadata_item.json b/apis/openstack-nova/src/test/resources/metadata_item.json new file mode 100644 index 0000000000..f853109c10 --- /dev/null +++ b/apis/openstack-nova/src/test/resources/metadata_item.json @@ -0,0 +1,5 @@ +{ + "metadata": { + "Server Label": "Web Head 1" + } +} \ No newline at end of file diff --git a/apis/openstack-nova/src/test/resources/metadata_list.json b/apis/openstack-nova/src/test/resources/metadata_list.json new file mode 100644 index 0000000000..174d7d60be --- /dev/null +++ b/apis/openstack-nova/src/test/resources/metadata_list.json @@ -0,0 +1,6 @@ +{ + "metadata": { + "Server Label": "Web Head 1", + "Image Version": "2.1" + } +} \ No newline at end of file diff --git a/apis/openstack-nova/src/test/resources/metadata_updated.json b/apis/openstack-nova/src/test/resources/metadata_updated.json new file mode 100644 index 0000000000..82d9fd3ac9 --- /dev/null +++ b/apis/openstack-nova/src/test/resources/metadata_updated.json @@ -0,0 +1,7 @@ +{ + "metadata": { + "Server Label": "Web Head 2", + "Image Version": "2.1", + "Server Description": "Simple Server" + } +} \ No newline at end of file