Skip to content
Permalink
Browse files
The get and delete methods for the Marconi Message API.
  • Loading branch information
Everett Toews committed Nov 25, 2013
1 parent 3e54454 commit ed814ce29f9ab402e9dde12a31f7d2990f8dc45c
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 31 deletions.
@@ -36,7 +36,7 @@ public class BindIdsToQueryParam implements Binder {
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
checkArgument(input instanceof Iterable<?>, "This binder is only valid for Iterable");
Iterable<String> ids = (Iterable<String>) checkNotNull(input, "Iterable of Strings");
Iterable<String> ids = (Iterable<String>) input;
checkArgument(Iterables.size(ids) > 0, "You must specify at least one id");

return (R) request.toBuilder().replaceQueryParam("ids", Joiner.on(',').join(ids)).build();
@@ -37,7 +37,7 @@ public class Queue {
private final Map<String, String> metadata;

protected Queue(String name, @Nullable Map<String, String> metadata) {
this.name = checkNotNull(name, "id required");
this.name = checkNotNull(name, "name required");
this.metadata = metadata;
}

@@ -16,16 +16,16 @@
*/
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.binders.BindIdsToQueryParam;
import org.jclouds.openstack.marconi.v1.domain.CreateMessage;
import org.jclouds.openstack.marconi.v1.domain.Message;
import org.jclouds.openstack.marconi.v1.domain.MessageStream;
import org.jclouds.openstack.marconi.v1.domain.MessagesCreated;
import org.jclouds.openstack.marconi.v1.functions.ParseMessagesToStream;
import org.jclouds.openstack.marconi.v1.functions.ParseMessage;
import org.jclouds.openstack.marconi.v1.functions.ParseMessagesCreated;
import org.jclouds.openstack.marconi.v1.functions.ParseMessagesToList;
import org.jclouds.openstack.marconi.v1.functions.ParseMessagesToStream;
import org.jclouds.openstack.marconi.v1.options.StreamMessagesOptions;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.Fallback;
@@ -36,16 +36,19 @@

import javax.inject.Named;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.UUID;

import static org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
import static org.jclouds.Fallbacks.FalseOnNotFoundOr404;
import static org.jclouds.Fallbacks.NullOnNotFoundOr404;
import static org.jclouds.openstack.keystone.v2_0.KeystoneFallbacks.EmptyPaginatedCollectionOnNotFoundOr404;

/**
@@ -71,7 +74,7 @@ public interface MessageApi {
@POST
@Path("/messages")
@ResponseParser(ParseMessagesCreated.class)
@Fallback(Fallbacks.FalseOnNotFoundOr404.class)
@Fallback(NullOnNotFoundOr404.class)
MessagesCreated create(@HeaderParam("Client-ID") UUID clientId,
@BinderParam(BindToJsonPayload.class) List<CreateMessage> messages);

@@ -92,7 +95,7 @@ MessageStream stream(@HeaderParam("Client-ID") UUID clientId,
StreamMessagesOptions... options);

/**
* List specific messages. Unlike the stream method, a client's own messages are always returned in this operation.
* Lists specific messages. Unlike the stream method, a client's own messages are always returned in this operation.
*
* @param clientId A UUID for each client instance.
* @param ids Specifies the IDs of the messages to get.
@@ -107,4 +110,36 @@ List<Message> list(@HeaderParam("Client-ID") UUID clientId,
@BinderParam(BindIdsToQueryParam.class) Iterable<String> ids);

// TODO: list by claim id when claim API done

/**
* Gets a specific message. Unlike the stream method, a client's own messages are always returned in this operation.
*
* @param clientId A UUID for each client instance.
* @param id Specific ID of the message to get.
*/
@Named("message:get")
@GET
@ResponseParser(ParseMessage.class)
@Consumes(MediaType.APPLICATION_JSON)
@Path("/messages/{message_id}")
@Fallback(NullOnNotFoundOr404.class)
Message get(@HeaderParam("Client-ID") UUID clientId,
@PathParam("message_id") String id);

/**
* Deletes specific messages. If any of the message IDs are malformed or non-existent, they are ignored. The
* remaining valid messages IDs are deleted.
*
* @param clientId A UUID for each client instance.
* @param ids Specifies the IDs of the messages to delete.
*/
@Named("message:delete")
@DELETE
@Consumes(MediaType.APPLICATION_JSON)
@Path("/messages")
@Fallback(FalseOnNotFoundOr404.class)
boolean delete(@HeaderParam("Client-ID") UUID clientId,
@BinderParam(BindIdsToQueryParam.class) Iterable<String> ids);

// TODO: delete by claim id when claim API done
}
@@ -94,7 +94,7 @@ public interface QueueApi {
boolean exists(@PathParam("name") String name);

/**
* List the queues.
* Lists the queues.
*
* @param detailed Determines whether queue metadata is included in the list.
*/
@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.openstack.marconi.v1.functions;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.openstack.marconi.v1.domain.Message;

import javax.inject.Inject;
import java.util.List;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.transform;
import static org.jclouds.openstack.marconi.v1.functions.ParseMessagesToStream.MessageWithHref;
import static org.jclouds.openstack.marconi.v1.functions.ParseMessagesToStream.TO_MESSAGE;

/**
* @author Everett Toews
*/
public class ParseMessage implements Function<HttpResponse, Message> {

private final ParseJson<MessageWithHref> json;

@Inject
ParseMessage(ParseJson<MessageWithHref> json) {
this.json = checkNotNull(json, "json");
}

@Override
public Message apply(HttpResponse response) {
MessageWithHref messagesWithHref = json.apply(response);

return TO_MESSAGE.apply(messagesWithHref);
}
}
@@ -52,6 +52,6 @@ public List<Message> apply(HttpResponse response) {
}

List<MessageWithHref> messagesWithHref = json.apply(response);
return Lists.newArrayList(transform(messagesWithHref, TO_MESSAGE));
return ImmutableList.copyOf(transform(messagesWithHref, TO_MESSAGE));
}
}
@@ -31,6 +31,7 @@
import java.util.Map;
import java.util.UUID;

import static com.google.common.collect.Iterables.getLast;
import static org.jclouds.openstack.marconi.v1.options.StreamMessagesOptions.Builder.echo;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
@@ -43,7 +44,7 @@ public class MessageApiLiveTest extends BaseMarconiApiLiveTest {
private final Map<String, List<String>> messageIds = Maps.newHashMap();

public void createQueues() throws Exception {
for (String zoneId : api.getConfiguredZones()) {
for (String zoneId : zones) {
QueueApi queueApi = api.getQueueApiForZone(zoneId);
boolean success = queueApi.create("jclouds-test");

@@ -53,7 +54,7 @@ public void createQueues() throws Exception {

@Test(dependsOnMethods = { "createQueues" })
public void streamZeroPagesOfMessages() throws Exception {
for (String zoneId : api.getConfiguredZones()) {
for (String zoneId : zones) {
MessageApi messageApi = api.getMessageApiForZoneAndQueue(zoneId, "jclouds-test");
UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");

@@ -66,7 +67,7 @@ public void streamZeroPagesOfMessages() throws Exception {

@Test(dependsOnMethods = { "streamZeroPagesOfMessages" })
public void createMessage() throws Exception {
for (String zoneId : api.getConfiguredZones()) {
for (String zoneId : zones) {
MessageApi messageApi = api.getMessageApiForZoneAndQueue(zoneId, "jclouds-test");

UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");
@@ -83,7 +84,7 @@ public void createMessage() throws Exception {

@Test(dependsOnMethods = { "createMessage" })
public void streamOnePageOfMessages() throws Exception {
for (String zoneId : api.getConfiguredZones()) {
for (String zoneId : zones) {
MessageApi messageApi = api.getMessageApiForZoneAndQueue(zoneId, "jclouds-test");
UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");

@@ -101,7 +102,7 @@ public void streamOnePageOfMessages() throws Exception {

@Test(dependsOnMethods = { "streamOnePageOfMessages" })
public void createMessages() throws Exception {
for (String zoneId : api.getConfiguredZones()) {
for (String zoneId : zones) {
MessageApi messageApi = api.getMessageApiForZoneAndQueue(zoneId, "jclouds-test");

UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");
@@ -122,7 +123,7 @@ public void createMessages() throws Exception {

@Test(dependsOnMethods = { "createMessages" })
public void streamManyPagesOfMessages() throws Exception {
for (String zoneId : api.getConfiguredZones()) {
for (String zoneId : zones) {
MessageApi messageApi = api.getMessageApiForZoneAndQueue(zoneId, "jclouds-test");
UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");
messageIds.put(zoneId, new ArrayList<String>());
@@ -145,7 +146,7 @@ public void streamManyPagesOfMessages() throws Exception {

@Test(dependsOnMethods = { "streamManyPagesOfMessages" })
public void listMessagesByIds() throws Exception {
for (String zoneId : api.getConfiguredZones()) {
for (String zoneId : zones) {
MessageApi messageApi = api.getMessageApiForZoneAndQueue(zoneId, "jclouds-test");
UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");

@@ -161,8 +162,33 @@ public void listMessagesByIds() throws Exception {
}

@Test(dependsOnMethods = { "listMessagesByIds" })
public void getMessage() throws Exception {
for (String zoneId : zones) {
MessageApi messageApi = api.getMessageApiForZoneAndQueue(zoneId, "jclouds-test");
UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");

Message message = messageApi.get(clientId, getLast(messageIds.get(zoneId)));

assertNotNull(message.getId());
assertNotNull(message.getBody());
}
}

@Test(dependsOnMethods = { "getMessage" })
public void deleteMessages() throws Exception {
for (String zoneId : zones) {
MessageApi messageApi = api.getMessageApiForZoneAndQueue(zoneId, "jclouds-test");
UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");

boolean success = messageApi.delete(clientId, messageIds.get(zoneId));

assertTrue(success);
}
}

@Test(dependsOnMethods = { "deleteMessages" })
public void delete() throws Exception {
for (String zoneId : api.getConfiguredZones()) {
for (String zoneId : zones) {
QueueApi queueApi = api.getQueueApiForZone(zoneId);
boolean success = queueApi.delete("jclouds-test");

@@ -227,4 +227,54 @@ public void listMessagesByIds() throws Exception {
server.shutdown();
}
}

public void getMessage() throws Exception {
MockWebServer server = mockOpenStackServer();
server.enqueue(new MockResponse().setBody(accessRackspace));
server.enqueue(new MockResponse().setResponseCode(200).setBody("{\"body\": \"{\\\"event\\\":{\\\"name\\\":\\\"Edmonton Java User Group\\\",\\\"attendees\\\":[\\\"bob\\\",\\\"jim\\\",\\\"sally\\\"]}}\", \"age\": 266, \"href\": \"/v1/queues/jclouds-test/messages/5292b30cef913e6d026f4dec\", \"ttl\": 86400}"));

try {
MarconiApi api = api(server.getUrl("/").toString(), "openstack-marconi");
MessageApi messageApi = api.getMessageApiForZoneAndQueue("DFW", "jclouds-test");
UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");

Message message = messageApi.get(clientId, "5292b30cef913e6d026f4dec");

assertEquals(message.getId(), "5292b30cef913e6d026f4dec");
assertEquals(message.getBody(), "{\"event\":{\"name\":\"Edmonton Java User Group\",\"attendees\":[\"bob\",\"jim\",\"sally\"]}}");
assertEquals(message.getAge(), 266);
assertEquals(message.getTTL(), 86400);

assertEquals(server.getRequestCount(), 2);
assertEquals(server.takeRequest().getRequestLine(), "POST /tokens HTTP/1.1");
assertEquals(server.takeRequest().getRequestLine(), "GET /v1/123123/queues/jclouds-test/messages/5292b30cef913e6d026f4dec HTTP/1.1");
}
finally {
server.shutdown();
}
}

public void deleteMessages() 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");
MessageApi messageApi = api.getMessageApiForZoneAndQueue("DFW", "jclouds-test");
UUID clientId = UUID.fromString("3381af92-2b9e-11e3-b191-71861300734c");
List<String> ids = ImmutableList.of("52936b8a3ac24e6ef4c067dd", "5292b30cef913e6d026f4dec");

boolean success = messageApi.delete(clientId, ids);

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/messages?ids=52936b8a3ac24e6ef4c067dd,5292b30cef913e6d026f4dec HTTP/1.1");
}
finally {
server.shutdown();
}
}
}

0 comments on commit ed814ce

Please sign in to comment.