/* * Copyright (c) 2011-2014 Jeppetto and Jonathan Thompson * * 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.iternine.jeppetto.dao.dynamodb.examples.forum; import org.iternine.jeppetto.dao.dynamodb.iterable.DynamoDBIterable; import org.iternine.jeppetto.dao.test.examples.forum.ForumDAO; import org.iternine.jeppetto.dao.test.examples.forum.ForumTest; import org.iternine.jeppetto.dao.test.examples.forum.Reply; import org.iternine.jeppetto.dao.test.examples.forum.ReplyDAO; import org.iternine.jeppetto.dao.test.examples.forum.ThreadDAO; import org.iternine.jeppetto.testsupport.DynamoDBDatabaseProvider; import org.iternine.jeppetto.testsupport.TestContext; import com.amazonaws.services.dynamodbv2.model.AttributeDefinition; import com.amazonaws.services.dynamodbv2.model.CreateTableRequest; import com.amazonaws.services.dynamodbv2.model.KeySchemaElement; import com.amazonaws.services.dynamodbv2.model.KeyType; import com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndex; import com.amazonaws.services.dynamodbv2.model.Projection; import com.amazonaws.services.dynamodbv2.model.ProjectionType; import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType; import junit.framework.Assert; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.List; /** */ public class DynamoDBForumTest extends ForumTest { //------------------------------------------------------------- // Constants //------------------------------------------------------------- public static final String FORUM_TEST_SPRING_XML = "DynamoDBForumTest.spring.xml"; //------------------------------------------------------------- // Variables - Private //------------------------------------------------------------- private TestContext testContext; private List<CreateTableRequest> createTableRequests = new ArrayList<CreateTableRequest>() { { add(new CreateTableRequest(Collections.singletonList(new AttributeDefinition("name", ScalarAttributeType.S)), "Forum", Collections.singletonList(new KeySchemaElement("name", KeyType.HASH)), new ProvisionedThroughput(1L, 1L))); add(new CreateTableRequest(Arrays.asList(new AttributeDefinition("forumName", ScalarAttributeType.S), new AttributeDefinition("subject", ScalarAttributeType.S)), "Thread", Arrays.asList(new KeySchemaElement("forumName", KeyType.HASH), new KeySchemaElement("subject", KeyType.RANGE)), new ProvisionedThroughput(1L, 1L))); add(new CreateTableRequest(Arrays.asList(new AttributeDefinition("id", ScalarAttributeType.S), new AttributeDefinition("replyDate", ScalarAttributeType.N), new AttributeDefinition("postedBy", ScalarAttributeType.S)), "Reply", Arrays.asList(new KeySchemaElement("id", KeyType.HASH), new KeySchemaElement("replyDate", KeyType.RANGE)), new ProvisionedThroughput(1L, 1L)) .withLocalSecondaryIndexes(new LocalSecondaryIndex().withIndexName("postedBy-Index") .withKeySchema(new KeySchemaElement("id", KeyType.HASH), new KeySchemaElement("postedBy", KeyType.RANGE)) .withProjection(new Projection().withProjectionType(ProjectionType.ALL)))); } }; //------------------------------------------------------------- // Methods - Implementation //------------------------------------------------------------- @Override protected ForumDAO getForumDAO() { if (testContext == null) { testContext = new TestContext(FORUM_TEST_SPRING_XML, "DynamoDBTest.properties", new DynamoDBDatabaseProvider(createTableRequests)); } //noinspection unchecked return (ForumDAO) testContext.getBean("forumDAO"); } @Override protected ThreadDAO getThreadDAO() { if (testContext == null) { testContext = new TestContext(FORUM_TEST_SPRING_XML, "DynamoDBTest.properties", new DynamoDBDatabaseProvider(createTableRequests)); } //noinspection unchecked return (ThreadDAO) testContext.getBean("threadDAO"); } @Override protected ReplyDAO getReplyDAO() { if (testContext == null) { testContext = new TestContext(FORUM_TEST_SPRING_XML, "DynamoDBTest.properties", new DynamoDBDatabaseProvider(createTableRequests)); } //noinspection unchecked return (ReplyDAO) testContext.getBean("replyDAO"); } @Override protected void reset() { if (testContext != null) { testContext.close(); testContext = null; } } //------------------------------------------------------------- // Tests //------------------------------------------------------------- @Test public void testPosition() { createData(); createAdditionalData(); int pageSize = 2; int page = 0; int itemCounter; String queryPosition = null; int totalItems = 0; do { Iterable<Reply> iterable = getReplyDAO().findByIdAndLimit(DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1, pageSize + 1); ((DynamoDBIterable) iterable).setPosition(queryPosition); page++; itemCounter = 0; for (Reply reply : iterable) { Assert.assertEquals(DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1, reply.getId()); System.out.println(reply.getMessage()); itemCounter++; totalItems++; if (itemCounter == pageSize) { break; } } queryPosition = ((DynamoDBIterable) iterable).getPosition(); } while (queryPosition != null); Assert.assertEquals(4, page); Assert.assertEquals(7, totalItems); } @Test public void testPaging() { createData(); createAdditionalData(); String replyId = DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1; int pageSize = 2; int totalItems = 0; DynamoDBIterable<Reply> iterable = (DynamoDBIterable<Reply>) getReplyDAO().findByIdAndLimit(replyId, pageSize); iterable.setLimit(pageSize); for (Reply reply : iterable) { Assert.assertEquals(replyId, reply.getId()); totalItems++; } Assert.assertEquals(2, totalItems); Assert.assertTrue(iterable.hasResultsPastLimit()); } @Test public void testPosition2() { createData(); createAdditionalData(); String replyId = DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1; int pageSize = 3; String queryPosition = getReplyPage(replyId, pageSize, null, 3); // First page, no existing queryPosition queryPosition = getReplyPage(replyId, pageSize, queryPosition, 3); queryPosition = getReplyPage(replyId, pageSize, queryPosition, 1); Assert.assertNull(queryPosition); } @Test public void testSortByReplyDate() { createData(); createAdditionalData(); String replyId = DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1; List<Reply> results = getReplyDAO().findByIdOrderByReplyDateDesc(replyId); Assert.assertEquals(7, results.size()); Date previousReplyDate = null; for (Reply reply : results) { if (previousReplyDate != null) { Assert.assertTrue(previousReplyDate.after(reply.getReplyDate())); } previousReplyDate = reply.getReplyDate(); } } @Test public void testSortByPostedBy() { createData(); createAdditionalData(); String replyId = DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1; List<Reply> results = getReplyDAO().findByIdOrderByPostedByAsc(replyId); Assert.assertEquals(7, results.size()); String previousPostedBy = null; for (Reply reply : results) { if (previousPostedBy != null) { Assert.assertTrue(previousPostedBy.compareTo(reply.getPostedBy()) <= 0); } previousPostedBy = reply.getPostedBy(); } } //------------------------------------------------------------- // Methods - Private //------------------------------------------------------------- private void createAdditionalData() { Date seventeenDaysAgo = new Date((new Date()).getTime() - (17*24*60*60*1000)); Date tenDaysAgo = new Date((new Date()).getTime() - (10*24*60*60*1000)); Date twoDaysAgo = new Date((new Date()).getTime() - (2*24*60*60*1000)); // Add more Replies getReplyDAO().save(new Reply(DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1, "DynamoDB Thread 1 Reply 3 text", USER_A, seventeenDaysAgo)); getReplyDAO().save(new Reply(DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1, "DynamoDB Thread 1 Reply 4 text", USER_B, tenDaysAgo)); getReplyDAO().save(new Reply(DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1, "DynamoDB Thread 1 Reply 5 text", USER_A, sevenDaysAgo)); getReplyDAO().save(new Reply(DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1, "DynamoDB Thread 1 Reply 6 text", USER_A, twoDaysAgo)); getReplyDAO().save(new Reply(DYNAMODB_FORUM + "#" + DYNAMODB_THREAD_1, "DynamoDB Thread 1 Reply 7 text", USER_A, oneDayAgo)); } private String getReplyPage(String replyId, int pageSize, String queryPosition, int expected) { DynamoDBIterable<Reply> iterable = (DynamoDBIterable<Reply>) getReplyDAO().findByIdAndLimit(replyId, pageSize); iterable.setPosition(queryPosition); iterable.setLimit(pageSize); int count = 0; for (Reply reply : iterable) { Assert.assertEquals(replyId, reply.getId()); count++; } Assert.assertEquals(expected, count); return iterable.hasResultsPastLimit() ? iterable.getPosition() : null; } }