Adding Support to putAttributes and Select

This commit is contained in:
Luis A. Bastiao Silva 2010-12-18 15:42:37 +00:00
parent a1bf070c7a
commit 0c425045a5
14 changed files with 341 additions and 6 deletions

View File

@ -22,6 +22,8 @@ package org.jclouds.aws.simpledb;
import static org.jclouds.aws.simpledb.reference.SimpleDBParameters.ACTION;
import static org.jclouds.aws.simpledb.reference.SimpleDBParameters.VERSION;
import java.util.Map;
import javax.annotation.Nullable;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
@ -29,9 +31,14 @@ import javax.ws.rs.Path;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.aws.functions.RegionToEndpoint;
import org.jclouds.aws.simpledb.binders.BindAttributesToIndexedFormParams;
import org.jclouds.aws.simpledb.domain.Item;
import org.jclouds.aws.simpledb.domain.AttributePair;
import org.jclouds.aws.simpledb.domain.ListDomainsResponse;
import org.jclouds.aws.simpledb.options.ListDomainsOptions;
import org.jclouds.aws.simpledb.xml.ItemsHandler;
import org.jclouds.aws.simpledb.xml.ListDomainsResponseHandler;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
@ -45,6 +52,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* <p/>
*
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
@RequestFilters(FormSigner.class)
@FormParams(keys = VERSION, values = SimpleDBAsyncClient.VERSION)
@ -80,4 +88,28 @@ public interface SimpleDBAsyncClient {
ListenableFuture<Void> deleteDomainInRegion(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region,
@FormParam("DomainName") String domainName);
/**
* @see SimpleDBClient#putAttributes
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "PutAttributes")
ListenableFuture<Void> putAttributes(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region,
@FormParam("DomainName") String domainName,
@FormParam("ItemName") String itemName,
@BinderParam(BindAttributesToIndexedFormParams.class) Item attributes);
/**
* @see SimpleDBClient#putAttributes
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "Select")
@XMLResponseParser(ItemsHandler.class)
ListenableFuture<? extends Map<String, Item>> select(@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region,
@FormParam("SelectExpression") String selectExpression);
}

View File

@ -19,19 +19,28 @@
package org.jclouds.aws.simpledb;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import javax.ws.rs.FormParam;
import org.jclouds.aws.functions.RegionToEndpoint;
import org.jclouds.aws.simpledb.domain.Item;
import org.jclouds.aws.simpledb.domain.AttributePair;
import org.jclouds.aws.simpledb.domain.ListDomainsResponse;
import org.jclouds.aws.simpledb.options.ListDomainsOptions;
import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.EndpointParam;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to SimpleDB via their REST API.
* <p/>
*
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface SimpleDBClient {
@ -103,5 +112,6 @@ public interface SimpleDBClient {
* />
*/
void deleteDomainInRegion(String region, String domainName);
void putAttributes(String region, String domain, String itemName, Item attributes);
Map<String, Item> select(String region, String selectionExpression);
}

View File

@ -41,6 +41,7 @@ import com.google.inject.Module;
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
* @see SimpleDBContext
*/
public class SimpleDBContextBuilder extends RestContextBuilder<SimpleDBClient, SimpleDBAsyncClient> {

View File

@ -36,6 +36,7 @@ import com.google.common.base.Joiner;
* Builds properties used in SimpleDB Clients
*
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
public class SimpleDBPropertiesBuilder extends PropertiesBuilder {
@Override
@ -46,15 +47,15 @@ public class SimpleDBPropertiesBuilder extends PropertiesBuilder {
properties.setProperty(PROPERTY_API_VERSION, SimpleDBAsyncClient.VERSION);
properties.setProperty(PROPERTY_REGIONS, Joiner.on(',').join(Region.US_EAST_1,
Region.US_WEST_1, Region.EU_WEST_1, Region.AP_SOUTHEAST_1));
properties.setProperty(PROPERTY_ENDPOINT, "https://sdb.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT, "http://sdb.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_EAST_1,
"https://sdb.amazonaws.com");
"http://sdb.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1,
"https://sdb.us-west-1.amazonaws.com");
"http://sdb.us-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.EU_WEST_1,
"https://sdb.eu-west-1.amazonaws.com");
"http://sdb.eu-west-1.amazonaws.com");
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
"https://sdb.ap-southeast-1.amazonaws.com");
"http://sdb.ap-southeast-1.amazonaws.com");
return properties;
}

View File

@ -0,0 +1,66 @@
package org.jclouds.aws.simpledb.binders;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
import static org.jclouds.http.HttpUtils.addFormParamTo;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.jclouds.aws.simpledb.domain.Item;
import org.jclouds.aws.simpledb.domain.AttributePair;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
public class BindAttributesToIndexedFormParams implements Binder {
private final String attributeName = "Attribute.%d.Name";
private final String attributeValue = "Attribute.%d.Value";
private final String attributeReplace = "Attribute.%d.Replace";
public void bindToRequest(HttpRequest request, Object input) {
checkArgument(checkNotNull(input, "input") instanceof Item,
"this binder is only valid for AttributeMap");
Item attributeMap = (Item) input;
int amazonOneBasedIndex = 1; // according to docs, counters must start with 1
for (String itemName : attributeMap.getAttributes().keySet())
{
Collection<AttributePair> c = attributeMap.getAttributes().get(itemName);
Iterator<AttributePair> it = c.iterator();
while(it.hasNext())
{
AttributePair attr = it.next();
// not null by contract
String value = attr.getValue();
// System.out.println(format(attributeName, amazonOneBasedIndex)+ "" + attr.getKey());
// System.out.println(format(attributeValue, amazonOneBasedIndex)+ "" + value);
// System.out.println(format(attributeReplace, amazonOneBasedIndex) +""+ String
// .valueOf(attr.isReplace()) );
if (value != null) {
addFormParamTo(request, format(attributeName, amazonOneBasedIndex), attr.getKey() );
addFormParamTo(request, format(attributeValue, amazonOneBasedIndex),
value);
addFormParamTo(request, format(attributeReplace, amazonOneBasedIndex), String
.valueOf(attr.isReplace()));
}
amazonOneBasedIndex++;
}
}
}
}

View File

@ -29,6 +29,7 @@ import org.jclouds.rest.ConfiguresRestClient;
* Configures the SimpleDB connection.
*
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
@RequiresHttp
@ConfiguresRestClient

View File

@ -0,0 +1,62 @@
package org.jclouds.aws.simpledb.domain;
import java.util.ArrayList;
import java.util.List;
/**
* AttributePair is a class to support the attributes to put in the SimpleDB
* <p/>
*
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
public class AttributePair
{
private String key;
private String value;
private boolean replace;
/**
*
* Default constructor to represent an attribute in a domain in SimpleDB
*
* <p/>
*
* @param key Name of Attribute
* @param value Value of Attribute
* @param replace Replace value if it already exists in domain
*/
public AttributePair(String key, String value, boolean replace)
{
this.key = key;
this.value = value ;
this.replace = replace;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
public void setValue(String value)
{
this.value = value;
}
public boolean isReplace() {
return replace;
}
}

View File

@ -27,6 +27,7 @@ import java.util.Date;
* "http://docs.amazonwebservices.com/AmazonSimpleDB/2009-04-15/DeveloperGuide/index.html?SDB_API_CreateDomain.html"
* />
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
public class DomainMetadata {
private final String region;

View File

@ -0,0 +1,45 @@
package org.jclouds.aws.simpledb.domain;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
/**
* Defines the mapping of Items
*
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
public class Item {
private final Multimap<String, AttributePair> attributes = LinkedHashMultimap
.create();
public Item() {
}
/**
* Creates a map of Attribute Pair
*
*/
public Item(Multimap<String, AttributePair> attributes)
{
this.attributes.putAll(attributes);
}
public Item addAttributePair(@Nullable String itemName,
AttributePair attrPair)
{
this.attributes.put(itemName, attrPair);
return this;
}
public Multimap<String, AttributePair> getAttributes()
{
return ImmutableMultimap.<String, AttributePair> builder().putAll(
attributes).build();
}
}

View File

@ -24,6 +24,7 @@ import java.util.Set;
/**
*
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
* @see <a href="http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html" />
*/
public interface ListDomainsResponse extends Set<String> {

View File

@ -38,6 +38,7 @@ import org.jclouds.http.options.BaseHttpRequestOptions;
* <code>
*
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonSimpleDB/2009-04-15/DeveloperGuide/SDB_API_ListDomains.html"
* />

View File

@ -25,6 +25,7 @@ package org.jclouds.aws.simpledb.reference;
* @see <a href="http://docs.amazonwebservices.com/AWSSimpleDomainService/2009-02-01/APIReference/Query_QueryParams.html"
* />
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
public interface SimpleDBParameters {

View File

@ -0,0 +1,112 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed 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.aws.simpledb.xml;
import com.google.common.collect.LinkedHashMultimap;
import java.util.Map;
import org.jclouds.aws.simpledb.domain.AttributePair;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import org.jclouds.aws.simpledb.domain.Item;
import org.xml.sax.Attributes;
/**
*
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
public class ItemsHandler extends
ParseSax.HandlerWithResult<Map<String, Item>> {
private StringBuilder currentText = new StringBuilder();
private Map<String, Item> items = Maps.newConcurrentMap();
private Multimap<String, AttributePair> attributes = LinkedHashMultimap.create();
private String attributeName;
private String attributeValue = "";
private String itemName;
private boolean inside = false;
protected final DateService dateService;
@Inject
public ItemsHandler(DateService dateService) {
this.dateService = dateService;
}
public Map<String, Item> getResult() {
return items;
}
public void startElement(String uri, String localName, String qName, Attributes attributes)
{
if (qName.equals("Attribute")) {
inside = true;
}
}
public void endElement(String uri, String name, String qName)
{
if (qName.equals("Attribute"))
{
inside = false;
System.out.println("AttributeName: " + attributeName);
System.out.println("AttributeValue: " + attributeValue);
}
else if(qName.equals("Name")) {
if (inside)
attributeName = currentText.toString().trim();
else
itemName = currentText.toString().trim();
} else if (qName.equals("Value"))
{
attributeValue = currentText.toString().trim();
attributes.put(attributeName,new AttributePair(attributeName,
attributeValue, false));
}
else if (qName.equals("Item"))
{
System.out.println("ItemName: " + itemName);
Item item = new Item(attributes);
items.put(itemName, item);
attributes = LinkedHashMultimap.create();
this.attributeName = null;
this.attributeValue = null;
this.itemName = null;
inside = false;
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -34,6 +34,7 @@ import com.google.common.collect.Sets;
* ListDomainsResponse
*
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
* @see <a href=
* "http://docs.amazonwebservices.com/AmazonSimpleDB/2009-04-15/DeveloperGuide/SDB_API_ListDomains.htm l"
* />