/*
* Copyright 2014-2015 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.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. 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.codesamples.lowlevel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.DeleteItemRequest;
import com.amazonaws.services.dynamodbv2.model.GetItemRequest;
import com.amazonaws.services.dynamodbv2.model.GetItemResult;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
public class LowLevelItemBinaryExample {
static AmazonDynamoDBClient client = new AmazonDynamoDBClient(new ProfileCredentialsProvider());
static String tableName = "Reply";
static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
public static void main(String[] args) throws IOException {
try {
// Format the primary key values
String threadId = "Amazon DynamoDB#DynamoDB Thread 2";
dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String replyDateTime = dateFormatter.format(new Date());
// Add a new reply with a binary attribute type
createItem(threadId, replyDateTime);
// Retrieve the reply with a binary attribute type
retrieveItem(threadId, replyDateTime);
// clean up by deleting the item
deleteItem(threadId, replyDateTime);
} catch (Exception e) {
System.err.println("Error running the binary attribute type example: " + e);
e.printStackTrace(System.err);
}
}
public static void createItem(String threadId, String replyDateTime) throws IOException {
// Craft a long message
String messageInput = "Long message to be compressed in a lengthy forum reply";
// Compress the long message
ByteBuffer compressedMessage = compressString(messageInput.toString());
// Add a the reply
Map<String, AttributeValue> replyInput = new HashMap<String, AttributeValue>();
replyInput.put("Id", new AttributeValue().withS(threadId));
replyInput.put("ReplyDateTime", new AttributeValue().withS(replyDateTime));
replyInput.put("Message", new AttributeValue().withS("Long message follows"));
replyInput.put("ExtendedMessage", new AttributeValue().withB(compressedMessage));
replyInput.put("PostedBy", new AttributeValue().withS("User A"));
PutItemRequest putReplyRequest = new PutItemRequest().withTableName(tableName).withItem(replyInput);
client.putItem(putReplyRequest);
}
public static void retrieveItem(String threadId, String replyDateTime) throws IOException {
HashMap<String, AttributeValue> key = new HashMap<String, AttributeValue>();
key.put("Id", new AttributeValue().withS(threadId));
key.put("ReplyDateTime", new AttributeValue().withS(replyDateTime));
GetItemRequest getReplyRequest = new GetItemRequest()
.withTableName(tableName)
.withKey(key)
.withConsistentRead(true);
GetItemResult getReplyResult = client.getItem(getReplyRequest);
// Decompress the reply message and print
Map<String, AttributeValue> reply = getReplyResult.getItem();
String message = decompressString(reply.get("ExtendedMessage").getB());
System.out.println("Reply message:\n"
+ " Id: " + reply.get("Id").getS() + "\n"
+ " ReplyDateTime: " + reply.get("ReplyDateTime").getS() + "\n"
+ " PostedBy: " + reply.get("PostedBy").getS() + "\n"
+ " Message: " + reply.get("Message").getS() + "\n"
+ " ExtendedMessage (decompressed): " + message);
}
public static void deleteItem(String threadId, String replyDateTime) {
HashMap<String, AttributeValue> key = new HashMap<String, AttributeValue>();
key.put("Id", new AttributeValue().withS(threadId));
key.put("ReplyDateTime", new AttributeValue().withS(replyDateTime));
DeleteItemRequest deleteReplyRequest = new DeleteItemRequest()
.withTableName(tableName)
.withKey(key);
client.deleteItem(deleteReplyRequest);
}
private static ByteBuffer compressString(String input) throws IOException {
// Compress the UTF-8 encoded String into a byte[]
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream os = new GZIPOutputStream(baos);
os.write(input.getBytes("UTF-8"));
os.finish();
byte[] compressedBytes = baos.toByteArray();
// The following code writes the compressed bytes to a ByteBuffer.
// A simpler way to do this is by simply calling ByteBuffer.wrap(compressedBytes);
// However, the longer form below shows the importance of resetting the position of the buffer
// back to the beginning of the buffer if you are writing bytes directly to it, since the SDK
// will consider only the bytes after the current position when sending data to DynamoDB.
// Using the "wrap" method automatically resets the position to zero.
ByteBuffer buffer = ByteBuffer.allocate(compressedBytes.length);
buffer.put(compressedBytes, 0, compressedBytes.length);
buffer.position(0); // Important: reset the position of the ByteBuffer to the beginning
return buffer;
}
private static String decompressString(ByteBuffer input) throws IOException {
byte[] bytes = input.array();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPInputStream is = new GZIPInputStream(bais);
int chunkSize = 1024;
byte[] buffer = new byte[chunkSize];
int length = 0;
while ((length = is.read(buffer, 0, chunkSize)) != -1) {
baos.write(buffer, 0, length);
}
return new String(baos.toByteArray(), "UTF-8");
}
}