diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/MessageAsyncApi.java b/labs/sqs/src/main/java/org/jclouds/sqs/MessageAsyncApi.java deleted file mode 100644 index c52701cfb4..0000000000 --- a/labs/sqs/src/main/java/org/jclouds/sqs/MessageAsyncApi.java +++ /dev/null @@ -1,130 +0,0 @@ -/** - * 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.sqs; - -import static org.jclouds.sqs.reference.SQSParameters.ACTION; -import static org.jclouds.sqs.reference.SQSParameters.VERSION; - -import java.util.Set; - -import javax.ws.rs.FormParam; -import javax.ws.rs.POST; -import javax.ws.rs.Path; - -import org.jclouds.Constants; -import org.jclouds.aws.filters.FormSigner; -import org.jclouds.rest.annotations.FormParams; -import org.jclouds.rest.annotations.RequestFilters; -import org.jclouds.rest.annotations.ResponseParser; -import org.jclouds.rest.annotations.VirtualHost; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.sqs.domain.Message; -import org.jclouds.sqs.domain.MessageIdAndMD5; -import org.jclouds.sqs.options.ReceiveMessageOptions; -import org.jclouds.sqs.options.SendMessageOptions; -import org.jclouds.sqs.xml.MessageHandler; -import org.jclouds.sqs.xml.ReceiveMessageResponseHandler; -import org.jclouds.sqs.xml.RegexMessageIdAndMD5Handler; - -import com.google.common.util.concurrent.ListenableFuture; - -/** - * Provides access to SQS via their REST API. - * <p/> - * - * @author Adrian Cole - */ -@RequestFilters(FormSigner.class) -@FormParams(keys = VERSION, values = "{" + Constants.PROPERTY_API_VERSION + "}") -@VirtualHost -public interface MessageAsyncApi { - - /** - * @see SQSApi#delete - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "DeleteMessage") - ListenableFuture<Void> delete(@FormParam("ReceiptHandle") String receiptHandle); - - /** - * @see SQSApi#changeVisibility - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "ChangeMessageVisibility") - ListenableFuture<Void> changeVisibility(@FormParam("ReceiptHandle") String receiptHandle, - @FormParam("VisibilityTimeout") int visibilityTimeout); - - /** - * @see SQSApi#send - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "SendMessage") - @ResponseParser(RegexMessageIdAndMD5Handler.class) - ListenableFuture<? extends MessageIdAndMD5> send(@FormParam("MessageBody") String message); - - /** - * @see SQSApi#send - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "SendMessage") - @ResponseParser(RegexMessageIdAndMD5Handler.class) - ListenableFuture<? extends MessageIdAndMD5> send(@FormParam("MessageBody") String message, SendMessageOptions options); - - /** - * @see SQSApi#receive - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "ReceiveMessage") - @XMLResponseParser(MessageHandler.class) - ListenableFuture<Message> receive(); - - /** - * @see SQSApi#receive - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "ReceiveMessage") - @XMLResponseParser(MessageHandler.class) - ListenableFuture<? extends Message> receive(ReceiveMessageOptions options); - - /** - * @see SQSApi#receive - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "ReceiveMessage") - @XMLResponseParser(ReceiveMessageResponseHandler.class) - ListenableFuture<? extends Set<? extends Message>> receive(@FormParam("MaxNumberOfMessages") int max); - - /** - * @see SQSApi#receive - */ - @POST - @Path("/") - @FormParams(keys = ACTION, values = "ReceiveMessage") - @XMLResponseParser(ReceiveMessageResponseHandler.class) - ListenableFuture<? extends Set<? extends Message>> receive(@FormParam("MaxNumberOfMessages") int max, - ReceiveMessageOptions options); - -} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/SQSApi.java b/labs/sqs/src/main/java/org/jclouds/sqs/SQSApi.java index 51636dbf0d..8804e24904 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/SQSApi.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/SQSApi.java @@ -28,6 +28,9 @@ import org.jclouds.location.Region; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.EndpointParam; +import org.jclouds.sqs.features.MessageApi; +import org.jclouds.sqs.features.PermissionApi; +import org.jclouds.sqs.features.QueueApi; import com.google.common.annotations.Beta; import com.google.inject.Provides; diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/SQSAsyncApi.java b/labs/sqs/src/main/java/org/jclouds/sqs/SQSAsyncApi.java index 164b3e98e7..c9a8f0ed56 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/SQSAsyncApi.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/SQSAsyncApi.java @@ -29,6 +29,9 @@ import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.sqs.features.MessageAsyncApi; +import org.jclouds.sqs.features.PermissionAsyncApi; +import org.jclouds.sqs.features.QueueAsyncApi; import com.google.common.annotations.Beta; import com.google.inject.Provides; diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams.java b/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams.java new file mode 100644 index 0000000000..1a722aa84c --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams.java @@ -0,0 +1,69 @@ +/** + * 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.sqs.binders; + +import java.util.Map; + +import org.jclouds.aws.binders.BindTableToIndexedFormParams; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.MapBinder; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.ImmutableTable.Builder; +import com.google.common.collect.Maps; + +/** + * @author Adrian Cole + */ +public class BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams extends BindTableToIndexedFormParams + implements MapBinder { + + protected BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams() { + super("ChangeMessageVisibilityBatchRequestEntry.%d.Id", + "ChangeMessageVisibilityBatchRequestEntry.%d.ReceiptHandle", + "ChangeMessageVisibilityBatchRequestEntry.%d.VisibilityTimeout"); + } + + public Map<String, String> idReceiptHandle(Iterable<String> input) { + return Maps.uniqueIndex((Iterable<String>) input, new Function<String, String>() { + int index = 1; + + @Override + public String apply(String input) { + return index++ + ""; + } + }); + } + + @SuppressWarnings("unchecked") + @Override + public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) { + Map<String, String> idReceiptHandle = (Map<String, String>) postParams.get("idReceiptHandle"); + if (idReceiptHandle == null) { + idReceiptHandle = idReceiptHandle((Iterable<String>) postParams.get("receiptHandles")); + } + int visibilityTimeout = (Integer) postParams.get("visibilityTimeout"); + + Builder<Object, Object, Object> builder = ImmutableTable.builder(); + for (Map.Entry<?, ?> entry : idReceiptHandle.entrySet()) + builder.put(entry.getKey(), entry.getValue(), visibilityTimeout); + return bindToRequest(request, (Object) builder.build()); + } +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindDeleteMessageBatchRequestEntryToIndexedFormParams.java b/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindDeleteMessageBatchRequestEntryToIndexedFormParams.java new file mode 100644 index 0000000000..dd1ba5e9ad --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindDeleteMessageBatchRequestEntryToIndexedFormParams.java @@ -0,0 +1,31 @@ +/** + * 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.sqs.binders; + +import org.jclouds.aws.binders.BindMapToIndexedFormParams; + +/** + * @author Adrian Cole + */ +public class BindDeleteMessageBatchRequestEntryToIndexedFormParams extends BindMapToIndexedFormParams { + + protected BindDeleteMessageBatchRequestEntryToIndexedFormParams() { + super("DeleteMessageBatchRequestEntry.%d.Id", "DeleteMessageBatchRequestEntry.%d.ReceiptHandle"); + } +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindSendMessageBatchRequestEntryToIndexedFormParams.java b/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindSendMessageBatchRequestEntryToIndexedFormParams.java new file mode 100644 index 0000000000..748c7d0fcb --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindSendMessageBatchRequestEntryToIndexedFormParams.java @@ -0,0 +1,31 @@ +/** + * 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.sqs.binders; + +import org.jclouds.aws.binders.BindMapToIndexedFormParams; + +/** + * @author Adrian Cole + */ +public class BindSendMessageBatchRequestEntryToIndexedFormParams extends BindMapToIndexedFormParams { + + protected BindSendMessageBatchRequestEntryToIndexedFormParams() { + super("SendMessageBatchRequestEntry.%d.Id", "SendMessageBatchRequestEntry.%d.MessageBody"); + } +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams.java b/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams.java new file mode 100644 index 0000000000..0727a47989 --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/binders/BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams.java @@ -0,0 +1,68 @@ +/** + * 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.sqs.binders; + +import java.util.Map; + +import org.jclouds.aws.binders.BindTableToIndexedFormParams; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.MapBinder; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.ImmutableTable.Builder; +import com.google.common.collect.Maps; + +/** + * @author Adrian Cole + */ +public class BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams extends BindTableToIndexedFormParams + implements MapBinder { + + protected BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams() { + super("SendMessageBatchRequestEntry.%d.Id", "SendMessageBatchRequestEntry.%d.MessageBody", + "SendMessageBatchRequestEntry.%d.DelaySeconds"); + } + + public Map<String, String> idMessageBody(Iterable<String> input) { + return Maps.uniqueIndex((Iterable<String>) input, new Function<String, String>() { + int index = 1; + + @Override + public String apply(String input) { + return index++ + ""; + } + }); + } + + @SuppressWarnings("unchecked") + @Override + public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) { + Map<String, String> idMessageBody = (Map<String, String>) postParams.get("idMessageBody"); + if (idMessageBody == null) { + idMessageBody = idMessageBody((Iterable<String>) postParams.get("messageBodies")); + } + int delaySeconds = (Integer) postParams.get("delaySeconds"); + + Builder<Object, Object, Object> builder = ImmutableTable.builder(); + for (Map.Entry<?, ?> entry : idMessageBody.entrySet()) + builder.put(entry.getKey(), entry.getValue(), delaySeconds); + return bindToRequest(request, (Object) builder.build()); + } +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/config/SQSRestClientModule.java b/labs/sqs/src/main/java/org/jclouds/sqs/config/SQSRestClientModule.java index 1839c951b6..09b4882d07 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/config/SQSRestClientModule.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/config/SQSRestClientModule.java @@ -27,14 +27,14 @@ import org.jclouds.http.annotation.ClientError; import org.jclouds.http.annotation.Redirection; import org.jclouds.http.annotation.ServerError; import org.jclouds.rest.ConfiguresRestClient; -import org.jclouds.sqs.MessageApi; -import org.jclouds.sqs.MessageAsyncApi; -import org.jclouds.sqs.PermissionApi; -import org.jclouds.sqs.PermissionAsyncApi; -import org.jclouds.sqs.QueueApi; -import org.jclouds.sqs.QueueAsyncApi; import org.jclouds.sqs.SQSApi; import org.jclouds.sqs.SQSAsyncApi; +import org.jclouds.sqs.features.MessageApi; +import org.jclouds.sqs.features.MessageAsyncApi; +import org.jclouds.sqs.features.PermissionApi; +import org.jclouds.sqs.features.PermissionAsyncApi; +import org.jclouds.sqs.features.QueueApi; +import org.jclouds.sqs.features.QueueAsyncApi; import org.jclouds.sqs.handlers.ParseSQSErrorFromXmlContent; import org.jclouds.sqs.handlers.SQSErrorRetryHandler; diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/domain/BatchError.java b/labs/sqs/src/main/java/org/jclouds/sqs/domain/BatchError.java new file mode 100644 index 0000000000..45696f4d70 --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/domain/BatchError.java @@ -0,0 +1,155 @@ +/** + * 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.sqs.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Objects; + +/** + * + * @see <a + * href="http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QueryDeleteMessageBatch.html" + * >doc</a> + * + * @author Adrian Cole + */ +public class BatchError { + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return builder().fromErrorEntry(this); + } + + public static class Builder { + + private String id; + private boolean senderFault; + private String code; + private String message; + + /** + * @see BatchError#getId() + */ + public Builder id(String id) { + this.id = id; + return this; + } + + /** + * @see BatchError#isSenderFault() + */ + public Builder senderFault(boolean senderFault) { + this.senderFault = senderFault; + return this; + } + + /** + * @see BatchError#getCode() + */ + public Builder code(String code) { + this.code = code; + return this; + } + + /** + * @see BatchError#getMessage() + */ + public Builder message(String message) { + this.message = message; + return this; + } + + public BatchError build() { + return new BatchError(id, senderFault, code, message); + } + + public Builder fromErrorEntry(BatchError in) { + return id(in.getId()).senderFault(in.isSenderFault()).code(in.getCode()).message(in.getMessage()); + } + } + + private final String id; + private final boolean senderFault; + private final String code; + private final String message; + + private BatchError(String id, boolean senderFault, String code, String message) { + this.id = checkNotNull(id, "id"); + this.senderFault = checkNotNull(senderFault, "senderFault of %s", id); + this.code = checkNotNull(code, "code of %s", id); + this.message = checkNotNull(message, "message of %s", id); + } + + /** + * The Id name that you assigned to the message. + */ + public String getId() { + return id; + } + + /** + * + */ + public boolean isSenderFault() { + return senderFault; + } + + /** + * A short string description of the error. + */ + public String getCode() { + return code; + } + + /** + * A description of the error. + */ + public String getMessage() { + return message; + } + + @Override + public int hashCode() { + return Objects.hashCode(id); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + BatchError that = BatchError.class.cast(obj); + return Objects.equal(this.id, that.id); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return Objects.toStringHelper(this).omitNullValues().add("id", id).add("senderFault", senderFault) + .add("message", message).add("code", code).toString(); + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/domain/BatchResult.java b/labs/sqs/src/main/java/org/jclouds/sqs/domain/BatchResult.java new file mode 100644 index 0000000000..cbb2d4b496 --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/domain/BatchResult.java @@ -0,0 +1,146 @@ +/** + * 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.sqs.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Map; + +import com.google.common.base.Function; +import com.google.common.base.Objects; +import com.google.common.collect.ForwardingMap; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; + +/** + * + * @see <a + * href="http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/MessageLifecycle.html" + * >doc</a> + * + * @author Adrian Cole + */ +public class BatchResult<V> extends ForwardingMap<String, V> { + + public static <V> Builder<V> builder() { + return new Builder<V>(); + } + + public Builder<V> toBuilder() { + return BatchResult.<V> builder().fromBatchResult(this); + } + + public static class Builder<V> { + + private ImmutableMap.Builder<String, V> results = ImmutableMap.<String, V> builder(); + private ImmutableSet.Builder<BatchError> errors = ImmutableSet.<BatchError> builder(); + + /** + * @see BatchResult#getErrors() + */ + public Builder<V> addError(BatchError error) { + this.errors.add(checkNotNull(error, "error")); + return this; + } + + /** + * @see BatchResult#getErrors() + */ + public Builder<V> errors(Iterable<BatchError> errors) { + this.errors = ImmutableSet.<BatchError> builder().addAll(checkNotNull(errors, "errors")); + return this; + } + + /** + * @see BatchResult#get + */ + public Builder<V> putAll(Map<String, V> results) { + this.results.putAll(checkNotNull(results, "results")); + return this; + } + + /** + * @see BatchResult#get + */ + public Builder<V> put(String name, V value) { + this.results.put(checkNotNull(name, "name"), checkNotNull(value, "value")); + return this; + } + + public BatchResult<V> build() { + return new BatchResult<V>(results.build(), errors.build()); + } + + public Builder<V> fromBatchResult(BatchResult<V> in) { + return putAll(in).errors(in.getErrors().values()); + } + } + + private final Map<String, V> results; + private final Map<String, BatchError> errors; + + private BatchResult(Map<String, V> results, Iterable<BatchError> errors) { + this.results = ImmutableMap.copyOf(checkNotNull(results, "results")); + this.errors = Maps.uniqueIndex(checkNotNull(errors, "errors"), new Function<BatchError, String>() { + @Override + public String apply(BatchError in) { + return in.getId(); + } + + }); + } + + @Override + protected Map<String, V> delegate() { + return results; + } + + /** + * Errors indexed by requestor supplied id + */ + public Map<String, BatchError> getErrors() { + return errors; + } + + @Override + public int hashCode() { + return Objects.hashCode(results, errors); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null || getClass() != obj.getClass()) + return false; + @SuppressWarnings("unchecked") + BatchResult<V> that = BatchResult.class.cast(obj); + return Objects.equal(this.results, that.results) && Objects.equal(this.errors, that.errors); + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return Objects.toStringHelper(this).omitNullValues().add("results", results).add("errors", errors).toString(); + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/MessageApi.java b/labs/sqs/src/main/java/org/jclouds/sqs/features/MessageApi.java similarity index 52% rename from labs/sqs/src/main/java/org/jclouds/sqs/MessageApi.java rename to labs/sqs/src/main/java/org/jclouds/sqs/features/MessageApi.java index 63fdc8ce4a..fa4b96ae4a 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/MessageApi.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/features/MessageApi.java @@ -16,23 +16,27 @@ * specific language governing permissions and limitations * under the License. */ -package org.jclouds.sqs; +package org.jclouds.sqs.features; import java.net.URI; -import java.util.Set; +import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; import org.jclouds.concurrent.Timeout; +import org.jclouds.sqs.domain.BatchResult; import org.jclouds.sqs.domain.Message; import org.jclouds.sqs.domain.MessageIdAndMD5; import org.jclouds.sqs.options.ReceiveMessageOptions; import org.jclouds.sqs.options.SendMessageOptions; +import com.google.common.collect.Table; + /** * Provides access to SQS via their REST API. * <p/> * - * @see SQSAsyncApi + * @see MessageAsyncApi * @author Adrian Cole */ @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) @@ -72,6 +76,40 @@ public interface MessageApi { */ void delete(String receiptHandle); + /** + * Currently, you can send up to 10 {@link #delete} requests. + * + * <h4>Example usage</h4> + * + * <pre> + * BatchResult<String> results = api.delete(ImmutableMap.<String, String>builder() + * .put("id1", "handle1") + * .put("id2", "handle2") + * .build()); + * + * if (results.keySet().equals(ImmutableSet.of("id", "id2")) + * // all ok + * else + * results.getErrors(); + * </pre> + * + * @param idReceiptHandle + * id for correlating the result to receipt handle + * @return result that contains success or errors of the operation + * @see #delete(String) + */ + BatchResult<String> delete(Map<String, String> idReceiptHandle); + + /** + * Same as {@link #delete(Map)}, except that we generate numeric ids starting + * with {@code 1} + * + * @param receiptHandles + * receipt handles to delete + * @see #delete(Map) + */ + BatchResult<String> delete(Iterable<String> receiptHandles); + /** * The ChangeMessageVisibility action changes the visibility timeout of a * specified message in a queue to a new value. The maximum allowed timeout @@ -114,6 +152,77 @@ public interface MessageApi { */ void changeVisibility(String receiptHandle, int visibilityTimeout); + /** + * Currently, you can send up to 10 {@link #changeVisibility} requests. + * + * action. <h4>Example usage</h4> + * + * <pre> + * BatchResult<String> results = api.changeVisibility(ImmutableTable.<String, String, Integer>builder() + * .put("id1", "handle1", 45) + * .put("id2", "handle2", 10) + * .build()); + * + * if (results.keySet().equals(ImmutableSet.of("id", "id2")) + * // all ok + * else + * results.getErrors(); + * </pre> + * + * @param idReceiptHandleVisibilityTimeout + * id for correlating the result, receipt handle, and visibility + * timeout + * @return result that contains success or errors of the operation + * @see #changeVisibility(String, int) + */ + BatchResult<String> changeVisibility(Table<String, String, Integer> idReceiptHandleVisibilityTimeout); + + /** + * Same as {@link #changeVisibility(Table)}, except that we generate numeric + * ids starting with {@code 1} + * + * @param receiptHandleVisibilityTimeout + * receipt handle to visibility timeout + * @see #changeVisibility(Table) + */ + BatchResult<? extends MessageIdAndMD5> changeVisibility(Map<String, Integer> receiptHandleVisibilityTimeout); + + /** + * Currently, you can send up to 10 {@link #changeVisibility} requests. + * + * action. <h4>Example usage</h4> + * + * <pre> + * BatchResult<String> results = api.changeVisibility(ImmutableMap.<String, String>builder() + * .put("id1", "handle1") + * .put("id2", "handle2") + * .build(), 45); + * + * if (results.keySet().equals(ImmutableSet.of("id", "id2")) + * // all ok + * else + * results.getErrors(); + * </pre> + * + * @param idReceiptHandle + * id for correlating the result to receipt handle + * @param visibilityTimeout + * The new value for the message's visibility timeout (in seconds). + * @return result that contains success or errors of the operation + * @see #changeVisibility(String, int) + */ + BatchResult<String> changeVisibility(Map<String, String> idReceiptHandle, int visibilityTimeout); + + /** + * Same as {@link #changeVisibility(Map, int)}, except that we generate + * numeric ids starting with {@code 1} + * + * @param receiptHandles + * receipt handles to change visibility + * @see #changeVisibility(Map, int) + */ + BatchResult<String> changeVisibility(Iterable<String> receiptHandles, int visibilityTimeout); + /** * The SendMessage action delivers a message to the specified queue. The * maximum allowed message size is 64 KB. @@ -138,6 +247,107 @@ public interface MessageApi { */ MessageIdAndMD5 send(String message); + /** + * Same as {@link #send(Map)} except you can set a delay for each message in + * the request. + * + * <h4>Example usage</h4> + * + * <pre> + * BatchResult<? extends MessageIdAndMD5> results = api.sendWithDelays(ImmutableTable.<String, String, Integer>builder() + * .put("id1", "test message one", 1) + * .put("id2", "test message two", 10) + * .build()); + * + * if (results.keySet().equals(ImmutableSet.of("id", "id2")) + * // all ok + * else + * results.getErrors(); + * </pre> + * + * @param idMessageBodyDelaySeconds + * id for correlating the result, message body, and delay seconds + * + * @return result that contains success or errors of the operation + * @see #send(String, SendMessageOptions) + */ + BatchResult<? extends MessageIdAndMD5> sendWithDelays(Table<String, String, Integer> idMessageBodyDelaySeconds); + + /** + * Same as {@link #sendWithDelays(Table)}, except that we generate numeric + * ids starting with {@code 1} + * + * @param messageBodyDelaySeconds + * message body to the delay desired + * @see #sendWithDelays(Table) + */ + BatchResult<? extends MessageIdAndMD5> sendWithDelays(Map<String, Integer> messageBodyDelaySeconds); + + /** + * Same as {@link #send(Map)} except you set a delay for all messages in the + * request + * + * @param delaySeconds + * The number of seconds to delay a specific message. Messages with + * a positive DelaySeconds value become available for processing + * after the delay time is finished. + * + * @see #send(String, SendMessageOptions) + */ + BatchResult<? extends MessageIdAndMD5> sendWithDelay(Map<String, String> idMessageBody, int delaySeconds); + + /** + * Same as {@link #sendWithDelay(Map, int)}, except that we generate numeric + * ids starting with {@code 1} + * + * @param messageBodies + * message bodies to send + * @see #sendWithDelay(Map, int) + */ + BatchResult<? extends MessageIdAndMD5> sendWithDelay(Iterable<String> messageBodies, int delaySeconds); + + /** + * The SendMessageBatch action delivers up to ten messages to the specified + * queue. The maximum allowed individual message size is 64 KiB (65,536 + * bytes). + * + * The maximum total payload size (i.e., the sum of all a batch's individual + * message lengths) is also 64 KiB (65,536 bytes). + * + * Currently, you can send up to 10 {@link #send} requests. + * + * action. <h4>Example usage</h4> + * + * <pre> + * BatchResult<? extends MessageIdAndMD5> results = api.send(ImmutableMap.<String, String>builder() + * .put("id1", "test message one") + * .put("id2", "test message two") + * .build()); + * + * if (results.keySet().equals(ImmutableSet.of("id", "id2")) + * // all ok + * else + * results.getErrors(); + * </pre> + * + * @param idMessageBody + * id for correlating the result to message body + * + * @return result that contains success or errors of the operation + * @see #send(String) + */ + BatchResult<? extends MessageIdAndMD5> send(Map<String, String> idMessageBody); + + /** + * Same as {@link #send(Map)}, except that we generate numeric ids starting + * with {@code 1} + * + * @param messageBodies + * message bodies to send + * @see #send(Map) + */ + BatchResult<? extends MessageIdAndMD5> send(Iterable<String> messageBodies); + /** * same as {@link #sendMessage(URI, String)} except you can control options * such as delay seconds. @@ -192,7 +402,7 @@ public interface MessageApi { * maximum messages to receive, current limit is 10 * @see #receive(URI) */ - Set<Message> receive(int max); + List<Message> receive(int max); /** * same as {@link #receive(URI, int)} except you can provide options like @@ -205,5 +415,5 @@ public interface MessageApi { * options such as VisibilityTimeout * @see #receive(URI, int) */ - Set<Message> receive(int max, ReceiveMessageOptions options); + List<Message> receive(int max, ReceiveMessageOptions options); } diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/features/MessageAsyncApi.java b/labs/sqs/src/main/java/org/jclouds/sqs/features/MessageAsyncApi.java new file mode 100644 index 0000000000..6eb9db388d --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/features/MessageAsyncApi.java @@ -0,0 +1,275 @@ +/** + * 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.sqs.features; + +import static org.jclouds.sqs.reference.SQSParameters.ACTION; +import static org.jclouds.sqs.reference.SQSParameters.VERSION; + +import java.util.List; +import java.util.Map; + +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.jclouds.Constants; +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.MapBinder; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.ResponseParser; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; +import org.jclouds.sqs.binders.BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams; +import org.jclouds.sqs.binders.BindDeleteMessageBatchRequestEntryToIndexedFormParams; +import org.jclouds.sqs.binders.BindSendMessageBatchRequestEntryToIndexedFormParams; +import org.jclouds.sqs.binders.BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams; +import org.jclouds.sqs.domain.BatchResult; +import org.jclouds.sqs.domain.Message; +import org.jclouds.sqs.domain.MessageIdAndMD5; +import org.jclouds.sqs.options.ReceiveMessageOptions; +import org.jclouds.sqs.options.SendMessageOptions; +import org.jclouds.sqs.xml.ChangeMessageVisibilityBatchResponseHandler; +import org.jclouds.sqs.xml.DeleteMessageBatchResponseHandler; +import org.jclouds.sqs.xml.MessageHandler; +import org.jclouds.sqs.xml.ReceiveMessageResponseHandler; +import org.jclouds.sqs.xml.RegexMessageIdAndMD5Handler; +import org.jclouds.sqs.xml.SendMessageBatchResponseHandler; + +import com.google.common.collect.Table; +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides access to SQS via their REST API. + * <p/> + * + * @author Adrian Cole + */ +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = "{" + Constants.PROPERTY_API_VERSION + "}") +@VirtualHost +public interface MessageAsyncApi { + + /** + * @see MessageApi#delete(String) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DeleteMessage") + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture<Void> delete(@FormParam("ReceiptHandle") String receiptHandle); + + /** + * @see MessageApi#delete(Map) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DeleteMessageBatch") + @XMLResponseParser(DeleteMessageBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<String>> delete( + @BinderParam(BindDeleteMessageBatchRequestEntryToIndexedFormParams.class) Map<String, String> idReceiptHandle); + + /** + * @see MessageApi#delete(Iterable) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DeleteMessageBatch") + @XMLResponseParser(DeleteMessageBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<String>> delete( + @BinderParam(BindDeleteMessageBatchRequestEntryToIndexedFormParams.class) Iterable<String> receiptHandles); + + /** + * @see MessageApi#changeVisibility(String, int) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ChangeMessageVisibility") + ListenableFuture<Void> changeVisibility(@FormParam("ReceiptHandle") String receiptHandle, + @FormParam("VisibilityTimeout") int visibilityTimeout); + + /** + * @see MessageApi#changeVisibility(Table) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ChangeMessageVisibilityBatch") + @XMLResponseParser(ChangeMessageVisibilityBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<String>> changeVisibility( + @BinderParam(BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams.class) Table<String, String, Integer> idReceiptHandleVisibilityTimeout); + + /** + * @see MessageApi#changeVisibility(Map) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ChangeMessageVisibilityBatch") + @XMLResponseParser(ChangeMessageVisibilityBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<String>> changeVisibility( + @BinderParam(BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams.class) Map<String, Integer> receiptHandleVisibilityTimeout); + + /** + * @see MessageApi#changeVisibility(Map, int) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ChangeMessageVisibilityBatch") + @MapBinder(BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams.class) + @XMLResponseParser(ChangeMessageVisibilityBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<String>> changeVisibility( + @PayloadParam("idReceiptHandle") Map<String, String> idReceiptHandle, + @PayloadParam("visibilityTimeout") int visibilityTimeout); + + /** + * @see MessageApi#changeVisibility(Iterable, int) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ChangeMessageVisibilityBatch") + @MapBinder(BindChangeMessageVisibilityBatchRequestEntryToIndexedFormParams.class) + @XMLResponseParser(ChangeMessageVisibilityBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<String>> changeVisibility( + @PayloadParam("receiptHandles") Iterable<String> receiptHandles, + @PayloadParam("visibilityTimeout") int visibilityTimeout); + + /** + * @see MessageApi#send(String) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "SendMessage") + @ResponseParser(RegexMessageIdAndMD5Handler.class) + ListenableFuture<? extends MessageIdAndMD5> send(@FormParam("MessageBody") String message); + + /** + * @see MessageApi#send(String, SendMessageOptions) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "SendMessage") + @ResponseParser(RegexMessageIdAndMD5Handler.class) + ListenableFuture<? extends MessageIdAndMD5> send(@FormParam("MessageBody") String message, SendMessageOptions options); + + /** + * @see MessageApi#sendWithDelays(Table) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "SendMessageBatch") + @ResponseParser(RegexMessageIdAndMD5Handler.class) + @XMLResponseParser(SendMessageBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<? extends MessageIdAndMD5>> sendWithDelays( + @BinderParam(BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams.class) Table<String, String, Integer> idMessageBodyDelaySeconds); + + /** + * @see MessageApi#sendWithDelays(Map) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "SendMessageBatch") + @ResponseParser(RegexMessageIdAndMD5Handler.class) + @XMLResponseParser(SendMessageBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<? extends MessageIdAndMD5>> sendWithDelays( + @BinderParam(BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams.class) Map<String, Integer> messageBodyDelaySeconds); + + /** + * @see MessageApi#sendWithDelay(Map, int) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "SendMessageBatch") + @MapBinder(BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams.class) + @XMLResponseParser(SendMessageBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<? extends MessageIdAndMD5>> sendWithDelay( + @PayloadParam("idMessageBody") Map<String, String> idMessageBody, + @PayloadParam("delaySeconds") int delaySeconds); + + /** + * @see MessageApi#sendWithDelay(Iterable, int) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "SendMessageBatch") + @MapBinder(BindSendMessageBatchRequestEntryWithDelaysToIndexedFormParams.class) + @XMLResponseParser(SendMessageBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<? extends MessageIdAndMD5>> sendWithDelay( + @PayloadParam("messageBodies") Iterable<String> messageBodies, @PayloadParam("delaySeconds") int delaySeconds); + + /** + * @see MessageApi#send(Map) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "SendMessageBatch") + @XMLResponseParser(SendMessageBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<? extends MessageIdAndMD5>> send( + @BinderParam(BindSendMessageBatchRequestEntryToIndexedFormParams.class) Map<String, String> idMessageBody); + + /** + * @see MessageApi#send(Iterable) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "SendMessageBatch") + @XMLResponseParser(SendMessageBatchResponseHandler.class) + ListenableFuture<? extends BatchResult<? extends MessageIdAndMD5>> send( + @BinderParam(BindSendMessageBatchRequestEntryToIndexedFormParams.class) Iterable<String> messageBodies); + + /** + * @see MessageApi#receive() + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ReceiveMessage") + @XMLResponseParser(MessageHandler.class) + ListenableFuture<Message> receive(); + + /** + * @see MessageApi#receive(ReceiveMessageOptions) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ReceiveMessage") + @XMLResponseParser(MessageHandler.class) + ListenableFuture<? extends Message> receive(ReceiveMessageOptions options); + + /** + * @see MessageApi#receive(int) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ReceiveMessage") + @XMLResponseParser(ReceiveMessageResponseHandler.class) + ListenableFuture<? extends List<? extends Message>> receive(@FormParam("MaxNumberOfMessages") int max); + + /** + * @see MessageApi#receive(int, ReceiveMessageOptions) + */ + @POST + @Path("/") + @FormParams(keys = ACTION, values = "ReceiveMessage") + @XMLResponseParser(ReceiveMessageResponseHandler.class) + ListenableFuture<? extends List<? extends Message>> receive(@FormParam("MaxNumberOfMessages") int max, + ReceiveMessageOptions options); + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/PermissionApi.java b/labs/sqs/src/main/java/org/jclouds/sqs/features/PermissionApi.java similarity index 98% rename from labs/sqs/src/main/java/org/jclouds/sqs/PermissionApi.java rename to labs/sqs/src/main/java/org/jclouds/sqs/features/PermissionApi.java index 71a2b4852b..2f2498e1a3 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/PermissionApi.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/features/PermissionApi.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jclouds.sqs; +package org.jclouds.sqs.features; import java.util.concurrent.TimeUnit; @@ -27,7 +27,7 @@ import org.jclouds.sqs.domain.Action; * Provides access to SQS via their REST API. * <p/> * - * @see SQSAsyncApi + * @see PermissionAsyncApi * @author Adrian Cole */ @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/PermissionAsyncApi.java b/labs/sqs/src/main/java/org/jclouds/sqs/features/PermissionAsyncApi.java similarity index 94% rename from labs/sqs/src/main/java/org/jclouds/sqs/PermissionAsyncApi.java rename to labs/sqs/src/main/java/org/jclouds/sqs/features/PermissionAsyncApi.java index 9eccd9b228..54902bd0ef 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/PermissionAsyncApi.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/features/PermissionAsyncApi.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jclouds.sqs; +package org.jclouds.sqs.features; import static org.jclouds.sqs.reference.SQSParameters.ACTION; import static org.jclouds.sqs.reference.SQSParameters.VERSION; @@ -46,7 +46,7 @@ import com.google.common.util.concurrent.ListenableFuture; public interface PermissionAsyncApi { /** - * @see SQSApi#addPermissionToAccount + * @see PermissionApi#addPermissionToAccount */ @POST @Path("/") @@ -55,7 +55,7 @@ public interface PermissionAsyncApi { @FormParam("ActionName.1") Action permission, @FormParam("AWSAccountId.1") String accountId); /** - * @see SQSApi#remove + * @see PermissionApi#remove */ @POST @Path("/") diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/QueueApi.java b/labs/sqs/src/main/java/org/jclouds/sqs/features/QueueApi.java similarity index 99% rename from labs/sqs/src/main/java/org/jclouds/sqs/QueueApi.java rename to labs/sqs/src/main/java/org/jclouds/sqs/features/QueueApi.java index 0492b819a0..ccd6dbec67 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/QueueApi.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/features/QueueApi.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jclouds.sqs; +package org.jclouds.sqs.features; import java.net.URI; import java.util.Map; @@ -32,7 +32,7 @@ import org.jclouds.sqs.options.ListQueuesOptions; * Provides access to SQS via their REST API. * <p/> * - * @see SQSAsyncApi + * @see QueueAsyncApi * @author Adrian Cole */ @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/QueueAsyncApi.java b/labs/sqs/src/main/java/org/jclouds/sqs/features/QueueAsyncApi.java similarity index 91% rename from labs/sqs/src/main/java/org/jclouds/sqs/QueueAsyncApi.java rename to labs/sqs/src/main/java/org/jclouds/sqs/features/QueueAsyncApi.java index 4621b90dad..251cc9dec1 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/QueueAsyncApi.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/features/QueueAsyncApi.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.jclouds.sqs; +package org.jclouds.sqs.features; import static org.jclouds.sqs.reference.SQSParameters.ACTION; import static org.jclouds.sqs.reference.SQSParameters.VERSION; @@ -41,6 +41,7 @@ import org.jclouds.rest.annotations.Transform; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.sqs.binders.BindAttributeNamesToIndexedFormParams; import org.jclouds.sqs.domain.QueueAttributes; import org.jclouds.sqs.functions.MapToQueueAttributes; @@ -65,7 +66,7 @@ import com.google.common.util.concurrent.ListenableFuture; public interface QueueAsyncApi { /** - * @see SQSApi#list + * @see QueueApi#list */ @POST @Path("/") @@ -74,7 +75,7 @@ public interface QueueAsyncApi { ListenableFuture<Set<URI>> list(); /** - * @see SQSApi#list + * @see QueueApi#list(ListQueuesOptions) */ @POST @Path("/") @@ -83,7 +84,7 @@ public interface QueueAsyncApi { ListenableFuture<Set<URI>> list(ListQueuesOptions options); /** - * @see SQSApi#create + * @see QueueApi#create */ @POST @Path("/") @@ -92,7 +93,7 @@ public interface QueueAsyncApi { ListenableFuture<URI> create(@FormParam("QueueName") String queueName); /** - * @see SQSApi#create + * @see QueueApi#create */ @POST @Path("/") @@ -101,15 +102,16 @@ public interface QueueAsyncApi { ListenableFuture<URI> create(@FormParam("QueueName") String queueName, CreateQueueOptions options); /** - * @see SQSApi#delete + * @see QueueApi#delete */ @POST @Path("/") @FormParams(keys = ACTION, values = "DeleteQueue") + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) ListenableFuture<Void> delete(@EndpointParam URI queue); /** - * @see SQSApi#getAttributes(URI) + * @see QueueApi#getAttributes(URI) */ @POST @Path("/") @@ -120,7 +122,7 @@ public interface QueueAsyncApi { ListenableFuture<? extends QueueAttributes> getAttributes(@EndpointParam URI queue); /** - * @see SQSApi#getAttributes(URI, Iterable) + * @see QueueApi#getAttributes(URI, Iterable) */ @POST @Path("/") @@ -130,7 +132,7 @@ public interface QueueAsyncApi { @BinderParam(BindAttributeNamesToIndexedFormParams.class) Iterable<String> attributeNames); /** - * @see SQSApi#getAttribute + * @see QueueApi#getAttribute */ @POST @Path("/") @@ -139,7 +141,7 @@ public interface QueueAsyncApi { ListenableFuture<String> getAttribute(@EndpointParam URI queue, @FormParam("AttributeName.1") String attributeName); /** - * @see SQSApi#setAttribute + * @see QueueApi#setAttribute */ @POST @Path("/") diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/BatchErrorHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/BatchErrorHandler.java new file mode 100644 index 0000000000..24889e29e6 --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/BatchErrorHandler.java @@ -0,0 +1,68 @@ +/** + * 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.sqs.xml; + +import static org.jclouds.util.SaxUtils.currentOrNull; + +import org.jclouds.http.functions.ParseSax; +import org.jclouds.sqs.domain.BatchError; + +/** + * @see <a href= + * "http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QueryDeleteMessageBatch.html" + * /> + * + * @author Adrian Cole + */ +public class BatchErrorHandler extends ParseSax.HandlerForGeneratedRequestWithResult<BatchError> { + + private StringBuilder currentText = new StringBuilder(); + private BatchError.Builder builder = BatchError.builder(); + + @Override + public BatchError getResult() { + try { + return builder.build(); + } catch (NullPointerException e) { + return null; + } finally { + builder = BatchError.builder(); + } + } + + @Override + public void endElement(String uri, String name, String qName) { + if (qName.equals("Id")) { + builder.id(currentOrNull(currentText)); + } else if (qName.equals("SenderFault")) { + builder.senderFault(Boolean.parseBoolean(currentOrNull(currentText))); + } else if (qName.equals("Code")) { + builder.code(currentOrNull(currentText)); + } else if (qName.equals("Message")) { + builder.message(currentOrNull(currentText)); + } + currentText = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/BatchResponseHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/BatchResponseHandler.java new file mode 100644 index 0000000000..07bd366d42 --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/BatchResponseHandler.java @@ -0,0 +1,106 @@ +/** + * 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.sqs.xml; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Map; + +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ParseSax.HandlerForGeneratedRequestWithResult; +import org.jclouds.sqs.domain.BatchError; +import org.jclouds.sqs.domain.BatchResult; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; + +/** + * @see <a + * href="http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QueryDeleteMessageBatch.html" + * >docs</a> + * + * @author Adrian Cole + */ +public class BatchResponseHandler<V> extends ParseSax.HandlerForGeneratedRequestWithResult<BatchResult<V>> { + + private final String resultElement; + private final ParseSax.HandlerForGeneratedRequestWithResult<Map.Entry<String, V>> resultHandler; + private final BatchErrorHandler errorHandler; + + private ImmutableMap.Builder<String, V> results = ImmutableMap.<String,V> builder(); + private Builder<BatchError> errors = ImmutableSet.<BatchError> builder(); + + private boolean inResult; + private boolean inError; + + protected BatchResponseHandler(String resultElement, HandlerForGeneratedRequestWithResult<Map.Entry<String, V>> resultHandler, + BatchErrorHandler errorHandler) { + this.resultElement = checkNotNull(resultElement, "resultElement");; + this.resultHandler = checkNotNull(resultHandler, "resultHandler");; + this.errorHandler = checkNotNull(errorHandler, "errorHandler");; + } + + @Override + public BatchResult<V> getResult() { + return BatchResult.<V> builder().putAll(results.build()).errors(errors.build()) + .build(); + } + + @Override + public void startElement(String url, String name, String qName, Attributes attributes) throws SAXException { + if (qName.equals(resultElement)) { + inResult = true; + } else if (qName.equals("BatchResultErrorEntry")) { + inError = true; + } + if (inResult) { + resultHandler.startElement(url, name, qName, attributes); + } else if (inError) { + errorHandler.startElement(url, name, qName, attributes); + } + } + + @Override + public void endElement(String uri, String name, String qName) throws SAXException { + if (qName.equals(resultElement)) { + results.put(resultHandler.getResult()); + inResult = false; + } else if (qName.equals("BatchResultErrorEntry")) { + errors.add(errorHandler.getResult()); + inError = false; + } else if (inResult) { + resultHandler.endElement(uri, name, qName); + } else if (inError) { + errorHandler.endElement(uri, name, qName); + } + } + + @Override + public void characters(char ch[], int start, int length) throws SAXException { + if (inResult) { + resultHandler.characters(ch, start, length); + } else if (inError) { + errorHandler.characters(ch, start, length); + } + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/ChangeMessageVisibilityBatchResponseHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/ChangeMessageVisibilityBatchResponseHandler.java new file mode 100644 index 0000000000..819f67158f --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/ChangeMessageVisibilityBatchResponseHandler.java @@ -0,0 +1,36 @@ +/** + * 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.sqs.xml; + +import javax.inject.Inject; + +/** + * @see <a + * href="http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QueryChangeMessageVisibilityBatch.html" + * >docs</a> + * + * @author Adrian Cole + */ +public class ChangeMessageVisibilityBatchResponseHandler extends BatchResponseHandler<String> { + @Inject + protected ChangeMessageVisibilityBatchResponseHandler(IdHandler resultHandler, BatchErrorHandler errorHandler) { + super("ChangeMessageVisibilityBatchResultEntry", resultHandler, errorHandler); + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/DeleteMessageBatchResponseHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/DeleteMessageBatchResponseHandler.java new file mode 100644 index 0000000000..1933851b15 --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/DeleteMessageBatchResponseHandler.java @@ -0,0 +1,37 @@ +/** + * 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.sqs.xml; + +import javax.inject.Inject; + +/** + * @see <a + * href="http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QueryDeleteMessageBatch.html" + * >docs</a> + * + * @author Adrian Cole + */ +public class DeleteMessageBatchResponseHandler extends BatchResponseHandler<String> { + + @Inject + protected DeleteMessageBatchResponseHandler(IdHandler resultHandler, BatchErrorHandler errorHandler) { + super("DeleteMessageBatchResultEntry", resultHandler, errorHandler); + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/IdHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/IdHandler.java new file mode 100644 index 0000000000..35d9f42191 --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/IdHandler.java @@ -0,0 +1,46 @@ +/** + * 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.sqs.xml; + +import java.util.Map; + +import javax.inject.Inject; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; + +/** + * @see <a href= + * "http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QueryDeleteMessageBatch.html" + * /> + * + * @author Adrian Cole + */ +public class IdHandler extends TextFromSingleElementHandler<Map.Entry<String, String>> { + @Inject + protected IdHandler(String elementName) { + super("Id"); + } + + @Override + public Map.Entry<String, String> apply(String in) { + return Iterables.getOnlyElement(ImmutableMap.of(in, in).entrySet()); + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/ReceiveMessageResponseHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/ReceiveMessageResponseHandler.java index 7976476acc..76c5551add 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/xml/ReceiveMessageResponseHandler.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/ReceiveMessageResponseHandler.java @@ -20,15 +20,15 @@ package org.jclouds.sqs.xml; import static org.jclouds.util.SaxUtils.equalsOrSuffix; -import java.util.Set; +import java.util.List; import org.jclouds.http.functions.ParseSax; import org.jclouds.sqs.domain.Message; import org.xml.sax.Attributes; import org.xml.sax.SAXException; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSet.Builder; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; import com.google.inject.Inject; /** @@ -38,11 +38,11 @@ import com.google.inject.Inject; * * @author Adrian Cole */ -public class ReceiveMessageResponseHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Set<Message>> { +public class ReceiveMessageResponseHandler extends ParseSax.HandlerForGeneratedRequestWithResult<List<Message>> { private final MessageHandler messageHandler; - private Builder<Message> messages = ImmutableSet.<Message> builder(); + private Builder<Message> messages = ImmutableList.<Message> builder(); private boolean inMessages; @@ -52,7 +52,7 @@ public class ReceiveMessageResponseHandler extends ParseSax.HandlerForGeneratedR } @Override - public Set<Message> getResult() { + public List<Message> getResult() { return messages.build(); } diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/SendMessageBatchResponseHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/SendMessageBatchResponseHandler.java new file mode 100644 index 0000000000..bb7780e29b --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/SendMessageBatchResponseHandler.java @@ -0,0 +1,40 @@ +/** + * 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.sqs.xml; + +import javax.inject.Inject; + +import org.jclouds.sqs.domain.MessageIdAndMD5; + +/** + * @see <a + * href="http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/APIReference/Query_QuerySendMessageBatch.html" + * >docs</a> + * + * @author Adrian Cole + */ +public class SendMessageBatchResponseHandler extends BatchResponseHandler<MessageIdAndMD5> { + + @Inject + protected SendMessageBatchResponseHandler(SendMessageBatchResultEntryHandler resultHandler, + BatchErrorHandler errorHandler) { + super("SendMessageBatchResultEntry", resultHandler, errorHandler); + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/SendMessageBatchResultEntryHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/SendMessageBatchResultEntryHandler.java new file mode 100644 index 0000000000..0474e2e75f --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/SendMessageBatchResultEntryHandler.java @@ -0,0 +1,74 @@ +/** + * 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.sqs.xml; + +import static org.jclouds.util.SaxUtils.currentOrNull; + +import java.util.Map; +import java.util.Map.Entry; + +import org.jclouds.crypto.CryptoStreams; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.sqs.domain.MessageIdAndMD5; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.hash.HashCodes; + +/** + * @see <a href= + * "http://docs.amazonwebservices.com/AWSSimpleQueueService/2011-10-01/APIReference/Query_QueryReceiveMessage.html" + * /> + * + * @author Adrian Cole + */ +public class SendMessageBatchResultEntryHandler extends + ParseSax.HandlerForGeneratedRequestWithResult<Map.Entry<String, MessageIdAndMD5>> { + + private StringBuilder currentText = new StringBuilder(); + private MessageIdAndMD5.Builder builder = MessageIdAndMD5.builder(); + private String id; + + @Override + public Entry<String, MessageIdAndMD5> getResult() { + try { + return Iterables.getOnlyElement(ImmutableMap.of(id, builder.build()).entrySet()); + } finally { + builder = MessageIdAndMD5.builder(); + } + } + + @Override + public void endElement(String uri, String name, String qName) { + if (qName.equals("Id")) { + this.id = currentOrNull(currentText); + } else if (qName.equals("MessageId")) { + builder.id(currentOrNull(currentText)); + } else if (qName.equals("MD5OfMessageBody")) { + builder.md5(HashCodes.fromBytes(CryptoStreams.hex(currentOrNull(currentText)))); + } + currentText = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/TextFromSingleElementHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/TextFromSingleElementHandler.java new file mode 100644 index 0000000000..cfde3d14df --- /dev/null +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/TextFromSingleElementHandler.java @@ -0,0 +1,63 @@ +/** + * 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.sqs.xml; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.util.SaxUtils.currentOrNull; + +import org.jclouds.http.functions.ParseSax; + +import com.google.common.base.Function; + +/** + * looks for a single value in the xml + * + * @author Adrian Cole + */ +public abstract class TextFromSingleElementHandler<V> extends ParseSax.HandlerForGeneratedRequestWithResult<V> + implements Function<String, V> { + private final String elementName; + + protected TextFromSingleElementHandler(String elementName) { + this.elementName = checkNotNull(elementName, "elementName"); + } + + private StringBuilder currentText = new StringBuilder(); + private String text; + + @Override + public V getResult() { + return apply(text); + } + + // this could be done with regex, if we had an unescaper + @Override + public void endElement(String uri, String name, String qName) { + if (qName.equals(elementName)) { + text = currentOrNull(currentText); + } + currentText = new StringBuilder(); + } + + @Override + public void characters(char ch[], int start, int length) { + currentText.append(ch, start, length); + } + +} diff --git a/labs/sqs/src/main/java/org/jclouds/sqs/xml/ValueHandler.java b/labs/sqs/src/main/java/org/jclouds/sqs/xml/ValueHandler.java index b30c622f27..c3764d3a83 100644 --- a/labs/sqs/src/main/java/org/jclouds/sqs/xml/ValueHandler.java +++ b/labs/sqs/src/main/java/org/jclouds/sqs/xml/ValueHandler.java @@ -18,9 +18,7 @@ */ package org.jclouds.sqs.xml; -import static org.jclouds.util.SaxUtils.currentOrNull; - -import org.jclouds.http.functions.ParseSax; +import javax.inject.Inject; /** * @see <a href= @@ -29,28 +27,15 @@ import org.jclouds.http.functions.ParseSax; * * @author Adrian Cole */ -public class ValueHandler extends ParseSax.HandlerForGeneratedRequestWithResult<String> { - - private StringBuilder currentText = new StringBuilder(); - private String value; - - @Override - public String getResult() { - return value; - } - - // this could be done with regex, if we had an unescaper - @Override - public void endElement(String uri, String name, String qName) { - if (qName.equals("Value")) { - value = currentOrNull(currentText); - } - currentText = new StringBuilder(); +public class ValueHandler extends TextFromSingleElementHandler<String> { + @Inject + protected ValueHandler(String elementName) { + super("Value"); } @Override - public void characters(char ch[], int start, int length) { - currentText.append(ch, start, length); + public String apply(String in) { + return in; } } diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/SQSApiExpectTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/SQSApiExpectTest.java deleted file mode 100644 index 24567740b8..0000000000 --- a/labs/sqs/src/test/java/org/jclouds/sqs/SQSApiExpectTest.java +++ /dev/null @@ -1,360 +0,0 @@ -/** - * 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.sqs; - -import static org.testng.Assert.assertEquals; - -import java.net.URI; - -import org.jclouds.http.HttpRequest; -import org.jclouds.http.HttpResponse; -import org.jclouds.sqs.domain.Action; -import org.jclouds.sqs.functions.MapToQueueAttributesTest; -import org.jclouds.sqs.internal.BaseSQSApiExpectTest; -import org.jclouds.sqs.parse.CreateQueueResponseTest; -import org.jclouds.sqs.parse.GetQueueAttributesResponseTest; -import org.jclouds.sqs.parse.ReceiveMessageResponseTest; -import org.jclouds.sqs.parse.SendMessageResponseTest; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; - -/** - * @author Adrian Cole - */ -@Test(groups = "unit", testName = "SQSApiExpectTest") -public class SQSApiExpectTest extends BaseSQSApiExpectTest { - - URI queue = URI.create("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/"); - - public HttpRequest createQueue = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "CreateQueue") - .addFormParam("QueueName", "queueName") - .addFormParam("Signature", "I7tmwiCzJ9cvw79pmlz1rOILh2C2ZV6OpLk23JGx6AU%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testCreateQueueWhenResponseIs2xx() throws Exception { - - HttpResponse createQueueResponse = HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType("/create_queue.xml", "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(createQueue, createQueueResponse); - - assertEquals(apiWhenExist.getQueueApi().create("queueName").toString(), new CreateQueueResponseTest().expected() - .toString()); - } - - public HttpRequest sendMessage = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "SendMessage") - .addFormParam("MessageBody", "hardyharhar") - .addFormParam("Signature", "PVzszzgIcT1xt9%2BEzGzWB2Bt8zDadBc48HsgF89AoJE%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testSendMessageWhenResponseIs2xx() throws Exception { - - HttpResponse sendMessageResponse = HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType("/send_message.xml", "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(sendMessage, sendMessageResponse); - - assertEquals(apiWhenExist.getMessageApiForQueue(queue).send("hardyharhar").toString(), - new SendMessageResponseTest().expected().toString()); - } - - - public HttpRequest receiveMessage = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "ReceiveMessage") - .addFormParam("Signature", "UURXsAjggoaz5P1h2EFswRd8Ji9euHmXhHvrAmIqM1E%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testReceiveMessageWhenResponseIs2xx() throws Exception { - - HttpResponse receiveMessageResponse = HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType("/messages.xml", "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(receiveMessage, receiveMessageResponse); - - assertEquals(apiWhenExist.getMessageApiForQueue(queue).receive().toString(), - Iterables.get(new ReceiveMessageResponseTest().expected(), 0).toString()); - } - - - public HttpRequest receiveMessages = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "ReceiveMessage") - .addFormParam("MaxNumberOfMessages", "10") - .addFormParam("Signature", "pZ9B4%2BTBvQA4n0joP4t8ue5x0xmKMd9prpVLVoT%2F7qU%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testReceiveMessagesWhenResponseIs2xx() throws Exception { - - HttpResponse receiveMessagesResponse = HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType("/messages.xml", "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(receiveMessages, receiveMessagesResponse); - - assertEquals(apiWhenExist.getMessageApiForQueue(queue).receive(10).toString(), new ReceiveMessageResponseTest() - .expected().toString()); - } - - public HttpRequest deleteMessage = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "DeleteMessage") - .addFormParam("ReceiptHandle", "eXJYhj5rDr9cAe") - .addFormParam("Signature", "9%2FkuCc2i78gMsmul%2BRsOPcdQ1OLUKrItqgGIRRBJb8M%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testDeleteMessageWhenResponseIs2xx() throws Exception { - - HttpResponse deleteMessageResponse = HttpResponse.builder() - .statusCode(200) - .payload( - payloadFromStringWithContentType( - "<DeleteMessageResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></DeleteMessageResponse>", - "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(deleteMessage, deleteMessageResponse); - - apiWhenExist.getMessageApiForQueue(queue).delete("eXJYhj5rDr9cAe"); - } - - - public HttpRequest changeMessageVisibility = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "ChangeMessageVisibility") - .addFormParam("ReceiptHandle", "eXJYhj5rDr9cAe") - .addFormParam("Signature", "gvmSHleGLkmszYU6aURCBImuec2k0O3pg3tAYhDvkNs%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("VisibilityTimeout", "10") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testChangeMessageVisibilityWhenResponseIs2xx() throws Exception { - - HttpResponse changeMessageVisibilityResponse = HttpResponse.builder() - .statusCode(200) - .payload( - payloadFromStringWithContentType( - "<ChangeMessageVisibilityResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></ChangeMessageVisibilityResponse>", - "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(changeMessageVisibility, changeMessageVisibilityResponse); - - apiWhenExist.getMessageApiForQueue(queue).changeVisibility("eXJYhj5rDr9cAe", 10); - } - - public HttpRequest getQueueAttribute = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "GetQueueAttributes") - .addFormParam("AttributeName.1", "VisibilityTimeout") - .addFormParam("Signature", "AfydayBBaIk4UGikHHY1CFNmOOAcTnogpFWydZyNass%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testGetQueueAttributeWhenResponseIs2xx() throws Exception { - - HttpResponse getQueueAttributeResponse = HttpResponse.builder() - .statusCode(200) - .payload( - payloadFromStringWithContentType( - "<GetQueueAttributesResponse><GetQueueAttributesResult><Attribute><Name>VisibilityTimeout</Name><Value>30</Value></Attribute></GetQueueAttributesResult></GetQueueAttributesResponse>", - "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(getQueueAttribute, getQueueAttributeResponse); - - assertEquals(apiWhenExist.getQueueApi().getAttribute(queue, "VisibilityTimeout"), "30"); - } - - public HttpRequest getQueueAttributes = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "GetQueueAttributes") - .addFormParam("AttributeName.1", "All") - .addFormParam("Signature", "welFLn0TV6JlH6s6s60XZTJeJfFXGiXN4qNPrBx7aHc%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testGetQueueAttributesWhenResponseIs2xx() throws Exception { - - HttpResponse getQueueAttributesResponse = HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType("/attributes.xml", "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(getQueueAttributes, getQueueAttributesResponse); - - assertEquals(apiWhenExist.getQueueApi().getAttributes(queue).toString(), new MapToQueueAttributesTest() - .expected().toString()); - } - - public HttpRequest getQueueAttributesSubset = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "GetQueueAttributes") - .addFormParam("AttributeName.1", "VisibilityTimeout") - .addFormParam("AttributeName.2", "DelaySeconds") - .addFormParam("Signature", "9KaiOOWWyFPTVMOnyHA3ZoXbPBPSD4AZ4q460UNMfDs%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testGetQueueAttributesSubsetWhenResponseIs2xx() throws Exception { - - HttpResponse getQueueAttributesSubsetResponse = HttpResponse.builder().statusCode(200) - .payload(payloadFromResourceWithContentType("/attributes.xml", "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(getQueueAttributesSubset, getQueueAttributesSubsetResponse); - - assertEquals(apiWhenExist.getQueueApi() - .getAttributes(queue, ImmutableSet.of("VisibilityTimeout", "DelaySeconds")).toString(), - new GetQueueAttributesResponseTest().expected().toString()); - } - - public HttpRequest setQueueAttribute = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "SetQueueAttributes") - .addFormParam("Attribute.Name", "MaximumMessageSize") - .addFormParam("Attribute.Value", "1") - .addFormParam("Signature", "ktBkQ3c%2FrwGcBSec0fkckfo73xmcoTuub5fxudM1qh0%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testSetQueueAttributeWhenResponseIs2xx() throws Exception { - - HttpResponse setQueueAttributeResponse = HttpResponse.builder() - .statusCode(200) - .payload( - payloadFromStringWithContentType( - "<SetQueueAttributesResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></SetQueueAttributesResponse>", - "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(setQueueAttribute, setQueueAttributeResponse); - - apiWhenExist.getQueueApi().setAttribute(queue, "MaximumMessageSize", "1"); - } - - public HttpRequest addPermission = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "AddPermission") - .addFormParam("ActionName.1", "ReceiveMessage") - .addFormParam("AWSAccountId.1", "125074342641") - .addFormParam("Label", "testLabel") - .addFormParam("Signature", "J9sV4q1rJ7dWYJDQp9JxsfEKNXQhpQBYIwBYi1IeXV0%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testAddPermissionWhenResponseIs2xx() throws Exception { - - HttpResponse addPermissionResponse = HttpResponse.builder() - .statusCode(200) - .payload( - payloadFromStringWithContentType( - "<AddPermissionsResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></AddPermissionsResponse>", - "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(addPermission, addPermissionResponse); - - apiWhenExist.getPermissionApiForQueue(queue).addPermissionToAccount("testLabel", Action.RECEIVE_MESSAGE, "125074342641"); - } - - public HttpRequest removePermission = HttpRequest.builder() - .method("POST") - .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") - .addHeader("Host", "sqs.us-east-1.amazonaws.com") - .addFormParam("Action", "RemovePermission") - .addFormParam("Label", "testLabel") - .addFormParam("Signature", "VOA0L1uRVKQDQL1Klt0cYUajGoxN4Ur%2B7ISQ2I4RpRs%3D") - .addFormParam("SignatureMethod", "HmacSHA256") - .addFormParam("SignatureVersion", "2") - .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") - .addFormParam("Version", "2011-10-01") - .addFormParam("AWSAccessKeyId", "identity").build(); - - public void testRemovePermissionWhenResponseIs2xx() throws Exception { - - HttpResponse removePermissionResponse = HttpResponse.builder() - .statusCode(200) - .payload( - payloadFromStringWithContentType( - "<RemovePermissionsResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></RemovePermissionsResponse>", - "text/xml")).build(); - - SQSApi apiWhenExist = requestSendsResponse(removePermission, removePermissionResponse); - - apiWhenExist.getPermissionApiForQueue(queue).remove("testLabel"); - } -} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/SQSApiLiveTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/SQSApiLiveTest.java deleted file mode 100644 index 200c89b0d2..0000000000 --- a/labs/sqs/src/test/java/org/jclouds/sqs/SQSApiLiveTest.java +++ /dev/null @@ -1,229 +0,0 @@ -/** - * 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.sqs; - -import static com.google.common.collect.Iterables.get; -import static com.google.common.collect.Iterables.getLast; -import static org.jclouds.concurrent.MoreExecutors.sameThreadExecutor; -import static org.jclouds.providers.AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint; -import static org.jclouds.sqs.options.ListQueuesOptions.Builder.queuePrefix; -import static org.jclouds.sqs.options.ReceiveMessageOptions.Builder.attribute; -import static org.jclouds.sqs.reference.SQSParameters.ACTION; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; - -import java.net.URI; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import javax.ws.rs.POST; -import javax.ws.rs.Path; - -import org.jclouds.ContextBuilder; -import org.jclouds.concurrent.Timeout; -import org.jclouds.concurrent.config.ExecutorServiceModule; -import org.jclouds.rest.annotations.FormParams; -import org.jclouds.rest.annotations.XMLResponseParser; -import org.jclouds.sqs.domain.Action; -import org.jclouds.sqs.domain.QueueAttributes; -import org.jclouds.sqs.internal.BaseSQSApiLiveTest; -import org.jclouds.sqs.xml.ValueHandler; -import org.testng.annotations.AfterClass; -import org.testng.annotations.Test; - -import com.google.common.base.Charsets; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import com.google.common.hash.HashCode; -import com.google.common.hash.Hashing; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.inject.Module; - -/** - * Tests behavior of {@code SQSApi} - * - * @author Adrian Cole - */ -@Test(groups = "live", singleThreaded = true, testName = "SQSApiLiveTest") -public class SQSApiLiveTest extends BaseSQSApiLiveTest { - - private Set<URI> queues = Sets.newHashSet(); - - @Test - protected void testListQueues() throws InterruptedException { - listQueuesInRegion(null); - } - - protected void listQueuesInRegion(String region) throws InterruptedException { - Set<URI> allResults = api().getQueueApiForRegion(region).list(); - assertNotNull(allResults); - if (allResults.size() >= 1) { - URI queue = getLast(allResults); - assertQueueInList(region, queue); - } - } - - public static final String PREFIX = System.getProperty("user.name") + "-sqs"; - - @Test - protected void testCanRecreateQueueGracefully() throws InterruptedException { - recreateQueueInRegion(PREFIX + "1", null); - recreateQueueInRegion(PREFIX + "1", null); - } - - public String recreateQueueInRegion(String queueName, String region) throws InterruptedException { - QueueApi api = api().getQueueApiForRegion(region); - Set<URI> result = api.list(queuePrefix(queueName)); - if (result.size() >= 1) { - api.delete(getLast(result)); - } - URI queue = api.create(queueName); - assertQueueInList(region, queue); - queues.add(queue); - return queueName; - } - - @Test(dependsOnMethods = "testCanRecreateQueueGracefully") - protected void testGetQueueAttributes() { - for (URI queue : queues) { - Map<String, String> attributes = api().getQueueApi().getAttributes(queue, ImmutableSet.of("All")); - assertEquals(api().getQueueApi().getAttributes(queue, attributes.keySet()), attributes); - } - } - - String message = "hardyharhar"; - HashCode md5 = Hashing.md5().hashString(message, Charsets.UTF_8); - - @Timeout(duration = 5, timeUnit = TimeUnit.SECONDS) - static interface AnonymousAttributesApi { - String getQueueArn(); - } - - static interface AnonymousAttributesAsyncApi { - @POST - @Path("/") - @FormParams(keys = { ACTION, "AttributeName.1" }, values = { "GetQueueAttributes", "QueueArn" }) - @XMLResponseParser(ValueHandler.class) - ListenableFuture<String> getQueueArn(); - } - - @Test(dependsOnMethods = "testGetQueueAttributes") - protected void testAddAnonymousPermission() throws InterruptedException { - for (URI queue : queues) { - QueueAttributes attributes = api().getQueueApi().getAttributes(queue); - assertNoPermissions(queue); - - String accountToAuthorize = getAccountToAuthorize(queue); - api().getPermissionApiForQueue(queue).addPermissionToAccount("fubar", Action.GET_QUEUE_ATTRIBUTES, - accountToAuthorize); - - String policyForAuthorizationByAccount = assertPolicyPresent(queue); - - String policyForAnonymous = policyForAuthorizationByAccount.replace("\"" + accountToAuthorize + "\"", "\"*\""); - api().getQueueApi().setAttribute(queue, "Policy", policyForAnonymous); - - assertEquals(getAnonymousAttributesApi(queue).getQueueArn(), attributes.getQueueArn()); - } - } - - protected String getAccountToAuthorize(URI queue) { - return get(Splitter.on('/').split(queue.getPath()), 1); - } - - @Test(dependsOnMethods = "testAddAnonymousPermission") - protected void testRemovePermission() throws InterruptedException { - for (URI queue : queues) { - api().getPermissionApiForQueue(queue).remove("fubar"); - assertNoPermissions(queue); - } - } - - @Test(dependsOnMethods = "testGetQueueAttributes") - protected void testSetQueueAttribute() { - for (URI queue : queues) { - api().getQueueApi().setAttribute(queue, "MaximumMessageSize", "1024"); - assertEquals(api().getQueueApi().getAttributes(queue).getMaximumMessageSize(), 1024); - } - } - - @Test(dependsOnMethods = "testGetQueueAttributes") - protected void testSendMessage() { - for (URI queue : queues) { - assertEquals(api().getMessageApiForQueue(queue).send(message).getMD5(), md5); - } - } - - @Test(dependsOnMethods = "testSendMessage") - protected void testReceiveMessageWithoutHidingMessage() { - for (URI queue : queues) { - assertEquals(api().getMessageApiForQueue(queue).receive(attribute("All").visibilityTimeout(0)).getMD5(), md5); - } - } - - String receiptHandle; - - @Test(dependsOnMethods = "testReceiveMessageWithoutHidingMessage") - protected void testChangeMessageVisibility() { - for (URI queue : queues) { - MessageApi api = api().getMessageApiForQueue(queue); - // start hiding it at 5 seconds - receiptHandle = api.receive(attribute("None").visibilityTimeout(5)).getReceiptHandle(); - // hidden message, so we can't see it - assertNull(api.receive()); - // this should unhide it - api.changeVisibility(receiptHandle, 0); - // so we can see it again - assertEquals(api.receive(attribute("All").visibilityTimeout(0)).getMD5(), md5); - } - } - - @Test(dependsOnMethods = "testChangeMessageVisibility") - protected void testDeleteMessage() throws InterruptedException { - for (URI queue : queues) { - api().getMessageApiForQueue(queue).delete(receiptHandle); - assertNoMessages(queue); - } - } - - @Override - @AfterClass(groups = "live") - protected void tearDownContext() { - for (URI queue : queues) { - api().getQueueApi().delete(queue); - } - super.tearDownContext(); - } - - protected SQSApi api() { - return context.getApi(); - } - - private AnonymousAttributesApi getAnonymousAttributesApi(URI queue) { - return ContextBuilder - .newBuilder( - forClientMappedToAsyncClientOnEndpoint(AnonymousAttributesApi.class, - AnonymousAttributesAsyncApi.class, queue.toASCIIString())) - .modules(ImmutableSet.<Module> of(new ExecutorServiceModule(sameThreadExecutor(), sameThreadExecutor()))) - .buildInjector().getInstance(AnonymousAttributesApi.class); - } - -} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/features/BulkMessageApiLiveTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/features/BulkMessageApiLiveTest.java new file mode 100644 index 0000000000..7bb8376b7e --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/features/BulkMessageApiLiveTest.java @@ -0,0 +1,130 @@ +/** + * 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.sqs.features; + +import static org.jclouds.sqs.options.ReceiveMessageOptions.Builder.attribute; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.net.URI; +import java.util.Map.Entry; +import java.util.Set; + +import org.jclouds.sqs.domain.BatchResult; +import org.jclouds.sqs.domain.Message; +import org.jclouds.sqs.domain.MessageIdAndMD5; +import org.jclouds.sqs.internal.BaseSQSApiLiveTest; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.testng.internal.annotations.Sets; + +import com.google.common.base.Charsets; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; +import com.google.common.collect.Iterables; +import com.google.common.hash.Hashing; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", singleThreaded = true, testName = "BulkMessageApiLiveTest") +public class BulkMessageApiLiveTest extends BaseSQSApiLiveTest { + + private ImmutableMap<String, String> idPayload; + + public BulkMessageApiLiveTest() { + prefix = prefix + "-bulk"; + + Builder<String, String> builder = ImmutableMap.<String, String> builder(); + for (int i = 0; i < 10; i++) { + String message = "hardyharhar" + i; + builder.put(i + "", message); + } + idPayload = builder.build(); + } + + @BeforeClass(groups = { "integration", "live" }) + @Override + public void setupContext() { + super.setupContext(); + recreateQueueInRegion(prefix, null); + } + + public void testSendMessages() { + for (URI queue : queues) { + BatchResult<? extends MessageIdAndMD5> acks = api().getMessageApiForQueue(queue).send(idPayload); + + assertEquals(acks.size(), idPayload.size(), "error sending " + acks); + assertEquals(acks.keySet(), idPayload.keySet()); + + for (Entry<String, ? extends MessageIdAndMD5> entry : acks.entrySet()) { + assertEquals(entry.getValue().getMD5(), + Hashing.md5().hashString(idPayload.get(entry.getKey()), Charsets.UTF_8), "bad md5 for: " + entry); + } + } + } + + private Iterable<String> receiptHandles; + + @Test(dependsOnMethods = "testSendMessages") + public void testChangeMessageVisibility() { + for (URI queue : queues) { + MessageApi api = api().getMessageApiForQueue(queue); + + Set<Message> messages = collectMessages(api); + + receiptHandles = Iterables.transform(messages, new Function<Message, String>() { + @Override + public String apply(Message in) { + return in.getReceiptHandle(); + } + }); + + // hidden message, so we can't see it + assertNull(api.receive()); + + // this should unhide it + BatchResult<String> acks = api.changeVisibility(receiptHandles, 0); + assertEquals(acks.size(), messages.size(), "error changing visibility " + acks); + + // so we can see it again + assertEquals(collectMessages(api).size(), messages.size()); + } + } + + protected Set<Message> collectMessages(MessageApi api) { + // you are not guaranteed to get all messages in the same request + Set<Message> messages = Sets.newLinkedHashSet(); + while (messages.size() != idPayload.size()) + messages.addAll(api.receive(idPayload.size(), attribute("None").visibilityTimeout(5))); + return messages; + } + + @Test(dependsOnMethods = "testChangeMessageVisibility") + public void testDeleteMessage() throws InterruptedException { + for (URI queue : queues) { + BatchResult<String> acks = api().getMessageApiForQueue(queue).delete(receiptHandles); + assertEquals(acks.size(), Iterables.size(receiptHandles), "error deleting messages " + acks); + assertNoMessages(queue); + } + } + +} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/features/MessageApiExpectTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/features/MessageApiExpectTest.java new file mode 100644 index 0000000000..da2fa1b138 --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/features/MessageApiExpectTest.java @@ -0,0 +1,542 @@ +/** + * 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.sqs.features; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.sqs.SQSApi; +import org.jclouds.sqs.internal.BaseSQSApiExpectTest; +import org.jclouds.sqs.parse.ChangeMessageVisibilityBatchResponseTest; +import org.jclouds.sqs.parse.DeleteMessageBatchResponseTest; +import org.jclouds.sqs.parse.ReceiveMessageResponseTest; +import org.jclouds.sqs.parse.SendMessageBatchResponseTest; +import org.jclouds.sqs.parse.SendMessageResponseTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.Iterables; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "MessageApiExpectTest") +public class MessageApiExpectTest extends BaseSQSApiExpectTest { + + public HttpRequest sendMessage = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "SendMessage") + .addFormParam("MessageBody", "hardyharhar") + .addFormParam("Signature", "PVzszzgIcT1xt9%2BEzGzWB2Bt8zDadBc48HsgF89AoJE%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testSendMessageWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/send_message.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(sendMessage, sendMessageResponse); + + assertEquals(apiWhenExist.getMessageApiForQueue(queue).send("hardyharhar").toString(), + new SendMessageResponseTest().expected().toString()); + } + + public HttpRequest sendMessageIterable = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "SendMessageBatch") + .addFormParam("SendMessageBatchRequestEntry.1.Id", "1") + .addFormParam("SendMessageBatchRequestEntry.1.MessageBody", "payload1") + .addFormParam("SendMessageBatchRequestEntry.2.Id", "2") + .addFormParam("SendMessageBatchRequestEntry.2.MessageBody", "payload2") + .addFormParam("Signature", "2AYMDMLhoLncALJgBfHBGfOkaTB5ut3PeFRJeWffxdI%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testSendMessageIterableWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/send_message_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(sendMessageIterable, sendMessageResponse); + + assertEquals(apiWhenExist.getMessageApiForQueue(queue).send(ImmutableSet.of("payload1", "payload2")) + .toString(), new SendMessageBatchResponseTest().expected().toString()); + } + + public HttpRequest sendMessageMap = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "SendMessageBatch") + .addFormParam("SendMessageBatchRequestEntry.1.Id", "foo1") + .addFormParam("SendMessageBatchRequestEntry.1.MessageBody", "payload1") + .addFormParam("SendMessageBatchRequestEntry.2.Id", "foo2") + .addFormParam("SendMessageBatchRequestEntry.2.MessageBody", "payload2") + .addFormParam("Signature", "f9v8e%2FrPXTI3zhBYMhg7U8yCfvPqHjAV8bFjhGL6%2BXc%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testSendMessageMapWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/send_message_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(sendMessageMap, sendMessageResponse); + + assertEquals( + apiWhenExist.getMessageApiForQueue(queue) + .send(ImmutableMap.of("foo1", "payload1", "foo2", "payload2")).toString(), + new SendMessageBatchResponseTest().expected().toString()); + } + + public HttpRequest sendMessageWithDelayMap = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "SendMessageBatch") + .addFormParam("SendMessageBatchRequestEntry.1.DelaySeconds", "10") + .addFormParam("SendMessageBatchRequestEntry.1.Id", "foo1") + .addFormParam("SendMessageBatchRequestEntry.1.MessageBody", "payload1") + .addFormParam("SendMessageBatchRequestEntry.2.DelaySeconds", "10") + .addFormParam("SendMessageBatchRequestEntry.2.Id", "foo2") + .addFormParam("SendMessageBatchRequestEntry.2.MessageBody", "payload2") + .addFormParam("Signature", "COjjEaJ76EwziEFtkT2FuSRSbrCIu%2FhlJf1Zmu7cYoU%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testSendMessageWithDelayMapWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/send_message_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(sendMessageWithDelayMap, sendMessageResponse); + + assertEquals(apiWhenExist.getMessageApiForQueue(queue).sendWithDelay(ImmutableMap.<String, String>builder() + .put("foo1", "payload1") + .put("foo2", "payload2") + .build(), 10) + .toString(), new SendMessageBatchResponseTest().expected().toString()); + } + + public HttpRequest sendMessageWithDelayIterable = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "SendMessageBatch") + .addFormParam("SendMessageBatchRequestEntry.1.DelaySeconds", "10") + .addFormParam("SendMessageBatchRequestEntry.1.Id", "1") + .addFormParam("SendMessageBatchRequestEntry.1.MessageBody", "payload1") + .addFormParam("SendMessageBatchRequestEntry.2.DelaySeconds", "10") + .addFormParam("SendMessageBatchRequestEntry.2.Id", "2") + .addFormParam("SendMessageBatchRequestEntry.2.MessageBody", "payload2") + .addFormParam("Signature", "8AVNvSVXPSnoXjJAc6h1rysMBBZPnSycbnmD2%2FqpdV8%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testSendMessageWithDelayIterableWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/send_message_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(sendMessageWithDelayIterable, sendMessageResponse); + + assertEquals( + apiWhenExist.getMessageApiForQueue(queue).sendWithDelay(ImmutableSet.of("payload1", "payload2"), 10) + .toString(), new SendMessageBatchResponseTest().expected().toString()); + } + public HttpRequest sendMessageWithDelaysTable = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "SendMessageBatch") + .addFormParam("SendMessageBatchRequestEntry.1.DelaySeconds", "1") + .addFormParam("SendMessageBatchRequestEntry.1.Id", "foo1") + .addFormParam("SendMessageBatchRequestEntry.1.MessageBody", "payload1") + .addFormParam("SendMessageBatchRequestEntry.2.DelaySeconds", "10") + .addFormParam("SendMessageBatchRequestEntry.2.Id", "foo2") + .addFormParam("SendMessageBatchRequestEntry.2.MessageBody", "payload2") + .addFormParam("Signature", "M2X8Al%2BbyyDM%2B9kdN28rMn1yJWl78hJ5i4GnaMZ1sYg%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testSendMessageWithDelaysTableWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/send_message_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(sendMessageWithDelaysTable, sendMessageResponse); + + assertEquals(apiWhenExist.getMessageApiForQueue(queue).sendWithDelays(ImmutableTable.<String, String, Integer>builder() + .put("foo1", "payload1", 1) + .put("foo2", "payload2", 10) + .build()) + .toString(), new SendMessageBatchResponseTest().expected().toString()); + } + + public HttpRequest sendMessageWithDelaysMap = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "SendMessageBatch") + .addFormParam("SendMessageBatchRequestEntry.1.DelaySeconds", "1") + .addFormParam("SendMessageBatchRequestEntry.1.Id", "1") + .addFormParam("SendMessageBatchRequestEntry.1.MessageBody", "payload1") + .addFormParam("SendMessageBatchRequestEntry.2.DelaySeconds", "10") + .addFormParam("SendMessageBatchRequestEntry.2.Id", "2") + .addFormParam("SendMessageBatchRequestEntry.2.MessageBody", "payload2") + .addFormParam("Signature", "nbA4UnKDAuQCiCcvQHH%2F1UjMMeo2s3d94A27Q3t9SlI%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testSendMessageWithDelaysMapWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/send_message_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(sendMessageWithDelaysMap, sendMessageResponse); + + assertEquals( + apiWhenExist.getMessageApiForQueue(queue).sendWithDelays(ImmutableMap.of("payload1", 1, "payload2", 10)) + .toString(), new SendMessageBatchResponseTest().expected().toString()); + } + + public HttpRequest receiveMessage = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "ReceiveMessage") + .addFormParam("Signature", "UURXsAjggoaz5P1h2EFswRd8Ji9euHmXhHvrAmIqM1E%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testReceiveMessageWhenResponseIs2xx() throws Exception { + + HttpResponse receiveMessageResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/messages.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(receiveMessage, receiveMessageResponse); + + assertEquals(apiWhenExist.getMessageApiForQueue(queue).receive().toString(), + Iterables.get(new ReceiveMessageResponseTest().expected(), 0).toString()); + } + + + public HttpRequest receiveMessages = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "ReceiveMessage") + .addFormParam("MaxNumberOfMessages", "10") + .addFormParam("Signature", "pZ9B4%2BTBvQA4n0joP4t8ue5x0xmKMd9prpVLVoT%2F7qU%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testReceiveMessagesWhenResponseIs2xx() throws Exception { + + HttpResponse receiveMessagesResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/messages.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(receiveMessages, receiveMessagesResponse); + + assertEquals(apiWhenExist.getMessageApiForQueue(queue).receive(10).toString(), new ReceiveMessageResponseTest() + .expected().toString()); + } + + public HttpRequest deleteMessage = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "DeleteMessage") + .addFormParam("ReceiptHandle", "eXJYhj5rDr9cAe") + .addFormParam("Signature", "9%2FkuCc2i78gMsmul%2BRsOPcdQ1OLUKrItqgGIRRBJb8M%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testDeleteMessageWhenResponseIs2xx() throws Exception { + + HttpResponse deleteMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload( + payloadFromStringWithContentType( + "<DeleteMessageResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></DeleteMessageResponse>", + "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(deleteMessage, deleteMessageResponse); + + apiWhenExist.getMessageApiForQueue(queue).delete("eXJYhj5rDr9cAe"); + } + + public HttpRequest deleteMessageIterable = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "DeleteMessageBatch") + .addFormParam("DeleteMessageBatchRequestEntry.1.Id", "1") + .addFormParam("DeleteMessageBatchRequestEntry.1.ReceiptHandle", "eXJYhj5rDr9cAe") + .addFormParam("DeleteMessageBatchRequestEntry.2.Id", "2") + .addFormParam("DeleteMessageBatchRequestEntry.2.ReceiptHandle", "fffeeerrr") + .addFormParam("Signature", "S4xIobjm3LOkJvibeI2X54nxKJw9r1a5zj%2FdvHlfDMY%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testDeleteMessageIterableWhenResponseIs2xx() throws Exception { + + HttpResponse deleteMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/delete_message_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(deleteMessageIterable, deleteMessageResponse); + + assertEquals(apiWhenExist.getMessageApiForQueue(queue).delete(ImmutableSet.of("eXJYhj5rDr9cAe", "fffeeerrr")) + .toString(), new DeleteMessageBatchResponseTest().expected().toString()); + } + + public HttpRequest deleteMessageMap = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "DeleteMessageBatch") + .addFormParam("DeleteMessageBatchRequestEntry.1.Id", "foo1") + .addFormParam("DeleteMessageBatchRequestEntry.1.ReceiptHandle", "eXJYhj5rDr9cAe") + .addFormParam("DeleteMessageBatchRequestEntry.2.Id", "foo2") + .addFormParam("DeleteMessageBatchRequestEntry.2.ReceiptHandle", "fffeeerrr") + .addFormParam("Signature", "kwHC3F3ZoJvfibhZWVTeIwFHUzoaVMR4OViyJbsmuV0%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testDeleteMessageMapWhenResponseIs2xx() throws Exception { + + HttpResponse deleteMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/delete_message_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(deleteMessageMap, deleteMessageResponse); + + assertEquals( + apiWhenExist.getMessageApiForQueue(queue) + .delete(ImmutableMap.of("foo1", "eXJYhj5rDr9cAe", "foo2", "fffeeerrr")).toString(), + new DeleteMessageBatchResponseTest().expected().toString()); + } + + public HttpRequest changeMessageVisibility = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "ChangeMessageVisibility") + .addFormParam("ReceiptHandle", "eXJYhj5rDr9cAe") + .addFormParam("Signature", "gvmSHleGLkmszYU6aURCBImuec2k0O3pg3tAYhDvkNs%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("VisibilityTimeout", "10") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testChangeMessageVisibilityWhenResponseIs2xx() throws Exception { + + HttpResponse changeMessageVisibilityResponse = HttpResponse.builder() + .statusCode(200) + .payload( + payloadFromStringWithContentType( + "<ChangeMessageVisibilityResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></ChangeMessageVisibilityResponse>", + "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(changeMessageVisibility, changeMessageVisibilityResponse); + + apiWhenExist.getMessageApiForQueue(queue).changeVisibility("eXJYhj5rDr9cAe", 10); + } + + public HttpRequest changeMessageVisibilityTable = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "ChangeMessageVisibilityBatch") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.Id", "foo1") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.ReceiptHandle", "aaaaaaaaa") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.VisibilityTimeout", "1") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.Id", "foo2") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.ReceiptHandle", "bbbbbbbbb") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.VisibilityTimeout", "10") + .addFormParam("Signature", "KjDusYiiC3hTdy3ZxLwBRHryrNoNaFb2AHJqUDu3mtQ%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testChangeMessageVisibilityTableWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/change_message_visibility_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(changeMessageVisibilityTable, sendMessageResponse); + + assertEquals(apiWhenExist.getMessageApiForQueue(queue).changeVisibility(ImmutableTable.<String, String, Integer>builder() + .put("foo1", "aaaaaaaaa", 1) + .put("foo2", "bbbbbbbbb", 10) + .build()) + .toString(), new ChangeMessageVisibilityBatchResponseTest().expected().toString()); + } + + public HttpRequest changeMessageVisibilityMap = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "ChangeMessageVisibilityBatch") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.Id", "1") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.ReceiptHandle", "aaaaaaaaa") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.VisibilityTimeout", "1") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.Id", "2") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.ReceiptHandle", "bbbbbbbbb") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.VisibilityTimeout", "10") + .addFormParam("Signature", "zj2cftkpHtiYb9iOjPR3AhcVhoobi0JvOy22PvQJtho%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testChangeMessageVisibilityMapWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/change_message_visibility_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(changeMessageVisibilityMap, sendMessageResponse); + + assertEquals( + apiWhenExist.getMessageApiForQueue(queue).changeVisibility(ImmutableMap.of("aaaaaaaaa", 1, "bbbbbbbbb", 10)) + .toString(), new ChangeMessageVisibilityBatchResponseTest().expected().toString()); + } + + public HttpRequest changeMessageVisibilityMapInt = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "ChangeMessageVisibilityBatch") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.Id", "foo1") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.ReceiptHandle", "aaaaaaaaa") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.VisibilityTimeout", "10") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.Id", "foo2") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.ReceiptHandle", "bbbbbbbbb") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.VisibilityTimeout", "10") + .addFormParam("Signature", "y%2FgaaxoE5wrG2P7NIAyfDo7DTgRx2PLJUi9%2FzNnWQ6A%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testChangeMessageVisibilityMapIntWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/change_message_visibility_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(changeMessageVisibilityMapInt, sendMessageResponse); + + assertEquals(apiWhenExist.getMessageApiForQueue(queue).changeVisibility(ImmutableMap.<String, String>builder() + .put("foo1", "aaaaaaaaa") + .put("foo2", "bbbbbbbbb") + .build(), 10) + .toString(), new ChangeMessageVisibilityBatchResponseTest().expected().toString()); + } + + public HttpRequest changeMessageVisibilityIterableInt = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "ChangeMessageVisibilityBatch") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.Id", "1") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.ReceiptHandle", "aaaaaaaaa") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.1.VisibilityTimeout", "10") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.Id", "2") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.ReceiptHandle", "bbbbbbbbb") + .addFormParam("ChangeMessageVisibilityBatchRequestEntry.2.VisibilityTimeout", "10") + .addFormParam("Signature", "f5aq7zdKFErM3%2BIdtDX5NOzPO7mqCRzPGj2wUUEWjgE%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testChangeMessageVisibilityIterableIntWhenResponseIs2xx() throws Exception { + + HttpResponse sendMessageResponse = HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResourceWithContentType("/change_message_visibility_batch.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(changeMessageVisibilityIterableInt, sendMessageResponse); + + assertEquals( + apiWhenExist.getMessageApiForQueue(queue).changeVisibility(ImmutableSet.of("aaaaaaaaa", "bbbbbbbbb"), 10) + .toString(), new ChangeMessageVisibilityBatchResponseTest().expected().toString()); + } +} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/features/MessageApiLiveTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/features/MessageApiLiveTest.java new file mode 100644 index 0000000000..0e2a3ea77c --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/features/MessageApiLiveTest.java @@ -0,0 +1,94 @@ +/** + * 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.sqs.features; + +import static org.jclouds.sqs.options.ReceiveMessageOptions.Builder.attribute; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.net.URI; + +import org.jclouds.sqs.internal.BaseSQSApiLiveTest; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; +import com.google.common.hash.HashCode; +import com.google.common.hash.Hashing; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", singleThreaded = true, testName = "MessageApiLiveTest") +public class MessageApiLiveTest extends BaseSQSApiLiveTest { + + public MessageApiLiveTest() { + prefix = prefix + "-message"; + } + + @BeforeClass(groups = { "integration", "live" }) + @Override + public void setupContext() { + super.setupContext(); + recreateQueueInRegion(prefix, null); + } + + String message = "hardyharhar"; + HashCode md5 = Hashing.md5().hashString(message, Charsets.UTF_8); + + public void testSendMessage() { + for (URI queue : queues) { + assertEquals(api().getMessageApiForQueue(queue).send(message).getMD5(), md5); + } + } + + @Test(dependsOnMethods = "testSendMessage") + public void testReceiveMessageWithoutHidingMessage() { + for (URI queue : queues) { + assertEquals(api().getMessageApiForQueue(queue).receive(attribute("All").visibilityTimeout(0)).getMD5(), md5); + } + } + + String receiptHandle; + + @Test(dependsOnMethods = "testReceiveMessageWithoutHidingMessage") + public void testChangeMessageVisibility() { + for (URI queue : queues) { + MessageApi api = api().getMessageApiForQueue(queue); + // start hiding it at 5 seconds + receiptHandle = api.receive(attribute("None").visibilityTimeout(5)).getReceiptHandle(); + // hidden message, so we can't see it + assertNull(api.receive()); + // this should unhide it + api.changeVisibility(receiptHandle, 0); + // so we can see it again + assertEquals(api.receive(attribute("All").visibilityTimeout(0)).getMD5(), md5); + } + } + + @Test(dependsOnMethods = "testChangeMessageVisibility") + public void testDeleteMessage() throws InterruptedException { + for (URI queue : queues) { + api().getMessageApiForQueue(queue).delete(receiptHandle); + assertNoMessages(queue); + } + } + +} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/features/PermissionApiExpectTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/features/PermissionApiExpectTest.java new file mode 100644 index 0000000000..037de11b3a --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/features/PermissionApiExpectTest.java @@ -0,0 +1,89 @@ +/** + * 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.sqs.features; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.sqs.SQSApi; +import org.jclouds.sqs.domain.Action; +import org.jclouds.sqs.internal.BaseSQSApiExpectTest; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "PermissionApiExpectTest") +public class PermissionApiExpectTest extends BaseSQSApiExpectTest { + + public HttpRequest addPermission = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "AddPermission") + .addFormParam("ActionName.1", "ReceiveMessage") + .addFormParam("AWSAccountId.1", "125074342641") + .addFormParam("Label", "testLabel") + .addFormParam("Signature", "J9sV4q1rJ7dWYJDQp9JxsfEKNXQhpQBYIwBYi1IeXV0%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testAddPermissionWhenResponseIs2xx() throws Exception { + + HttpResponse addPermissionResponse = HttpResponse.builder() + .statusCode(200) + .payload( + payloadFromStringWithContentType( + "<AddPermissionsResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></AddPermissionsResponse>", + "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(addPermission, addPermissionResponse); + + apiWhenExist.getPermissionApiForQueue(queue).addPermissionToAccount("testLabel", Action.RECEIVE_MESSAGE, "125074342641"); + } + + public HttpRequest removePermission = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "RemovePermission") + .addFormParam("Label", "testLabel") + .addFormParam("Signature", "VOA0L1uRVKQDQL1Klt0cYUajGoxN4Ur%2B7ISQ2I4RpRs%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testRemovePermissionWhenResponseIs2xx() throws Exception { + + HttpResponse removePermissionResponse = HttpResponse.builder() + .statusCode(200) + .payload( + payloadFromStringWithContentType( + "<RemovePermissionsResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></RemovePermissionsResponse>", + "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(removePermission, removePermissionResponse); + + apiWhenExist.getPermissionApiForQueue(queue).remove("testLabel"); + } +} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/features/PermissionApiLiveTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/features/PermissionApiLiveTest.java new file mode 100644 index 0000000000..b1aa629840 --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/features/PermissionApiLiveTest.java @@ -0,0 +1,121 @@ +/** + * 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.sqs.features; + +import static com.google.common.collect.Iterables.get; +import static org.jclouds.concurrent.MoreExecutors.sameThreadExecutor; +import static org.jclouds.providers.AnonymousProviderMetadata.forClientMappedToAsyncClientOnEndpoint; +import static org.jclouds.sqs.reference.SQSParameters.ACTION; +import static org.testng.Assert.assertEquals; + +import java.net.URI; +import java.util.concurrent.TimeUnit; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.jclouds.ContextBuilder; +import org.jclouds.concurrent.Timeout; +import org.jclouds.concurrent.config.ExecutorServiceModule; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.sqs.domain.Action; +import org.jclouds.sqs.domain.QueueAttributes; +import org.jclouds.sqs.internal.BaseSQSApiLiveTest; +import org.jclouds.sqs.xml.ValueHandler; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableSet; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.inject.Module; + +/** + * + * + * @author Adrian Cole + */ +@Test(groups = "live", singleThreaded = true, testName = "PermissionApiLiveTest") +public class PermissionApiLiveTest extends BaseSQSApiLiveTest { + + public PermissionApiLiveTest() { + prefix = prefix + "-permission"; + } + + @BeforeClass(groups = { "integration", "live" }) + @Override + public void setupContext() { + super.setupContext(); + recreateQueueInRegion(prefix, null); + } + + @Timeout(duration = 5, timeUnit = TimeUnit.SECONDS) + static interface AnonymousAttributesApi { + String getQueueArn(); + } + + static interface AnonymousAttributesAsyncApi { + @POST + @Path("/") + @FormParams(keys = { ACTION, "AttributeName.1" }, values = { "GetQueueAttributes", "QueueArn" }) + @XMLResponseParser(ValueHandler.class) + ListenableFuture<String> getQueueArn(); + } + + public void testAddAnonymousPermission() throws InterruptedException { + for (URI queue : queues) { + QueueAttributes attributes = api().getQueueApi().getAttributes(queue); + assertNoPermissions(queue); + + String accountToAuthorize = getAccountToAuthorize(queue); + api().getPermissionApiForQueue(queue).addPermissionToAccount("fubar", Action.GET_QUEUE_ATTRIBUTES, + accountToAuthorize); + + String policyForAuthorizationByAccount = assertPolicyPresent(queue); + + String policyForAnonymous = policyForAuthorizationByAccount.replace("\"" + accountToAuthorize + "\"", "\"*\""); + api().getQueueApi().setAttribute(queue, "Policy", policyForAnonymous); + + assertEquals(getAnonymousAttributesApi(queue).getQueueArn(), attributes.getQueueArn()); + } + } + + protected String getAccountToAuthorize(URI queue) { + return get(Splitter.on('/').split(queue.getPath()), 1); + } + + @Test(dependsOnMethods = "testAddAnonymousPermission") + public void testRemovePermission() throws InterruptedException { + for (URI queue : queues) { + api().getPermissionApiForQueue(queue).remove("fubar"); + assertNoPermissions(queue); + } + } + + private AnonymousAttributesApi getAnonymousAttributesApi(URI queue) { + return ContextBuilder + .newBuilder( + forClientMappedToAsyncClientOnEndpoint(AnonymousAttributesApi.class, + AnonymousAttributesAsyncApi.class, queue.toASCIIString())) + .modules(ImmutableSet.<Module> of(new ExecutorServiceModule(sameThreadExecutor(), sameThreadExecutor()))) + .buildInjector().getInstance(AnonymousAttributesApi.class); + } + +} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/features/QueueApiExpectTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/features/QueueApiExpectTest.java new file mode 100644 index 0000000000..a9b09a1c4f --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/features/QueueApiExpectTest.java @@ -0,0 +1,169 @@ +/** + * 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.sqs.features; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.sqs.SQSApi; +import org.jclouds.sqs.functions.MapToQueueAttributesTest; +import org.jclouds.sqs.internal.BaseSQSApiExpectTest; +import org.jclouds.sqs.parse.CreateQueueResponseTest; +import org.jclouds.sqs.parse.GetQueueAttributesResponseTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "QueueApiExpectTest") +public class QueueApiExpectTest extends BaseSQSApiExpectTest { + + public HttpRequest createQueue = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "CreateQueue") + .addFormParam("QueueName", "queueName") + .addFormParam("Signature", "I7tmwiCzJ9cvw79pmlz1rOILh2C2ZV6OpLk23JGx6AU%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testCreateQueueWhenResponseIs2xx() throws Exception { + + HttpResponse createQueueResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/create_queue.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(createQueue, createQueueResponse); + + assertEquals(apiWhenExist.getQueueApi().create("queueName").toString(), new CreateQueueResponseTest().expected() + .toString()); + } + + public HttpRequest getQueueAttribute = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "GetQueueAttributes") + .addFormParam("AttributeName.1", "VisibilityTimeout") + .addFormParam("Signature", "AfydayBBaIk4UGikHHY1CFNmOOAcTnogpFWydZyNass%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testGetQueueAttributeWhenResponseIs2xx() throws Exception { + + HttpResponse getQueueAttributeResponse = HttpResponse.builder() + .statusCode(200) + .payload( + payloadFromStringWithContentType( + "<GetQueueAttributesResponse><GetQueueAttributesResult><Attribute><Name>VisibilityTimeout</Name><Value>30</Value></Attribute></GetQueueAttributesResult></GetQueueAttributesResponse>", + "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(getQueueAttribute, getQueueAttributeResponse); + + assertEquals(apiWhenExist.getQueueApi().getAttribute(queue, "VisibilityTimeout"), "30"); + } + + public HttpRequest getQueueAttributes = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "GetQueueAttributes") + .addFormParam("AttributeName.1", "All") + .addFormParam("Signature", "welFLn0TV6JlH6s6s60XZTJeJfFXGiXN4qNPrBx7aHc%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testGetQueueAttributesWhenResponseIs2xx() throws Exception { + + HttpResponse getQueueAttributesResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/attributes.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(getQueueAttributes, getQueueAttributesResponse); + + assertEquals(apiWhenExist.getQueueApi().getAttributes(queue).toString(), new MapToQueueAttributesTest() + .expected().toString()); + } + + public HttpRequest getQueueAttributesSubset = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "GetQueueAttributes") + .addFormParam("AttributeName.1", "VisibilityTimeout") + .addFormParam("AttributeName.2", "DelaySeconds") + .addFormParam("Signature", "9KaiOOWWyFPTVMOnyHA3ZoXbPBPSD4AZ4q460UNMfDs%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testGetQueueAttributesSubsetWhenResponseIs2xx() throws Exception { + + HttpResponse getQueueAttributesSubsetResponse = HttpResponse.builder().statusCode(200) + .payload(payloadFromResourceWithContentType("/attributes.xml", "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(getQueueAttributesSubset, getQueueAttributesSubsetResponse); + + assertEquals(apiWhenExist.getQueueApi() + .getAttributes(queue, ImmutableSet.of("VisibilityTimeout", "DelaySeconds")).toString(), + new GetQueueAttributesResponseTest().expected().toString()); + } + + public HttpRequest setQueueAttribute = HttpRequest.builder() + .method("POST") + .endpoint("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/") + .addHeader("Host", "sqs.us-east-1.amazonaws.com") + .addFormParam("Action", "SetQueueAttributes") + .addFormParam("Attribute.Name", "MaximumMessageSize") + .addFormParam("Attribute.Value", "1") + .addFormParam("Signature", "ktBkQ3c%2FrwGcBSec0fkckfo73xmcoTuub5fxudM1qh0%3D") + .addFormParam("SignatureMethod", "HmacSHA256") + .addFormParam("SignatureVersion", "2") + .addFormParam("Timestamp", "2009-11-08T15%3A54%3A08.897Z") + .addFormParam("Version", "2011-10-01") + .addFormParam("AWSAccessKeyId", "identity").build(); + + public void testSetQueueAttributeWhenResponseIs2xx() throws Exception { + + HttpResponse setQueueAttributeResponse = HttpResponse.builder() + .statusCode(200) + .payload( + payloadFromStringWithContentType( + "<SetQueueAttributesResponse><ResponseMetadata><RequestId>b5293cb5-d306-4a17-9048-b263635abe42</RequestId></ResponseMetadata></SetQueueAttributesResponse>", + "text/xml")).build(); + + SQSApi apiWhenExist = requestSendsResponse(setQueueAttribute, setQueueAttributeResponse); + + apiWhenExist.getQueueApi().setAttribute(queue, "MaximumMessageSize", "1"); + } + +} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/features/QueueApiLiveTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/features/QueueApiLiveTest.java new file mode 100644 index 0000000000..d6481ece9a --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/features/QueueApiLiveTest.java @@ -0,0 +1,80 @@ +/** + * 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.sqs.features; + +import static com.google.common.collect.Iterables.getLast; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.net.URI; +import java.util.Map; +import java.util.Set; + +import org.jclouds.sqs.internal.BaseSQSApiLiveTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", singleThreaded = true, testName = "QueueApiLiveTest") +public class QueueApiLiveTest extends BaseSQSApiLiveTest { + + public QueueApiLiveTest() { + prefix = prefix + "-queue"; + } + + @Test + public void testListQueues() throws InterruptedException { + listQueuesInRegion(null); + } + + protected void listQueuesInRegion(String region) throws InterruptedException { + Set<URI> allResults = api().getQueueApiForRegion(region).list(); + assertNotNull(allResults); + if (allResults.size() >= 1) { + URI queue = getLast(allResults); + assertQueueInList(region, queue); + } + } + + @Test + public void testCanRecreateQueueGracefully() throws InterruptedException { + recreateQueueInRegion(prefix, null); + recreateQueueInRegion(prefix, null); + } + + @Test(dependsOnMethods = "testCanRecreateQueueGracefully") + public void testGetQueueAttributes() { + for (URI queue : queues) { + Map<String, String> attributes = api().getQueueApi().getAttributes(queue, ImmutableSet.of("All")); + assertEquals(api().getQueueApi().getAttributes(queue, attributes.keySet()), attributes); + } + } + + @Test(dependsOnMethods = "testGetQueueAttributes") + public void testSetQueueAttribute() { + for (URI queue : queues) { + api().getQueueApi().setAttribute(queue, "MaximumMessageSize", "1024"); + assertEquals(api().getQueueApi().getAttributes(queue).getMaximumMessageSize(), 1024); + } + } +} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/internal/BaseSQSApiLiveTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/internal/BaseSQSApiLiveTest.java index 7b60c8df48..35799ec397 100644 --- a/labs/sqs/src/test/java/org/jclouds/sqs/internal/BaseSQSApiLiveTest.java +++ b/labs/sqs/src/test/java/org/jclouds/sqs/internal/BaseSQSApiLiveTest.java @@ -18,12 +18,15 @@ */ package org.jclouds.sqs.internal; +import static com.google.common.collect.Iterables.getLast; +import static org.jclouds.sqs.options.ListQueuesOptions.Builder.queuePrefix; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import java.net.URI; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.jclouds.apis.BaseContextLiveTest; @@ -32,9 +35,13 @@ import org.jclouds.sqs.SQSApi; import org.jclouds.sqs.SQSApiMetadata; import org.jclouds.sqs.SQSAsyncApi; import org.jclouds.sqs.domain.Message; +import org.jclouds.sqs.features.QueueApi; +import org.testng.annotations.AfterClass; import org.testng.annotations.Test; +import com.google.common.collect.Sets; import com.google.common.reflect.TypeToken; +import com.google.common.util.concurrent.Uninterruptibles; /** * @@ -43,16 +50,32 @@ import com.google.common.reflect.TypeToken; @Test(groups = "live") public class BaseSQSApiLiveTest extends BaseContextLiveTest<RestContext<SQSApi, SQSAsyncApi>> { + protected String prefix = System.getProperty("user.name") + "-sqs"; + public BaseSQSApiLiveTest() { provider = "sqs"; } + protected Set<URI> queues = Sets.newHashSet(); + + protected String recreateQueueInRegion(String queueName, String region) { + QueueApi api = api().getQueueApiForRegion(region); + Set<URI> result = api.list(queuePrefix(queueName)); + if (result.size() >= 1) { + api.delete(getLast(result)); + } + URI queue = api.create(queueName); + assertQueueInList(region, queue); + queues.add(queue); + return queueName; + } + @Override protected TypeToken<RestContext<SQSApi, SQSAsyncApi>> contextType() { return SQSApiMetadata.CONTEXT_TOKEN; } - protected String assertPolicyPresent(final URI queue) throws InterruptedException { + protected String assertPolicyPresent(final URI queue) { final AtomicReference<String> policy = new AtomicReference<String>(); assertEventually(new Runnable() { public void run() { @@ -65,7 +88,7 @@ public class BaseSQSApiLiveTest extends BaseContextLiveTest<RestContext<SQSApi, return policy.get(); } - protected void assertNoPermissions(final URI queue) throws InterruptedException { + protected void assertNoPermissions(final URI queue) { assertEventually(new Runnable() { public void run() { String policy = api().getQueueApi().getAttribute(queue, "Policy"); @@ -74,7 +97,7 @@ public class BaseSQSApiLiveTest extends BaseContextLiveTest<RestContext<SQSApi, }); } - protected void assertNoMessages(final URI queue) throws InterruptedException { + protected void assertNoMessages(final URI queue) { assertEventually(new Runnable() { public void run() { Message message = api().getMessageApiForQueue(queue).receive(); @@ -83,7 +106,7 @@ public class BaseSQSApiLiveTest extends BaseContextLiveTest<RestContext<SQSApi, }); } - protected void assertQueueInList(final String region, URI queue) throws InterruptedException { + protected void assertQueueInList(final String region, URI queue) { final URI finalQ = queue; assertEventually(new Runnable() { public void run() { @@ -95,10 +118,6 @@ public class BaseSQSApiLiveTest extends BaseContextLiveTest<RestContext<SQSApi, }); } - private SQSApi api() { - return context.getApi(); - } - private static final int INCONSISTENCY_WINDOW = 10000; /** @@ -106,7 +125,7 @@ public class BaseSQSApiLiveTest extends BaseContextLiveTest<RestContext<SQSApi, * immediately. Hence, we will try up to the inconsistency window to see if * the assertion completes. */ - protected static void assertEventually(Runnable assertion) throws InterruptedException { + protected static void assertEventually(Runnable assertion) { long start = System.currentTimeMillis(); AssertionError error = null; for (int i = 0; i < 30; i++) { @@ -119,9 +138,23 @@ public class BaseSQSApiLiveTest extends BaseContextLiveTest<RestContext<SQSApi, } catch (AssertionError e) { error = e; } - Thread.sleep(INCONSISTENCY_WINDOW / 30); + Uninterruptibles.sleepUninterruptibly(INCONSISTENCY_WINDOW / 30, TimeUnit.MILLISECONDS); } if (error != null) throw error; } + + @Override + @AfterClass(groups = "live") + protected void tearDownContext() { + for (URI queue : queues) { + api().getQueueApi().delete(queue); + } + super.tearDownContext(); + } + + protected SQSApi api() { + return context.getApi(); + } + } diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/internal/BaseSQSExpectTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/internal/BaseSQSExpectTest.java index 6896a1ad65..082cb1d2b4 100644 --- a/labs/sqs/src/test/java/org/jclouds/sqs/internal/BaseSQSExpectTest.java +++ b/labs/sqs/src/test/java/org/jclouds/sqs/internal/BaseSQSExpectTest.java @@ -18,6 +18,8 @@ */ package org.jclouds.sqs.internal; +import java.net.URI; + import org.jclouds.date.DateService; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.internal.BaseRestApiExpectTest; @@ -30,6 +32,7 @@ import com.google.inject.Module; * @author Adrian Cole */ public class BaseSQSExpectTest<T> extends BaseRestApiExpectTest<T> { + protected URI queue = URI.create("https://sqs.us-east-1.amazonaws.com/993194456877/adrian-sqs11/"); public BaseSQSExpectTest() { provider = "sqs"; diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/parse/ChangeMessageVisibilityBatchResponseTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/parse/ChangeMessageVisibilityBatchResponseTest.java new file mode 100644 index 0000000000..4e40613310 --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/parse/ChangeMessageVisibilityBatchResponseTest.java @@ -0,0 +1,56 @@ +/** + * 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.sqs.parse; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.http.functions.BaseHandlerTest; +import org.jclouds.sqs.domain.BatchResult; +import org.jclouds.sqs.xml.ChangeMessageVisibilityBatchResponseHandler; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during +// surefire +@Test(groups = "unit", testName = "ChangeMessageVisibilityBatchResponseTest") +public class ChangeMessageVisibilityBatchResponseTest extends BaseHandlerTest { + + public void test() { + InputStream is = getClass().getResourceAsStream("/change_message_visibility_batch.xml"); + + BatchResult<String> expected = expected(); + + ChangeMessageVisibilityBatchResponseHandler handler = injector.getInstance(ChangeMessageVisibilityBatchResponseHandler.class); + BatchResult<String> result = factory.create(handler).parse(is); + + assertEquals(result.toString(), expected.toString()); + + } + + public BatchResult<String> expected() { + return BatchResult.<String> builder() + .put("change_visibility_msg_2","change_visibility_msg_2") + .put("change_visibility_msg_3","change_visibility_msg_3") + .build(); + } +} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/parse/DeleteMessageBatchResponseTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/parse/DeleteMessageBatchResponseTest.java new file mode 100644 index 0000000000..c7e4ce47c5 --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/parse/DeleteMessageBatchResponseTest.java @@ -0,0 +1,56 @@ +/** + * 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.sqs.parse; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.http.functions.BaseHandlerTest; +import org.jclouds.sqs.domain.BatchResult; +import org.jclouds.sqs.xml.DeleteMessageBatchResponseHandler; +import org.testng.annotations.Test; + +/** + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during +// surefire +@Test(groups = "unit", testName = "DeleteMessageBatchResponseTest") +public class DeleteMessageBatchResponseTest extends BaseHandlerTest { + + public void test() { + InputStream is = getClass().getResourceAsStream("/delete_message_batch.xml"); + + BatchResult<String> expected = expected(); + + DeleteMessageBatchResponseHandler handler = injector.getInstance(DeleteMessageBatchResponseHandler.class); + BatchResult<String> result = factory.create(handler).parse(is); + + assertEquals(result.toString(), expected.toString()); + + } + + public BatchResult<String> expected() { + return BatchResult.<String> builder() + .put("msg1","msg1") + .put("msg2","msg2") + .build(); + } +} diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/parse/ReceiveMessageResponseTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/parse/ReceiveMessageResponseTest.java index d345656efd..77f50ee0b1 100644 --- a/labs/sqs/src/test/java/org/jclouds/sqs/parse/ReceiveMessageResponseTest.java +++ b/labs/sqs/src/test/java/org/jclouds/sqs/parse/ReceiveMessageResponseTest.java @@ -21,7 +21,7 @@ package org.jclouds.sqs.parse; import static org.testng.Assert.assertEquals; import java.io.InputStream; -import java.util.Set; +import java.util.List; import org.jclouds.crypto.CryptoStreams; import org.jclouds.http.functions.BaseHandlerTest; @@ -29,7 +29,7 @@ import org.jclouds.sqs.domain.Message; import org.jclouds.sqs.xml.ReceiveMessageResponseHandler; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableList; import com.google.common.hash.HashCodes; /** @@ -43,17 +43,17 @@ public class ReceiveMessageResponseTest extends BaseHandlerTest { public void test() { InputStream is = getClass().getResourceAsStream("/messages.xml"); - Set<Message> expected = expected(); + List<Message> expected = expected(); ReceiveMessageResponseHandler handler = injector.getInstance(ReceiveMessageResponseHandler.class); - Set<Message> result = factory.create(handler).parse(is); + List<Message> result = factory.create(handler).parse(is); assertEquals(result.toString(), expected.toString()); } - public Set<Message> expected() { - return ImmutableSet.of(Message + public List<Message> expected() { + return ImmutableList.of(Message .builder() .id("5fea7756-0ea4-451a-a703-a558b933e274") .receiptHandle( diff --git a/labs/sqs/src/test/java/org/jclouds/sqs/parse/SendMessageBatchResponseTest.java b/labs/sqs/src/test/java/org/jclouds/sqs/parse/SendMessageBatchResponseTest.java new file mode 100644 index 0000000000..fcafc10c10 --- /dev/null +++ b/labs/sqs/src/test/java/org/jclouds/sqs/parse/SendMessageBatchResponseTest.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.sqs.parse; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.crypto.CryptoStreams; +import org.jclouds.http.functions.BaseHandlerTest; +import org.jclouds.sqs.domain.BatchResult; +import org.jclouds.sqs.domain.MessageIdAndMD5; +import org.jclouds.sqs.xml.SendMessageBatchResponseHandler; +import org.testng.annotations.Test; + +import com.google.common.hash.HashCodes; + +/** + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during +// surefire +@Test(groups = "unit", testName = "SendMessageBatchResponseTest") +public class SendMessageBatchResponseTest extends BaseHandlerTest { + + public void test() { + InputStream is = getClass().getResourceAsStream("/send_message_batch.xml"); + + BatchResult<MessageIdAndMD5> expected = expected(); + + SendMessageBatchResponseHandler handler = injector.getInstance(SendMessageBatchResponseHandler.class); + BatchResult<MessageIdAndMD5> result = factory.create(handler).parse(is); + + assertEquals(result.toString(), expected.toString()); + + } + + public BatchResult<MessageIdAndMD5> expected() { + return BatchResult + .<MessageIdAndMD5> builder() + .put("test_msg_001", + MessageIdAndMD5.builder().id("0a5231c7-8bff-4955-be2e-8dc7c50a25fa") + .md5(HashCodes.fromBytes(CryptoStreams.hex("0e024d309850c78cba5eabbeff7cae71"))).build()) + .put("test_msg_002", + MessageIdAndMD5.builder().id("15ee1ed3-87e7-40c1-bdaa-2e49968ea7e9") + .md5(HashCodes.fromBytes(CryptoStreams.hex("7fb8146a82f95e0af155278f406862c2"))).build()) + .build(); + } +} diff --git a/labs/sqs/src/test/resources/change_message_visibility_batch.xml b/labs/sqs/src/test/resources/change_message_visibility_batch.xml new file mode 100644 index 0000000000..bfc4707d34 --- /dev/null +++ b/labs/sqs/src/test/resources/change_message_visibility_batch.xml @@ -0,0 +1,13 @@ +<ChangeMessageVisibilityBatchResponse> + <ChangeMessageVisibilityBatchResult> + <ChangeMessageVisibilityBatchResultEntry> + <Id>change_visibility_msg_2</Id> + </ChangeMessageVisibilityBatchResultEntry> + <ChangeMessageVisibilityBatchResultEntry> + <Id>change_visibility_msg_3</Id> + </ChangeMessageVisibilityBatchResultEntry> + </ChangeMessageVisibilityBatchResult> + <ResponseMetadata> + <RequestId>ca9668f7-ab1b-4f7a-8859-f15747ab17a7</RequestId> + </ResponseMetadata> +</ChangeMessageVisibilityBatchResponse> \ No newline at end of file diff --git a/labs/sqs/src/test/resources/delete_message_batch.xml b/labs/sqs/src/test/resources/delete_message_batch.xml new file mode 100644 index 0000000000..aeaefa7f5e --- /dev/null +++ b/labs/sqs/src/test/resources/delete_message_batch.xml @@ -0,0 +1,13 @@ +<DeleteMessageBatchResponse> + <DeleteMessageBatchResult> + <DeleteMessageBatchResultEntry> + <Id>msg1</Id> + </DeleteMessageBatchResultEntry> + <DeleteMessageBatchResultEntry> + <Id>msg2</Id> + </DeleteMessageBatchResultEntry> + </DeleteMessageBatchResult> + <ResponseMetadata> + <RequestId>d6f86b7a-74d1-4439-b43f-196a1e29cd85</RequestId> + </ResponseMetadata> +</DeleteMessageBatchResponse> \ No newline at end of file diff --git a/labs/sqs/src/test/resources/send_message_batch.xml b/labs/sqs/src/test/resources/send_message_batch.xml new file mode 100644 index 0000000000..5761d08ea9 --- /dev/null +++ b/labs/sqs/src/test/resources/send_message_batch.xml @@ -0,0 +1,17 @@ +<SendMessageBatchResponse> + <SendMessageBatchResult> + <SendMessageBatchResultEntry> + <Id>test_msg_001</Id> + <MessageId>0a5231c7-8bff-4955-be2e-8dc7c50a25fa</MessageId> + <MD5OfMessageBody>0e024d309850c78cba5eabbeff7cae71</MD5OfMessageBody> + </SendMessageBatchResultEntry> + <SendMessageBatchResultEntry> + <Id>test_msg_002</Id> + <MessageId>15ee1ed3-87e7-40c1-bdaa-2e49968ea7e9</MessageId> + <MD5OfMessageBody>7fb8146a82f95e0af155278f406862c2</MD5OfMessageBody> + </SendMessageBatchResultEntry> + </SendMessageBatchResult> + <ResponseMetadata> + <RequestId>ca1ad5d0-8271-408b-8d0f-1351bf547e74</RequestId> + </ResponseMetadata> +</SendMessageBatchResponse> \ No newline at end of file