Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
The AWS SDK for Java with support for OSGi. The AWS SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).
/*
* Copyright 2015-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* 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://aws.amazon.com/apache2.0
*
* This file 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 com.amazonaws.services.dynamodbv2.datamodeling;
import static com.amazonaws.services.dynamodbv2.model.KeyType.HASH;
import static com.amazonaws.services.dynamodbv2.model.KeyType.RANGE;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.AmazonWebServiceRequest;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.retry.RetryUtils;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.BatchLoadRetryStrategy;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.BatchWriteRetryStrategy;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.ConsistentReads;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.SaveBehavior;
import com.amazonaws.services.dynamodbv2.model.AttributeAction;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate;
import com.amazonaws.services.dynamodbv2.model.BatchGetItemRequest;
import com.amazonaws.services.dynamodbv2.model.BatchGetItemResult;
import com.amazonaws.services.dynamodbv2.model.BatchWriteItemRequest;
import com.amazonaws.services.dynamodbv2.model.BatchWriteItemResult;
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
import com.amazonaws.services.dynamodbv2.model.Condition;
import com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException;
import com.amazonaws.services.dynamodbv2.model.ConditionalOperator;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.DeleteItemRequest;
import com.amazonaws.services.dynamodbv2.model.DeleteRequest;
import com.amazonaws.services.dynamodbv2.model.DeleteTableRequest;
import com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue;
import com.amazonaws.services.dynamodbv2.model.GetItemRequest;
import com.amazonaws.services.dynamodbv2.model.GetItemResult;
import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndex;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeysAndAttributes;
import com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndex;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
import com.amazonaws.services.dynamodbv2.model.PutItemResult;
import com.amazonaws.services.dynamodbv2.model.PutRequest;
import com.amazonaws.services.dynamodbv2.model.QueryRequest;
import com.amazonaws.services.dynamodbv2.model.QueryResult;
import com.amazonaws.services.dynamodbv2.model.ReturnValue;
import com.amazonaws.services.dynamodbv2.model.ScanRequest;
import com.amazonaws.services.dynamodbv2.model.ScanResult;
import com.amazonaws.services.dynamodbv2.model.Select;
import com.amazonaws.services.dynamodbv2.model.UpdateItemRequest;
import com.amazonaws.services.dynamodbv2.model.UpdateItemResult;
import com.amazonaws.services.dynamodbv2.model.WriteRequest;
import com.amazonaws.services.s3.model.Region;
import com.amazonaws.util.VersionInfoUtils;
/**
* Object mapper for domain-object interaction with DynamoDB.
*
* To use, define a domain class that represents an item in a DynamoDB table and
* annotate it with the annotations found in the
* com.amazonaws.services.dynamodbv2.datamodeling package. In order to allow the
* mapper to correctly persist the data, each modeled property in the domain
* class should be accessible via getter and setter methods, and each property
* annotation should be either applied to the getter method or the class field.
* A minimal example using getter annotations:
*
*
* @DynamoDBTable(tableName = "TestTable")
* public class TestClass {
*
* private Long key;
* private double rangeKey;
* private Long version;
*
* private Set<Integer> integerSetAttribute;
*
* @DynamoDBHashKey
* public Long getKey() {
* return key;
* }
*
* public void setKey(Long key) {
* this.key = key;
* }
*
* @DynamoDBRangeKey
* public double getRangeKey() {
* return rangeKey;
* }
*
* public void setRangeKey(double rangeKey) {
* this.rangeKey = rangeKey;
* }
*
* @DynamoDBAttribute(attributeName = "integerSetAttribute")
* public Set<Integer> getIntegerAttribute() {
* return integerSetAttribute;
* }
*
* public void setIntegerAttribute(Set<Integer> integerAttribute) {
* this.integerSetAttribute = integerAttribute;
* }
*
* @DynamoDBVersionAttribute
* public Long getVersion() {
* return version;
* }
*
* public void setVersion(Long version) {
* this.version = version;
* }
* }
*
*
* Save instances of annotated classes to DynamoDB, retrieve them, and delete
* them using the {@link DynamoDBMapper} class, as in the following example.
*
*
* If you don't have your DynamoDB table set up yet, you can use
* {@link DynamoDBMapper#generateCreateTableRequest(Class)} to construct the
* {@link CreateTableRequest} for the table represented by your annotated class.
*
*
* AmazonDynamoDB dynamoDBClient = new AmazonDynamoDBClient();
* DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient);
* CreateTableRequest req = mapper.generateCreateTableRequest(TestClass.class);
* // Table provision throughput is still required since it cannot be specified in your POJO
* req.setProvisionedThroughput(new ProvisionedThroughput(5L, 5L));
* // Fire off the CreateTableRequest using the low-level client
* dynamoDBClient.createTable(req);
*
*
* When using the save, load, and delete methods, {@link DynamoDBMapper} will
* throw {@link DynamoDBMappingException}s to indicate that domain classes are
* incorrectly annotated or otherwise incompatible with this class. Service
* exceptions will always be propagated as {@link AmazonClientException}, and
* DynamoDB-specific subclasses such as {@link ConditionalCheckFailedException}
* will be used when possible.
*
* This class is thread-safe and can be shared between threads. It's also very
* lightweight, so it doesn't need to be.
*
* @see DynamoDBTable
* @see DynamoDBHashKey
* @see DynamoDBRangeKey
* @see DynamoDBAutoGeneratedKey
* @see DynamoDBAttribute
* @see DynamoDBVersionAttribute
* @see DynamoDBIgnore
* @see DynamoDBMarshalling
* @see DynamoDBMapperConfig
*/
public class DynamoDBMapper extends AbstractDynamoDBMapper {
private final S3ClientCache s3cc;
private final AmazonDynamoDB db;
private final DynamoDBMapperConfig config;
private final DynamoDBMapperModelFactory.Factory models;
private final AttributeTransformer transformer;
/**
* The max back off time for batch get. The configuration for batch write
* has been moved to DynamoDBMapperConfig
*/
static final long MAX_BACKOFF_IN_MILLISECONDS = 1000 * 3;
/** The max number of items allowed in a BatchWrite request */
static final int MAX_ITEMS_PER_BATCH = 25;
/**
* This retry count is applicable only when every batch get item request
* results in no data retrieved from server and the un processed keys is
* same as request items
*/
static final int BATCH_GET_MAX_RETRY_COUNT_ALL_KEYS = 5;
/**
* User agent for requests made using the {@link DynamoDBMapper}.
*/
private static final String USER_AGENT =
DynamoDBMapper.class.getName() + "/" + VersionInfoUtils.getVersion();
private static final String USER_AGENT_BATCH_OPERATION =
DynamoDBMapper.class.getName() + "_batch_operation/" + VersionInfoUtils.getVersion();
private static final String NO_RANGE_KEY = new String();
private static final Log log = LogFactory.getLog(DynamoDBMapper.class);
/**
* Fail fast when trying to create a subclass of the DynamoDBMapper that
* attempts to override one of the old {@code transformAttributes} methods.
*/
private static void failFastOnIncompatibleSubclass(Class> clazz) {
while (clazz != DynamoDBMapper.class) {
Class>[] classOverride = new Class>[] {
Class.class,
Map.class
};
Class>[] nameOverride = new Class>[] {
String.class,
String.class,
Map.class
};
for (Method method : clazz.getDeclaredMethods()) {
if (method.getName().equals("transformAttributes")) {
Class>[] params = method.getParameterTypes();
if (Arrays.equals(params, classOverride)
|| Arrays.equals(params, nameOverride)) {
throw new IllegalStateException(
"The deprecated transformAttributes method is "
+ "no longer supported as of 1.9.0. Use an "
+ "AttributeTransformer to inject custom "
+ "attribute transformation logic.");
}
}
}
clazz = clazz.getSuperclass();
}
}
/**
* Constructs a new mapper with the service object given, using the default
* configuration.
*
* @param dynamoDB
* The service object to use for all service calls.
* @see DynamoDBMapperConfig#DEFAULT
*/
public DynamoDBMapper(final AmazonDynamoDB dynamoDB) {
this(dynamoDB, DynamoDBMapperConfig.DEFAULT, null, null);
}
/**
* Constructs a new mapper with the service object and configuration given.
*
* @param dynamoDB
* The service object to use for all service calls.
* @param config
* The default configuration to use for all service calls. It can
* be overridden on a per-operation basis.
*/
public DynamoDBMapper(
final AmazonDynamoDB dynamoDB,
final DynamoDBMapperConfig config) {
this(dynamoDB, config, null, null);
}
/**
* Constructs a new mapper with the service object and S3 client cache
* given, using the default configuration.
*
* @param ddb
* The service object to use for all service calls.
* @param s3CredentialProvider
* The credentials provider for accessing S3.
* Relevant only if {@link S3Link} is involved.
* @see DynamoDBMapperConfig#DEFAULT
*/
public DynamoDBMapper(
final AmazonDynamoDB ddb,
final AWSCredentialsProvider s3CredentialProvider) {
this(ddb, DynamoDBMapperConfig.DEFAULT, s3CredentialProvider);
}
/**
* Constructs a new mapper with the given service object, configuration,
* and transform hook.
*
* @param dynamoDB
* the service object to use for all service calls
* @param config
* the default configuration to use for all service calls. It
* can be overridden on a per-operation basis
* @param transformer
* The custom attribute transformer to invoke when serializing or
* deserializing an object.
*/
public DynamoDBMapper(
final AmazonDynamoDB dynamoDB,
final DynamoDBMapperConfig config,
final AttributeTransformer transformer) {
this(dynamoDB, config, transformer, null);
}
/**
* Constructs a new mapper with the service object, configuration, and S3
* client cache given.
*
* @param dynamoDB
* The service object to use for all service calls.
* @param config
* The default configuration to use for all service calls. It can
* be overridden on a per-operation basis.
* @param s3CredentialProvider
* The credentials provider for accessing S3.
* Relevant only if {@link S3Link} is involved.
*/
public DynamoDBMapper(
final AmazonDynamoDB dynamoDB,
final DynamoDBMapperConfig config,
final AWSCredentialsProvider s3CredentialProvider) {
this(dynamoDB, config, null, validate(s3CredentialProvider));
}
/**
* Throws an exception if the given credentials provider is {@code null}.
*/
private static AWSCredentialsProvider validate(
final AWSCredentialsProvider provider) {
if (provider == null) {
throw new IllegalArgumentException(
"s3 credentials provider must not be null");
}
return provider;
}
/**
* Constructor with all parameters.
*
* @param dynamoDB
* The service object to use for all service calls.
* @param config
* The default configuration to use for all service calls. It can
* be overridden on a per-operation basis.
* @param transformer
* The custom attribute transformer to invoke when serializing or
* deserializing an object.
* @param s3CredentialProvider
* The credentials provider for accessing S3.
* Relevant only if {@link S3Link} is involved.
*/
public DynamoDBMapper(
final AmazonDynamoDB dynamoDB,
final DynamoDBMapperConfig config,
final AttributeTransformer transformer,
final AWSCredentialsProvider s3CredentialsProvider) {
failFastOnIncompatibleSubclass(getClass());
this.db = dynamoDB;
this.config = config;
this.transformer = transformer;
if (s3CredentialsProvider == null) {
this.s3cc = null;
} else {
this.s3cc = new S3ClientCache(s3CredentialsProvider);
}
this.models = StandardModelFactories.of(new ConversionSchema.Dependencies()
.with(S3ClientCache.class, this.s3cc));
}
private DynamoDBMapperTableModel getTableModel(Class clazz, DynamoDBMapperConfig config) {
return this.models.getModelFactory(config).getTableModel(clazz);
}
@Override
public T load(Class clazz, Object hashKey, DynamoDBMapperConfig config) {
return load(clazz, hashKey, null, config);
}
@Override
public T load(Class clazz, Object hashKey) {
return load(clazz, hashKey, null, config);
}
@Override
public T load(Class clazz, Object hashKey, Object rangeKey) {
return load(clazz, hashKey, rangeKey, config);
}
@Override
public T load(T keyObject) {
return load(keyObject, this.config);
}
@Override
public T load(T keyObject, DynamoDBMapperConfig config) {
@SuppressWarnings("unchecked")
Class clazz = (Class) keyObject.getClass();
config = mergeConfig(config);
final DynamoDBMapperTableModel model = getTableModel(clazz, config);
String tableName = getTableName(clazz, keyObject, config);
GetItemRequest rq = new GetItemRequest()
.withRequestMetricCollector(config.getRequestMetricCollector());
Map key = model.mapKey(keyObject);
rq.setKey(key);
rq.setTableName(tableName);
rq.setConsistentRead(config.getConsistentReads() == ConsistentReads.CONSISTENT);
GetItemResult item = db.getItem(applyUserAgent(rq));
Map itemAttributes = item.getItem();
if ( itemAttributes == null ) {
return null;
}
T object = privateMarshallIntoObject(
toParameters(itemAttributes, clazz, tableName, config));
return object;
}
@Override
public T load(Class clazz, Object hashKey, Object rangeKey, DynamoDBMapperConfig config) {
config = mergeConfig(config);
final DynamoDBMapperTableModel model = getTableModel(clazz, config);
T keyObject = model.newKey(hashKey, rangeKey);
return load(keyObject, config);
}
/**
* Returns a map of attribute name to EQ condition for the key prototype
* object given. This method considers attributes annotated with either
* {@link DynamoDBHashKey} or {@link DynamoDBIndexHashKey}.
*
* @param obj
* The prototype object that includes the hash key value.
* @return A map of hash key attribute name to EQ condition for the key
* prototype object, or an empty map if obj is null.
*/
private Map getHashKeyEqualsConditions(
DynamoDBMapperTableModel model,
T obj) {
Map conditions = new HashMap();
if (obj == null) {
return conditions;
}
for (final DynamoDBMapperFieldModel field : model.fields()) {
if (field.anyKey(HASH)) {
final Object getterReturnResult = field.get(obj);
if (getterReturnResult != null) {
conditions.put(field.name(), field.eq(getterReturnResult));
}
}
}
return conditions;
}
/**
* Returns the table name for the class given.
*/
protected final String getTableName(final Class> clazz,
final DynamoDBMapperConfig config) {
return internalGetTableName(clazz, null, config);
}
/**
* Returns the table name for the class or object given.
*/
protected final String getTableName(final Class> clazz,
final Object object,
final DynamoDBMapperConfig config) {
return internalGetTableName(clazz, object, config);
}
static String internalGetTableName(final Class> clazz,
final Object object,
final DynamoDBMapperConfig config) {
// Resolve by object, if possible and desired
DynamoDBMapperConfig.ObjectTableNameResolver objectResolver = config.getObjectTableNameResolver();
if (object != null && objectResolver != null) {
return objectResolver.getTableName(object, config);
}
// Resolve by class
return config.getTableNameResolver(true).getTableName(clazz, config);
}
@Override
public T marshallIntoObject(Class clazz, Map itemAttributes) {
String tableName = getTableName(clazz, config);
return privateMarshallIntoObject(
toParameters(itemAttributes, clazz, tableName, config));
}
/**
* The one true implementation of marshallIntoObject.
*/
private T privateMarshallIntoObject(
AttributeTransformer.Parameters parameters) {
Class clazz = parameters.getModelClass();
Map values = untransformAttributes(parameters);
final DynamoDBMapperTableModel model = getTableModel(clazz, parameters.getMapperConfig());
return model.unconvert(values);
}
@Override
public List marshallIntoObjects(Class clazz, List