Updated Branches: refs/heads/master 2e92538b1 -> 60fd86d3c
The Queue API for OpenStack Marconi. Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/commit/60fd86d3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/60fd86d3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/60fd86d3 Branch: refs/heads/master Commit: 60fd86d3cd09ad2e76ed6cfc5c3874e48278336a Parents: 2e92538 Author: Everett Toews <[email protected]> Authored: Thu Oct 17 15:30:27 2013 -0500 Committer: Everett Toews <[email protected]> Committed: Fri Oct 18 11:23:43 2013 -0500 ---------------------------------------------------------------------- .../openstack/marconi/v1/domain/Aged.java | 123 ++++++++++++ .../marconi/v1/domain/MessagesStats.java | 187 +++++++++++++++++++ .../openstack/marconi/v1/domain/QueueStats.java | 67 +++++++ .../openstack/marconi/v1/features/QueueApi.java | 85 ++++++++- .../v1/handlers/MarconiErrorHandler.java | 12 +- .../marconi/v1/features/QueueApiLiveTest.java | 73 +++++++- .../marconi/v1/features/QueueApiMockTest.java | 140 ++++++++++++++ .../us/CloudQueuesUSProviderMetadata.java | 2 +- 8 files changed, 679 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/60fd86d3/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/Aged.java ---------------------------------------------------------------------- diff --git a/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/Aged.java b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/Aged.java new file mode 100644 index 0000000..84ac899 --- /dev/null +++ b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/Aged.java @@ -0,0 +1,123 @@ +/* + * 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.marconi.v1.domain; + +import com.google.common.base.Objects; + +import java.util.Date; + +/** + * The age of messages in a queue. + * + * @author Everett Toews + */ +public class Aged { + + private int age; + private Date created; + + protected Aged(int age, Date created) { + this.age = age; + this.created = created; + } + + /** + * @return Age of the oldest/newest message in seconds. + */ + public int getAge() { + return age; + } + + /** + * @return Date/Time of the oldest/newest message. + */ + public Date getCreated() { + return created; + } + + @Override + public int hashCode() { + return Objects.hashCode(age, created); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Aged that = Aged.class.cast(obj); + return Objects.equal(this.age, that.age) && Objects.equal(this.created, that.created); + } + + protected Objects.ToStringHelper string() { + return Objects.toStringHelper(this) + .add("age", age).add("created", created); + } + + @Override + public String toString() { + return string().toString(); + } + + public static Builder builder() { + return new ConcreteBuilder(); + } + + public Builder toBuilder() { + return new ConcreteBuilder().fromAged(this); + } + + public static abstract class Builder { + protected abstract Builder self(); + + protected int age; + protected Date created; + + /** + * @see Aged#age + */ + public Builder age(int age) { + this.age = age; + return self(); + } + + /** + * @see Aged#created + */ + public Builder created(Date created) { + this.created = created; + return self(); + } + + public Aged build() { + return new Aged(age, created); + } + + public Builder fromAged(Aged in) { + return this.age(in.getAge()).created(in.getCreated()); + } + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/60fd86d3/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/MessagesStats.java ---------------------------------------------------------------------- diff --git a/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/MessagesStats.java b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/MessagesStats.java new file mode 100644 index 0000000..1440592 --- /dev/null +++ b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/MessagesStats.java @@ -0,0 +1,187 @@ +/* + * 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.marconi.v1.domain; + +import com.google.common.base.Objects; +import com.google.common.base.Optional; +import org.jclouds.javax.annotation.Nullable; + +import java.beans.ConstructorProperties; + +/** + * Statistics on messages in this queue. + * + * @author Everett Toews + */ +public class MessagesStats { + + private int claimed; + private int free; + private int total; + private Aged oldest; + private Aged newest; + + @ConstructorProperties({ + "claimed", "free", "total", "oldest", "newest" + }) + protected MessagesStats(int claimed, int free, int total, @Nullable Aged oldest, @Nullable Aged newest) { + this.claimed = claimed; + this.free = free; + this.total = total; + this.oldest = oldest; + this.newest = newest; + } + + /** + * @return The number of claimed messages in this queue. + */ + public int getClaimed() { + return claimed; + } + + /** + * @return The number of free messages in this queue. + */ + public int getFree() { + return free; + } + + /** + * @return The total number of messages in this queue. + */ + public int getTotal() { + return total; + } + + /** + * @return Statistics on the oldest messages in this queue. If the value of total is 0, then oldest is not present. + */ + public Optional<Aged> getOldest() { + return Optional.fromNullable(oldest); + } + + /** + * @return Statistics on the newest messages in this queue. If the value of total is 0, then newest is not present. + */ + public Optional<Aged> getNewest() { + return Optional.fromNullable(newest); + } + + @Override + public int hashCode() { + return Objects.hashCode(claimed, free, total, oldest, newest); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + MessagesStats that = MessagesStats.class.cast(obj); + return Objects.equal(this.claimed, that.claimed) + && Objects.equal(this.free, that.free) + && Objects.equal(this.total, that.total) + && Objects.equal(this.oldest, that.oldest) + && Objects.equal(this.newest, that.newest); + } + + protected Objects.ToStringHelper string() { + return Objects.toStringHelper(this).omitNullValues() + .add("claimed", claimed).add("free", free).add("total", total).add("oldest", oldest).add("newest", newest); + } + + @Override + public String toString() { + return string().toString(); + } + + public static Builder builder() { + return new ConcreteBuilder(); + } + + public Builder toBuilder() { + return new ConcreteBuilder().fromMessagesStats(this); + } + + public static abstract class Builder { + protected abstract Builder self(); + + protected int claimed; + protected int free; + protected int total; + protected Aged oldest; + protected Aged newest; + + /** + * @see MessagesStats#claimed + */ + public Builder claimed(int claimed) { + this.claimed = claimed; + return self(); + } + + /** + * @see MessagesStats#free + */ + public Builder free(int free) { + this.free = free; + return self(); + } + + /** + * @see MessagesStats#total + */ + public Builder total(int total) { + this.total = total; + return self(); + } + + /** + * @see MessagesStats#oldest + */ + public Builder oldest(Aged oldest) { + this.oldest = oldest; + return self(); + } + + /** + * @see MessagesStats#newest + */ + public Builder newest(Aged newest) { + this.newest = newest; + return self(); + } + + public MessagesStats build() { + return new MessagesStats(claimed, free, total, oldest, newest); + } + + public Builder fromMessagesStats(MessagesStats in) { + return this.claimed(in.getClaimed()).free(in.getFree()).total(in.getTotal()).oldest(in.getOldest().orNull()) + .newest(in.getNewest().orNull()); + } + } + + private static class ConcreteBuilder extends Builder { + @Override + protected ConcreteBuilder self() { + return this; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/60fd86d3/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/QueueStats.java ---------------------------------------------------------------------- diff --git a/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/QueueStats.java b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/QueueStats.java new file mode 100644 index 0000000..492f432 --- /dev/null +++ b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/domain/QueueStats.java @@ -0,0 +1,67 @@ +/* + * 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.marconi.v1.domain; + +import com.google.common.base.Objects; + +import java.beans.ConstructorProperties; + +/** + * Queue statistics, including how many messages are in the queue. + * + * @author Everett Toews + */ +public class QueueStats { + + private MessagesStats messages; + + protected QueueStats(MessagesStats messages) { + this.messages = messages; + } + + /** + * @return The statistics of the messages in this queue. + */ + public MessagesStats getMessagesStats() { + return messages; + } + + @Override + public int hashCode() { + return Objects.hashCode(messages); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + QueueStats that = QueueStats.class.cast(obj); + return Objects.equal(this.messages, that.messages); + } + + protected Objects.ToStringHelper string() { + return Objects.toStringHelper(this) + .add("messagesStats", messages); + } + + @Override + public String toString() { + return string().toString(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/60fd86d3/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/features/QueueApi.java ---------------------------------------------------------------------- diff --git a/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/features/QueueApi.java b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/features/QueueApi.java index e620002..aca5782 100644 --- a/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/features/QueueApi.java +++ b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/features/QueueApi.java @@ -18,35 +18,112 @@ package org.jclouds.openstack.marconi.v1.features; import org.jclouds.Fallbacks; import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest; +import org.jclouds.openstack.marconi.v1.domain.QueueStats; +import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Fallback; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.binders.BindToJsonPayload; import javax.inject.Named; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; 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 java.util.Map; /** * Provides access to Queues via their REST API. - * + * * @author Everett Toews */ @SkipEncoding({'/', '='}) @RequestFilters(AuthenticateRequest.class) public interface QueueApi { /** - * Creates a new Queue + * Create a queue. * - * @param name Name of the Queue. The name must not exceed 64 bytes in length, and it is limited to US-ASCII + * @param name Name of the queue. The name must not exceed 64 bytes in length, and it is limited to US-ASCII * letters, digits, underscores, and hyphens. */ @Named("queue:create") @PUT @Path("queues/{name}") - @Consumes(MediaType.APPLICATION_JSON) @Fallback(Fallbacks.FalseOnNotFoundOr404.class) boolean create(@PathParam("name") String name); + + /** + * Delete a queue. + * + * @param name Name of the queue. The name must not exceed 64 bytes in length, and it is limited to US-ASCII + * letters, digits, underscores, and hyphens. + */ + @Named("queue:delete") + @DELETE + @Path("queues/{name}") + @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + boolean delete(@PathParam("name") String name); + + /** + * Check for a queue's existence. + * + * @param name Name of the queue. The name must not exceed 64 bytes in length, and it is limited to US-ASCII + * letters, digits, underscores, and hyphens. + */ + @Named("queue:get") + @GET + @Path("queues/{name}") + @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + boolean exists(@PathParam("name") String name); + + /** + * Sets metadata for the specified queue. + * <p/> + * The request body has a limit of 256 KB, excluding whitespace. + * <p/> + * This operation replaces any existing metadata document in its entirety. Ensure that you do not accidentally + * overwrite existing metadata that you want to retain. + * + * @param name Name of the queue. The name must not exceed 64 bytes in length, and it is limited to US-ASCII + * letters, digits, underscores, and hyphens. + * @param metadata Metadata in key/value pairs. + */ + @Named("queue:setMetadata") + @PUT + @Path("queues/{name}/metadata") + @Produces(MediaType.APPLICATION_JSON) + @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + boolean setMetadata(@PathParam("name") String name, + @BinderParam(BindToJsonPayload.class) Map<String, String> metadata); + + /** + * Gets metadata for the specified queue. + * + * @param name Name of the queue. The name must not exceed 64 bytes in length, and it is limited to US-ASCII + * letters, digits, underscores, and hyphens. + */ + @Named("queue:getMetadata") + @GET + @Path("queues/{name}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + Map<String, String> getMetadata(@PathParam("name") String name); + + + /** + * Gets stats for the specified queue. + * + * @param name Name of the queue. The name must not exceed 64 bytes in length, and it is limited to US-ASCII + * letters, digits, underscores, and hyphens. + */ + @Named("queue:getStats") + @GET + @Path("queues/{name}/stats") + @Consumes(MediaType.APPLICATION_JSON) + @Fallback(Fallbacks.FalseOnNotFoundOr404.class) + QueueStats getStats(@PathParam("name") String name); } http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/60fd86d3/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/handlers/MarconiErrorHandler.java ---------------------------------------------------------------------- diff --git a/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/handlers/MarconiErrorHandler.java b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/handlers/MarconiErrorHandler.java index dd6c603..098fa17 100644 --- a/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/handlers/MarconiErrorHandler.java +++ b/openstack-marconi/src/main/java/org/jclouds/openstack/marconi/v1/handlers/MarconiErrorHandler.java @@ -29,11 +29,14 @@ public class MarconiErrorHandler implements HttpErrorHandler { public void handleError(HttpCommand command, HttpResponse response) { // it is important to always read fully and close streams byte[] data = closeClientButKeepContentStream(response); - String message = (data != null) ? new String(data) : null; + Exception exception; - Exception exception = (message != null) ? - new HttpResponseException(command, response, message) : - new HttpResponseException(command, response); + if (data == null) { + exception = new HttpResponseException(command, response); + } + else { + exception = new HttpResponseException(command, response, new String(data)); + } switch (response.getStatusCode()) { case 401: @@ -43,6 +46,7 @@ public class MarconiErrorHandler implements HttpErrorHandler { exception = new IllegalStateException(exception.getMessage(), exception); break; } + command.setException(exception); } } http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/60fd86d3/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiLiveTest.java ---------------------------------------------------------------------- diff --git a/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiLiveTest.java b/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiLiveTest.java index 86f1f0d..7c1341f 100644 --- a/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiLiveTest.java +++ b/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiLiveTest.java @@ -16,12 +16,18 @@ */ package org.jclouds.openstack.marconi.v1.features; +import com.google.common.collect.ImmutableMap; +import org.jclouds.openstack.marconi.v1.domain.QueueStats; import org.jclouds.openstack.marconi.v1.internal.BaseMarconiApiLiveTest; import org.testng.annotations.Test; +import java.util.Map; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; -@Test(groups = "live", testName = "QueueApiLiveTest") +@Test(groups = "live", testName = "QueueApiLiveTest", singleThreaded = true) public class QueueApiLiveTest extends BaseMarconiApiLiveTest { public void create() throws Exception { @@ -32,4 +38,69 @@ public class QueueApiLiveTest extends BaseMarconiApiLiveTest { assertTrue(success); } } + + @Test(dependsOnMethods = { "create" }) + public void exists() throws Exception { + for (String zoneId : api.getConfiguredZones()) { + QueueApi queueApi = api.getQueueApiForZone(zoneId); + boolean success = queueApi.exists("jclouds-test"); + + assertTrue(success); + } + } + + @Test(dependsOnMethods = { "exists" }) + public void setMetadata() throws Exception { + for (String zoneId : api.getConfiguredZones()) { + QueueApi queueApi = api.getQueueApiForZone(zoneId); + Map<String, String> metadata = ImmutableMap.of("key1", "value1"); + boolean success = queueApi.setMetadata("jclouds-test", metadata); + + assertTrue(success); + } + } + + @Test(dependsOnMethods = { "setMetadata" }) + public void getMetadata() throws Exception { + for (String zoneId : api.getConfiguredZones()) { + QueueApi queueApi = api.getQueueApiForZone(zoneId); + Map<String, String> metadata = queueApi.getMetadata("jclouds-test"); + + assertEquals(metadata.get("key1"), "value1"); + } + } + + @Test(dependsOnMethods = { "getMetadata" }) + public void getStatsWithoutTotal() throws Exception { + for (String zoneId : api.getConfiguredZones()) { + QueueApi queueApi = api.getQueueApiForZone(zoneId); + QueueStats stats = queueApi.getStats("jclouds-test"); + + assertEquals(stats.getMessagesStats().getClaimed(), 0); + assertEquals(stats.getMessagesStats().getFree(), 0); + assertEquals(stats.getMessagesStats().getTotal(), 0); + assertFalse(stats.getMessagesStats().getOldest().isPresent()); + assertFalse(stats.getMessagesStats().getNewest().isPresent()); + } + } + + @Test(dependsOnMethods = { "getStatsWithoutTotal" }) + public void delete() throws Exception { + for (String zoneId : api.getConfiguredZones()) { + QueueApi queueApi = api.getQueueApiForZone(zoneId); + boolean success = queueApi.delete("jclouds-test"); + + assertTrue(success); + } + } + + @Test(dependsOnMethods = { "delete" }) + public void doesNotExist() throws Exception { + for (String zoneId : api.getConfiguredZones()) { + QueueApi queueApi = api.getQueueApiForZone(zoneId); + boolean success = queueApi.exists("jclouds-test"); + + assertFalse(success); + } + } } http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/60fd86d3/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiMockTest.java ---------------------------------------------------------------------- diff --git a/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiMockTest.java b/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiMockTest.java index db0caf0..02e0488 100644 --- a/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiMockTest.java +++ b/openstack-marconi/src/test/java/org/jclouds/openstack/marconi/v1/features/QueueApiMockTest.java @@ -16,13 +16,19 @@ */ package org.jclouds.openstack.marconi.v1.features; +import com.google.common.collect.ImmutableMap; import com.squareup.okhttp.mockwebserver.MockResponse; import com.squareup.okhttp.mockwebserver.MockWebServer; +import com.squareup.okhttp.mockwebserver.RecordedRequest; import org.jclouds.openstack.marconi.v1.MarconiApi; +import org.jclouds.openstack.marconi.v1.domain.QueueStats; import org.jclouds.openstack.v2_0.internal.BaseOpenStackMockTest; import org.testng.annotations.Test; +import java.util.Map; + import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; /** @@ -51,4 +57,138 @@ public class QueueApiMockTest extends BaseOpenStackMockTest<MarconiApi> { server.shutdown(); } } + + public void deleteQueue() throws Exception { + MockWebServer server = mockOpenStackServer(); + server.enqueue(new MockResponse().setBody(accessRackspace)); + server.enqueue(new MockResponse().setResponseCode(204)); + + try { + MarconiApi api = api(server.getUrl("/").toString(), "openstack-marconi"); + QueueApi queueApi = api.getQueueApiForZone("DFW"); + boolean success = queueApi.delete("jclouds-test"); + + assertTrue(success); + + assertEquals(server.getRequestCount(), 2); + assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); + assertEquals(server.takeRequest().getRequestLine(), "DELETE /v1/123123/queues/jclouds-test HTTP/1.1"); + } + finally { + server.shutdown(); + } + } + + public void existsQueue() throws Exception { + MockWebServer server = mockOpenStackServer(); + server.enqueue(new MockResponse().setBody(accessRackspace)); + server.enqueue(new MockResponse().setResponseCode(204)); + + try { + MarconiApi api = api(server.getUrl("/").toString(), "openstack-marconi"); + QueueApi queueApi = api.getQueueApiForZone("DFW"); + boolean success = queueApi.exists("jclouds-test"); + + assertTrue(success); + + assertEquals(server.getRequestCount(), 2); + assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); + assertEquals(server.takeRequest().getRequestLine(), "GET /v1/123123/queues/jclouds-test HTTP/1.1"); + } + finally { + server.shutdown(); + } + } + + public void doesNotExistQueue() throws Exception { + MockWebServer server = mockOpenStackServer(); + server.enqueue(new MockResponse().setBody(accessRackspace)); + server.enqueue(new MockResponse().setResponseCode(404)); + + try { + MarconiApi api = api(server.getUrl("/").toString(), "openstack-marconi"); + QueueApi queueApi = api.getQueueApiForZone("DFW"); + boolean success = queueApi.exists("jclouds-blerg"); + + assertFalse(success); + + assertEquals(server.getRequestCount(), 2); + assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); + assertEquals(server.takeRequest().getRequestLine(), "GET /v1/123123/queues/jclouds-blerg HTTP/1.1"); + } + finally { + server.shutdown(); + } + } + + public void setMetadata() throws Exception { + MockWebServer server = mockOpenStackServer(); + server.enqueue(new MockResponse().setBody(accessRackspace)); + server.enqueue(new MockResponse().setResponseCode(204)); + + try { + MarconiApi api = api(server.getUrl("/").toString(), "openstack-marconi"); + QueueApi queueApi = api.getQueueApiForZone("DFW"); + Map<String, String> metadata = ImmutableMap.of("key1", "value1"); + boolean success = queueApi.setMetadata("jclouds-test", metadata); + + assertTrue(success); + + assertEquals(server.getRequestCount(), 2); + assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); + RecordedRequest request = server.takeRequest(); + assertEquals(request.getRequestLine(), "PUT /v1/123123/queues/jclouds-test/metadata HTTP/1.1"); + assertEquals(request.getUtf8Body(), "{\"key1\":\"value1\"}"); + } + finally { + server.shutdown(); + } + } + + public void getMetadata() throws Exception { + MockWebServer server = mockOpenStackServer(); + server.enqueue(new MockResponse().setBody(accessRackspace)); + server.enqueue(new MockResponse().setResponseCode(200).setBody("{\"key1\":\"value1\"}")); + + try { + MarconiApi api = api(server.getUrl("/").toString(), "openstack-marconi"); + QueueApi queueApi = api.getQueueApiForZone("DFW"); + Map<String, String> metadata = queueApi.getMetadata("jclouds-test"); + + assertEquals(metadata.get("key1"), "value1"); + + assertEquals(server.getRequestCount(), 2); + assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); + assertEquals(server.takeRequest().getRequestLine(), "GET /v1/123123/queues/jclouds-test/metadata HTTP/1.1"); + } + finally { + server.shutdown(); + } + } + + public void getQueueStatsWithoutTotal() throws Exception { + MockWebServer server = mockOpenStackServer(); + server.enqueue(new MockResponse().setBody(accessRackspace)); + server.enqueue(new MockResponse().setResponseCode(200) + .setBody("{\"messages\":{\"claimed\":0,\"total\":0,\"free\":0}}")); + + try { + MarconiApi api = api(server.getUrl("/").toString(), "openstack-marconi"); + QueueApi queueApi = api.getQueueApiForZone("DFW"); + QueueStats stats = queueApi.getStats("jclouds-test"); + + assertEquals(stats.getMessagesStats().getClaimed(), 0); + assertEquals(stats.getMessagesStats().getFree(), 0); + assertEquals(stats.getMessagesStats().getTotal(), 0); + assertFalse(stats.getMessagesStats().getOldest().isPresent()); + assertFalse(stats.getMessagesStats().getNewest().isPresent()); + + assertEquals(server.getRequestCount(), 2); + assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1"); + assertEquals(server.takeRequest().getRequestLine(), "GET /v1/123123/queues/jclouds-test/stats HTTP/1.1"); + } + finally { + server.shutdown(); + } + } } http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/60fd86d3/rackspace-cloudqueues-us/src/main/java/org/jclouds/rackspace/cloudqueues/us/CloudQueuesUSProviderMetadata.java ---------------------------------------------------------------------- diff --git a/rackspace-cloudqueues-us/src/main/java/org/jclouds/rackspace/cloudqueues/us/CloudQueuesUSProviderMetadata.java b/rackspace-cloudqueues-us/src/main/java/org/jclouds/rackspace/cloudqueues/us/CloudQueuesUSProviderMetadata.java index 95d8c0c..0baf912 100644 --- a/rackspace-cloudqueues-us/src/main/java/org/jclouds/rackspace/cloudqueues/us/CloudQueuesUSProviderMetadata.java +++ b/rackspace-cloudqueues-us/src/main/java/org/jclouds/rackspace/cloudqueues/us/CloudQueuesUSProviderMetadata.java @@ -84,7 +84,7 @@ public class CloudQueuesUSProviderMetadata extends BaseProviderMetadata { .identityName("${userName}") .credentialName("${apiKey}") .defaultEndpoint("https://identity.api.rackspacecloud.com/v2.0/") - .endpointName("identity service url ending in /v2.0/") + .endpointName("Rackspace Cloud Identity service URL ending in /v2.0/") .documentation(URI.create("http://docs.rackspace.com/queues/api/v1.0/cq-devguide/content/overview.html")) .defaultModules(ImmutableSet.<Class<? extends Module>>builder() .add(CloudIdentityAuthenticationApiModule.class)
