/** * Copyright 2012 Willet Inc. * * 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 com.willetinc.hadoop.mapreduce.dynamodb; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.mapreduce.InputSplit; import org.apache.hadoop.mapreduce.Job; import org.junit.Test; import com.amazonaws.services.dynamodb.model.AttributeValue; import com.amazonaws.services.dynamodb.model.ComparisonOperator; import com.willetinc.hadoop.mapreduce.dynamodb.AbstractSplitter; import com.willetinc.hadoop.mapreduce.dynamodb.DynamoDBQueryInputFormat; import com.willetinc.hadoop.mapreduce.dynamodb.DynamoDBSplitter; import com.willetinc.hadoop.mapreduce.dynamodb.Types; import com.willetinc.hadoop.mapreduce.dynamodb.DynamoDBQueryInputFormat.DynamoDBQueryInputSplit; public class AbstractSplitterTest { @Test public void testSplitWithHashKey() throws IOException { DynamoDBSplitter splitter = new AbstractSplitter() { @Override public void generateRangeKeySplits( Configuration conf, List<InputSplit> splits, Types hashKeyType, AttributeValue hashKeyValue, Types rangeKeyType, AttributeValue minRangeKeyValue, AttributeValue maxRangeKeyValue, int numRangeSplits) { fail("This method should not be called!"); } }; final String VALUE = "007"; Types hashKeyType = Types.NUMBER; AttributeValue hashKeyValue = new AttributeValue().withN(VALUE); // configure job Job job = new Job(); Configuration conf = job.getConfiguration(); DynamoDBQueryInputFormat.setHashKeyValue(conf, hashKeyType, hashKeyValue); // generate splits List<InputSplit> splits = splitter.split(conf); // check results assertEquals(1, splits.size()); DynamoDBQueryInputSplit split = (DynamoDBQueryInputSplit) splits.get(0); assertTrue(split.hasHashKey()); assertEquals(hashKeyType, split.getHashKeyType()); assertEquals(hashKeyValue, split.getHashKeyValue()); assertFalse(split.hasRangeKey()); } @Test public void testSplitWithHashKeyAndRangeKey() throws IOException { DynamoDBSplitter splitter = new AbstractSplitter() { @Override public void generateRangeKeySplits( Configuration conf, List<InputSplit> splits, Types hashKeyType, AttributeValue hashKeyValue, Types rangeKeyType, AttributeValue minRangeKeyValue, AttributeValue maxRangeKeyValue, int numRangeSplits) { fail("This method should not be called!"); } }; final String VALUE = "007"; Types hashKeyType = Types.NUMBER; AttributeValue hashKeyValue = new AttributeValue().withN(VALUE); Types rangeKeyType = Types.NUMBER; List<AttributeValue> rangeKeyValues = new ArrayList<AttributeValue>(); rangeKeyValues.add(new AttributeValue().withN("005")); ComparisonOperator rangeKeyOperator = ComparisonOperator.GT; // configure job Job job = new Job(); Configuration conf = job.getConfiguration(); DynamoDBQueryInputFormat.setHashKeyValue(conf, hashKeyType, hashKeyValue); DynamoDBQueryInputFormat.setRangeKeyCondition(conf, rangeKeyType, rangeKeyOperator, rangeKeyValues); // generate splits List<InputSplit> splits = splitter.split(conf); // verify results assertEquals(1, splits.size()); DynamoDBQueryInputSplit split = (DynamoDBQueryInputSplit) splits.get(0); assertTrue(split.hasHashKey()); assertEquals(hashKeyType, split.getHashKeyType()); assertEquals(hashKeyValue, split.getHashKeyValue()); assertTrue(split.hasRangeKey()); assertEquals(rangeKeyType, split.getRangeKeyType()); assertEquals(rangeKeyOperator, split.getRangeKeyOperator()); assertEquals(1, split.getRangeKeyValues().size()); } @Test public void testSplitWithHashKeyAndInterpolation() throws IOException { final int NUM_MAP_TASKS = 2; final String VALUE = "007"; final Types hashKeyType = Types.NUMBER; final AttributeValue hashKeyValue = new AttributeValue().withN(VALUE); final Types rangeKeyType = Types.NUMBER; final AttributeValue minRangeKeyValue = new AttributeValue().withN(Long.toString(Long.MIN_VALUE)); final AttributeValue maxRangeKeyValue = new AttributeValue().withN(Long.toString(Long.MIN_VALUE)); DynamoDBSplitter splitter = new AbstractSplitter() { @Override public void generateRangeKeySplits( Configuration conf, List<InputSplit> splits, Types inHashKeyType, AttributeValue inHashKeyValue, Types inRangeKeyType, AttributeValue inMinRangeKeyValue, AttributeValue inMaxRangeKeyValue, int numRangeSplits) { // check values assertEquals(hashKeyType, inHashKeyType); assertEquals(hashKeyValue, inHashKeyValue); assertEquals(rangeKeyType, inRangeKeyType); assertEquals(minRangeKeyValue, inMinRangeKeyValue); assertEquals(maxRangeKeyValue, inMaxRangeKeyValue); assertEquals(NUM_MAP_TASKS, numRangeSplits); List<AttributeValue> rangeKeyValues = new ArrayList<AttributeValue>(); rangeKeyValues.add(inMinRangeKeyValue); rangeKeyValues.add(inMaxRangeKeyValue); DynamoDBQueryInputFormat.DynamoDBQueryInputSplit split = new DynamoDBQueryInputFormat.DynamoDBQueryInputSplit( hashKeyType, hashKeyValue, rangeKeyType, rangeKeyValues, ComparisonOperator.BETWEEN); splits.add(split); } }; // configure job Job job = new Job(); Configuration conf = job.getConfiguration(); conf.setInt("mapred.map.tasks", NUM_MAP_TASKS); DynamoDBQueryInputFormat.setHashKeyValue(conf, hashKeyType, hashKeyValue); DynamoDBQueryInputFormat.setRangeKeyType(conf, rangeKeyType); DynamoDBQueryInputFormat.setRangeKeyInterpolateRange(conf, rangeKeyType, minRangeKeyValue, maxRangeKeyValue); // generate input splits List<InputSplit> splits = splitter.split(conf); assertEquals(1, splits.size()); DynamoDBQueryInputSplit split = (DynamoDBQueryInputSplit) splits.get(0); // check results assertTrue(split.hasHashKey()); assertEquals(hashKeyType, split.getHashKeyType()); assertEquals(hashKeyValue, split.getHashKeyValue()); assertTrue(split.hasRangeKey()); assertEquals(rangeKeyType, split.getRangeKeyType()); assertEquals(ComparisonOperator.BETWEEN, split.getRangeKeyOperator()); assertEquals(2, split.getRangeKeyValues().size()); Iterator<AttributeValue> itr = split.getRangeKeyValues().iterator(); assertEquals(minRangeKeyValue, itr.next()); assertEquals(maxRangeKeyValue, itr.next()); } }