* 'master' of https://github.com/bastiao/jclouds:
  Remove printfs and adding comments
  adding some test functions to putAttributes
  Adding simpledb demo to module of parent pom.xml, forget it
  adding a simpledb demo
  Revert properties to use https
  Adding Support to putAttributes and Select
This commit is contained in:
Adrian Cole 2011-01-01 01:52:19 +01:00
commit e1fa18a6a6
19 changed files with 540 additions and 2 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

@ -0,0 +1,63 @@
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();
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

@ -21,5 +21,6 @@
*
* @see <a href="http://docs.amazonwebservices.com/AmazonSimpleDB/2009-04-15/DeveloperGuide/index.html"/>
* @author Adrian Cole
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*/
package org.jclouds.aws.simpledb;

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"
* />

View File

@ -23,6 +23,7 @@ import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Properties;
import org.jclouds.aws.domain.Region;
@ -96,12 +97,32 @@ public class SimpleDBAsyncClientTest extends RestClientTest<SimpleDBAsyncClient>
}
public void testAllRegions() throws SecurityException, NoSuchMethodException, IOException {
Method method = SimpleDBAsyncClient.class.getMethod("createDomainInRegion", String.class, String.class);
Method method = SimpleDBAsyncClient.class.getMethod("putAttributes", String.class, String.class);
for (String region : Region.ALL_SIMPLEDB) {
processor.createRequest(method, region, "domainName");
}
}
public void testPutAttributes() throws SecurityException, NoSuchMethodException, IOException {
Method method = SimpleDBAsyncClient.class.getMethod("putAttributes", String.class, String.class, Map.class);
HttpRequest request = processor.createRequest(method, null, "domainName");
assertRequestLineEquals(request, "POST https://sdb.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: sdb.amazonaws.com\n");
assertPayloadEquals(request, "Version=2009-04-15&Action=PutAttributes&DomainName=domainName&ItemName=itemName" +
"&Attribute.1.Name=name" +
"&Attribute.1.Value=fuzzy" +
"&Attribute.1.Replace=true",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
@Override
protected void checkFilters(HttpRequest request) {
assertEquals(request.getFilters().size(), 1);

View File

@ -37,6 +37,7 @@
<module>createlamp</module>
<module>speedtest-sqs</module>
<module>createandlistbuckets</module>
<module>simpledb</module>
</modules>
<dependencies>

View File

@ -0,0 +1,29 @@
====
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.
====================================================================
====
#
# this is a simple example command line client to test usage of simpledb
# functions like putAttribute is tested and then it select and retrieve results.
# 1. execute 'mvn install' to build the sample
# 2. invoke the jar, passing your aws credentials and the bucket you wish to create
# ex.
# java -jar target/jclouds-aws-demo-simpledb-jar-with-dependencies.jar $AWS_USER $AWS_PWD simpledbtest
# Further information: Luís A. astião Silva bastiao@ua.pt>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
====================================================================
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-aws-demos-project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>jclouds-aws-demo-simpledb</artifactId>
<name>jclouds simpledb sample that putAttributes and select it</name>
<description>jclouds simpledb sample that putAttributes and select it</description>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>org.jclouds.aws.s3.samples.MainApp</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>org.jclouds.aws.simpledb.samples.MainApp</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,80 @@
/**
*
* 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.samples;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.simpledb.SimpleDBAsyncClient;
import org.jclouds.aws.simpledb.SimpleDBClient;
import org.jclouds.aws.simpledb.domain.AttributePair;
import org.jclouds.aws.simpledb.domain.Item;
import org.jclouds.aws.simpledb.options.ListDomainsOptions;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
/**
* This the Main class of an Application that demonstrates the use of the simpledb.
*
* Usage is: java MainApp \"accesskeyid\" \"secretkey\"
*
* @author Luís A. Bastião Silva <bastiao@ua.pt>
*
*/
public class MainApp
{
public static int PARAMETERS = 3;
public static String INVALID_SYNTAX = "Invalid number of parameters. Syntax is: \"accesskeyid\" \"secretkey\" \"bucketName\" ";
public static void main(String[] args) throws IOException {
// Args
String accesskeyid = args[0];
String secretkey = args[1];
Properties properties = new Properties();
properties.setProperty("simpledb.identity", accesskeyid);
properties.setProperty("simpledb.credential", secretkey);
RestContext<SimpleDBClient, SimpleDBAsyncClient> context = new RestContextFactory().createContext("simpledb", "AKIAJODKICBEKG7MM4XA", "FfqiNSiC88B6tJPDIOKUWUJGY68BQaQpkNz6Fsgq", new Properties());
AttributePair p = new AttributePair("AccessNumber", "1213123", true);
Multimap<String,AttributePair> m =LinkedHashMultimap.create();
m.put("AccessNumber", p);
Item attributes = new Item(m);
// Use Provider API
context.getApi().putAttributes(Region.EU_WEST_1, "tse", "AccessNumber", attributes );
//context.getApi().createDomainInRegion(Region.EU_WEST_1, "tse");
Map<String, Item> results = context.getApi().select(Region.EU_WEST_1, "select * from tse");
System.out.println(results);
ListDomainsOptions [] list = new ListDomainsOptions[100];
//context.getApi().listDomainsInRegion(Region.EU_WEST_1, list);
System.out.println(list[0]);
context.close();
}
}