private static <T extends Item> void addRangeKeyConditionToQuerySpec(final QuerySpec querySpec, final CompoundAttributeQuery compoundAttributeQuery, final Class<T> itemClass) { final String supportingConditionStringValue = compoundAttributeQuery.getSupportingCondition().getValues().iterator() .next(); final Operators comparisonOperator = compoundAttributeQuery.getSupportingCondition().getComparisonOperator(); final Class<?> supportingAttributeType = compoundAttributeQuery.getSupportingAttributeType(itemClass); try { final Object supportingConditionValue = supportingAttributeType.getConstructor(String.class).newInstance(supportingConditionStringValue); final RangeKeyCondition rangeKeyCondition = RangeKeyConditionBuilder .build(compoundAttributeQuery.getSupportingAttributeName(), supportingConditionValue, comparisonOperator); querySpec.withRangeKeyCondition(rangeKeyCondition); } catch (final Exception e) { throw new PersistenceResourceFailureException( String.format("Could not add range key condition for query: %s on item %s.", compoundAttributeQuery, itemClass.getSimpleName()), e); } }
@Test public void shouldBuild_withAttributeQuery() { // Given final String attributeName = randomString(10); final Condition mockCondition = randomCondition(1); final String expectedValue = mockCondition.getValues().iterator().next(); final AttributeQuery mockAttributeQuery = mock(AttributeQuery.class); when(mockAttributeQuery.getAttributeName()).thenReturn(attributeName); when(mockAttributeQuery.getCondition()).thenReturn(mockCondition); // When final QuerySpec querySpec = QuerySpecBuilder.build(mockAttributeQuery, StubItem.class); // Then assertEquals(attributeName, querySpec.getHashKey().getName()); assertEquals(expectedValue, querySpec.getHashKey().getValue()); assertNull(querySpec.getRangeKeyCondition()); }
@Test public void shouldQueryTable() { // Given final ItemId itemId = new ItemId(randomId()); final ItemConfiguration itemConfiguration = new ItemConfiguration(StubItem.class, tableName); final Collection<ItemConfiguration> itemConfigurations = Arrays.asList(itemConfiguration); when(mockDatabaseSchemaHolder.itemConfigurations()).thenReturn(itemConfigurations); final Table mockTable = mock(Table.class); when(mockDynamoDBClient.getTable(any(String.class))).thenReturn(mockTable); final DynamoDocumentStoreTemplate dynamoDocumentStoreTemplate = new DynamoDocumentStoreTemplate( mockDatabaseSchemaHolder); dynamoDocumentStoreTemplate.initialize(mockAmazonDynamoDbClient); final ItemCollection<QueryOutcome> outcome = mock(ItemCollection.class); when(mockTable.query(any(QuerySpec.class))).thenReturn(outcome); // when dynamoDocumentStoreTemplate.fetch(new AttributeQuery("id", new Condition(Operators.EQUALS, itemId.value())), StubItem.class); // then verify(mockTable.query(any(QuerySpec.class))); }
private static Page<Item, QueryOutcome> queryGSI(String appid, Pager p) { Pager pager = (p != null) ? p : new Pager(); Index index = getSharedIndex(); QuerySpec spec = new QuerySpec(). withMaxPageSize(pager.getLimit()). withMaxResultSize(pager.getLimit()). withKeyConditionExpression(Config._APPID + " = :aid"). withValueMap(new ValueMap().withString(":aid", appid)); if (!StringUtils.isBlank(pager.getLastKey())) { spec = spec.withExclusiveStartKey(new KeyAttribute(Config._APPID, appid), // HASH/PARTITION KEY new KeyAttribute(Config._ID, pager.getLastKey()), // RANGE/SORT KEY new KeyAttribute(Config._KEY, getKeyForAppid(pager.getLastKey(), appid))); // TABLE PRIMARY KEY } return index != null ? index.query(spec).firstPage() : null; }
private static void findRepliesUsingAFilterExpression(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withProjectionExpression("Message, ReplyDateTime, PostedBy") .withKeyConditionExpression("Id = :v_id") .withFilterExpression("PostedBy = :v_postedby") .withValueMap(new ValueMap() .withString(":v_id", replyId) .withString(":v_postedby", "User B")); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesUsingAFilterExpression results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } }
@Override public boolean queryRelationExists(String relationHashKey, String relationRangeKey) { Table table = dynamoDB.getTable(this.groupGraphTableName); QuerySpec querySpec = new QuerySpec() .withKeyConditionExpression("subject = :k_subject and object_relation = :k_object_relation") .withValueMap(new ValueMap() .withString(":k_subject", relationHashKey) .withString(":k_object_relation", relationRangeKey) ) .withMaxResultSize(1) .withConsistentRead(true); DynamoDbCommand<ItemCollection<QueryOutcome>> cmd = new DynamoDbCommand<>("queryRelation", () -> queryTable(table, querySpec), () -> { throw new RuntimeException("queryRelation"); }, dynamodbNamespaceGraphQueryHystrix, metrics); // can't use getLastLowLevelResult directly; it's false unless the outcome is iterated first :| return cmd.execute().iterator().hasNext(); }
@Override public Optional<Group> loadByKey(String key) { Table table = dynamoDB.getTable(this.groupTableName); QuerySpec querySpec = new QuerySpec() .withKeyConditionExpression(HASH_KEY + " = :k_app_key") .withValueMap(new ValueMap() .withString(":k_app_key", key) ) .withMaxResultSize(1) .withConsistentRead(true); DynamoDbCommand<ItemCollection<QueryOutcome>> cmd = new DynamoDbCommand<>("loadByKey", () -> queryTable(table, querySpec), () -> { throw new RuntimeException("loadByKey"); }, dynamodbNamespaceGraphQueryHystrix, metrics); final ItemCollection<QueryOutcome> items = cmd.execute(); final IteratorSupport<Item, QueryOutcome> iterator = items.iterator(); if (iterator.hasNext()) { return Optional.of(GroupSupport.toGroup(iterator.next().getString("json"))); } return Optional.empty(); }
@Override public List<Feature> loadFeatures(String group) { logger.info("{}", kvp("op", "loadFeatures", "group", group)); List<Feature> features = Lists.newArrayList(); Table table = dynamoDB.getTable(featureTableName); QuerySpec querySpec = new QuerySpec() .withKeyConditionExpression(HASH_KEY + " = :k_" + HASH_KEY) .withValueMap(new ValueMap().withString(":k_" + HASH_KEY, group)) .withConsistentRead(true); DynamoDbCommand<ItemCollection<QueryOutcome>> cmd = new DynamoDbCommand<>("loadFeatures", () -> queryTable(table, querySpec), () -> { throw new RuntimeException("loadFeatureById"); }, hystrixReadConfiguration, metrics); ItemCollection<QueryOutcome> items = cmd.execute(); for (Page<Item, QueryOutcome> page : items.pages()) { page.forEach(item -> features.add(FeatureSupport.toFeature(item.getString("json")))); } return features; }
@Override public QueryItemsBuilder<T> queryItems(Object hk, PageIterator pageIterator) { if ( null == _convertMarker ) { throw new IllegalStateException("Index must first be initialized with ConvertMarker"); } QuerySpec spec = withMarker(new QuerySpec().withHashKey(_hkName, hk), pageIterator, hk); return new QueryItemsBuilderImpl<T>(spec, _rkName, pageIterator, this::countItems, this::listItems, _clazz, _encryption); }
private QueryOutcome query(Object hk, QuerySpec querySpec, PageIterator pageIterator) { if ( null == _convertMarker ) { throw new IllegalStateException("Index must first be initialized with ConvertMarker"); } if ( pageIterator.getPageSize() <= 0 ) { return new QueryOutcome(new QueryResult()); } ItemCollection<QueryOutcome> itemCollection = maybeBackoff(true, () -> _query.query(withMarker(querySpec.withHashKey(_hkName, hk), pageIterator, hk))); if ( null != itemCollection ) { Iterator<Page<Item, QueryOutcome>> iterator = itemCollection.pages().iterator(); if ( iterator.hasNext() ) { QueryOutcome outcome = maybeBackoff(true, () -> iterator.next().getLowLevelResult()); QueryResult result = outcome.getQueryResult(); if ( null != pageIterator.getMarker() && null != result.getItems() && result.getItems().size() > 0 ) { pageIterator.setPrevMarker(toMarker(result.getItems().get(0), true)); } else { pageIterator.setPrevMarker(null); } Map<String,AttributeValue> lastKey = result.getLastEvaluatedKey(); if ( null != lastKey && ! lastKey.isEmpty() ) { pageIterator.setMarker(toMarker(lastKey, true)); } else { pageIterator.setMarker(null); } return outcome; } } pageIterator.setPrevMarker(null); pageIterator.setMarker(null); return new QueryOutcome(new QueryResult()); }
private QuerySpec withMarker(QuerySpec spec, PageIterator pageIterator, Object hk) { if ( null != pageIterator.getMarker() ) { spec.withExclusiveStartKey(fromMarker(hk, pageIterator.getMarker())); } int pageSize = pageIterator.getPageSize(); if ( pageSize != Integer.MAX_VALUE ) { spec.withMaxPageSize(pageSize); } return spec.withScanIndexForward(pageIterator.isForward()); }
public QueryItemsBuilderImpl(QuerySpec spec, String rangeKeyName, PageIterator iter, CountItems countItems, ListItems listItems, Class<T> clazz, DDBEncryption encryption) { _spec = spec; _rkName = rangeKeyName; _iter = iter; _countItems = countItems; _listItems = listItems; _clazz = clazz; _encryption = encryption; }
@Override public List<String> retrieveRecordsForProvince(String dataSetLabel, String infoSetTag, Province province, Locale locale) { if (!useDynamoDirect) { URI uriToCall = baseBuilder() .path("/records/{dataset}/{infoSet}") .queryParam("province", province.toString()) .queryParam("locale", locale.toLanguageTag()) .buildAndExpand(dataSetLabel, infoSetTag).toUri(); log.info("assembled URI to get records = {}", uriToCall.toString()); return getFromUri(uriToCall); } else { DynamoDB dynamoDB = new DynamoDB(dynamoDBClient); Table geoApiTable = dynamoDB.getTable("geo_" + dataSetLabel.toLowerCase()); log.info("querying from table, name: {}, number of rows: {}", "geo_" + dataSetLabel.toLowerCase(), geoApiTable.describe().toString()); log.info("looking for province, with name: {}, on infoSet: {}", province.name(), infoSetTag); Index provinceIndex = geoApiTable.getIndex("lowestGeoInfo"); // figure out how to adapt when province != lowest QuerySpec querySpec = new QuerySpec() .withKeyConditionExpression("province = :prv and infoTag = :info") .withValueMap(new ValueMap() .withString(":prv", province.name()) .withString(":info", infoSetTag)); try { ItemCollection<QueryOutcome> records = provinceIndex.query(querySpec); List<String> result = new ArrayList<>(); records.iterator().forEachRemaining(i -> result.add(i.getString("description"))); log.info("iterated through the results, number of results: {}", result.size()); return result; } catch (Exception e) { log.error("Error!", e); throw new IllegalArgumentException("No results for that dataset, province and field"); } } }
public static <T extends Item> QuerySpec build(final AttributeQuery attributeQuery, final Class<T> itemClass) { if (CompoundAttributeQuery.class.isAssignableFrom(attributeQuery.getClass())) { final CompoundAttributeQuery compoundAttributeQuery = (CompoundAttributeQuery) attributeQuery; return buildWithHashAndRangeKey(compoundAttributeQuery, itemClass); } return buildWithHashKey(attributeQuery); }
private static <T extends Item> QuerySpec buildWithHashAndRangeKey( final CompoundAttributeQuery compoundAttributeQuery, final Class<T> itemClass) { final Set<String> supportingConditionValues = compoundAttributeQuery.getSupportingCondition().getValues(); validateSupportingConditionValues(supportingConditionValues); final QuerySpec querySpec = buildWithHashKey(compoundAttributeQuery); addRangeKeyConditionToQuerySpec(querySpec, compoundAttributeQuery, itemClass); return querySpec; }
@Test public void shouldBuild_withCompoundAttributeQuery() { // Given final String attributeName = randomString(10); final String supportingAttributeName = randomString(10); final Condition condition = randomCondition(1); final Condition supportingCondition = randomCondition(1); final CompoundAttributeQuery compoundAttributeQuery = mock(CompoundAttributeQuery.class); final RangeKeyCondition mockRangeKeyCondition = mock(RangeKeyCondition.class); final String expectedValue = condition.getValues().iterator().next(); final String expectedSupportingValue = supportingCondition.getValues().iterator().next(); final Operators expectedSupportingComparisonOperator = supportingCondition.getComparisonOperator(); when(compoundAttributeQuery.getAttributeName()).thenReturn(attributeName); when(compoundAttributeQuery.getCondition()).thenReturn(condition); when(compoundAttributeQuery.getSupportingCondition()).thenReturn(supportingCondition); Mockito.<Class<?>> when(compoundAttributeQuery.getSupportingAttributeType(any())).thenReturn(String.class); when(compoundAttributeQuery.getSupportingAttributeName()).thenReturn(supportingAttributeName); when(RangeKeyConditionBuilder.build(supportingAttributeName, expectedSupportingValue, expectedSupportingComparisonOperator)).thenReturn(mockRangeKeyCondition); // When final QuerySpec querySpec = QuerySpecBuilder.build(compoundAttributeQuery, StubWithGlobalSecondaryIndexItem.class); // Then assertEquals(attributeName, querySpec.getHashKey().getName()); assertEquals(expectedValue, querySpec.getHashKey().getValue()); assertEquals(mockRangeKeyCondition, querySpec.getRangeKeyCondition()); }
@Test public void shouldQueryIndex_withAttributeQuery() { // Given final ItemId itemId = new ItemId(randomId()); final ItemConfiguration itemConfiguration = new ItemConfiguration(StubItem.class, tableName); itemConfiguration.registerIndexes(Arrays.asList(new IndexDefinition("stringProperty"))); final Collection<ItemConfiguration> itemConfigurations = Arrays.asList(itemConfiguration); when(mockDatabaseSchemaHolder.itemConfigurations()).thenReturn(itemConfigurations); final Table mockTable = mock(Table.class); when(mockDynamoDBClient.getTable(any(String.class))).thenReturn(mockTable); final DynamoDocumentStoreTemplate dynamoDocumentStoreTemplate = new DynamoDocumentStoreTemplate( mockDatabaseSchemaHolder); dynamoDocumentStoreTemplate.initialize(mockAmazonDynamoDbClient); final Index mockIndex = mock(Index.class); when(mockTable.getIndex(anyString())).thenReturn(mockIndex); final ItemCollection<QueryOutcome> outcome = mock(ItemCollection.class); when(mockIndex.query(any(QuerySpec.class))).thenReturn(outcome); // when dynamoDocumentStoreTemplate.fetch( new AttributeQuery("stringProperty", new Condition(Operators.EQUALS, itemId.value())), StubItem.class); // then verify(mockIndex.query(any(QuerySpec.class))); }
private static void findRepliesInLast15DaysWithConfig( String tableName, String forumName, String threadSubject) { String replyId = forumName + "#" + threadSubject; long twoWeeksAgoMilli = (new Date()).getTime() - (15L * 24L * 60L * 60L * 1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String twoWeeksAgoStr = df.format(twoWeeksAgo); Table table = dynamoDB.getTable(tableName); QuerySpec querySpec = new QuerySpec() .withKeyConditionExpression("Id = :v1 and ReplyDateTime > :v2") .withValueMap(new ValueMap() .withString(":v1", replyId) .withString(":v2", twoWeeksAgoStr)) .withProjectionExpression("Message, ReplyDateTime, PostedBy"); ItemCollection<QueryOutcome> items = table.query(querySpec); Iterator<Item> iterator = items.iterator(); System.out.println("Query: printing results..."); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } }
private static void findRepliesForAThreadSpecifyOptionalLimit(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withKeyConditionExpression("Id = :v_id") .withValueMap(new ValueMap() .withString(":v_id", replyId)) .withMaxPageSize(1); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesForAThreadSpecifyOptionalLimit results:"); // Process each page of results int pageNum = 0; for (Page<Item, QueryOutcome> page : items.pages()) { System.out.println("\nPage: " + ++pageNum); // Process each item on the current page Iterator<Item> item = page.iterator(); while (item.hasNext()) { System.out.println(item.next().toJSONPretty()); } } }
private static void findRepliesInLast15DaysWithConfig(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); long twoWeeksAgoMilli = (new Date()).getTime() - (15L*24L*60L*60L*1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String twoWeeksAgoStr = df.format(twoWeeksAgo); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withProjectionExpression("Message, ReplyDateTime, PostedBy") .withKeyConditionExpression("Id = :v_id and ReplyDateTime <= :v_reply_dt_tm") .withValueMap(new ValueMap() .withString(":v_id", replyId) .withString(":v_reply_dt_tm", twoWeeksAgoStr)); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesInLast15DaysWithConfig results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } }
private static void findRepliesPostedWithinTimePeriod(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); long startDateMilli = (new Date()).getTime() - (15L*24L*60L*60L*1000L); long endDateMilli = (new Date()).getTime() - (5L*24L*60L*60L*1000L); java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String startDate = df.format(startDateMilli); String endDate = df.format(endDateMilli); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withProjectionExpression("Message, ReplyDateTime, PostedBy") .withKeyConditionExpression("Id = :v_id and ReplyDateTime between :v_start_dt and :v_end_dt") .withValueMap(new ValueMap() .withString(":v_id", replyId) .withString(":v_start_dt", startDate) .withString(":v_end_dt", endDate)); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesPostedWithinTimePeriod results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } }
private ItemCollection<QueryOutcome> queryTable(Table table, QuerySpec querySpec) { return table.query(querySpec); }
private int countItems(QuerySpec spec, PageIterator iter) { return toCount(query(spec.getHashKey().getValue(), spec, iter)); }
private <V> List<V> listItems(QuerySpec spec, Class<V> type, PageIterator iter) { return toList(query(spec.getHashKey().getValue(), spec, iter), type); }
private static QuerySpec buildWithHashKey(final AttributeQuery attributeQuery) { return new QuerySpec().withHashKey(attributeQuery.getAttributeName(), attributeQuery.getCondition().getValues().iterator().next()); }
@Test public void shouldQueryIndex_withAttributeQueryOnHashPartOfCompoundIndex() { // Given final ItemId itemId = new ItemId(randomId()); final ItemConfiguration itemConfiguration = new ItemConfiguration(StubWithGlobalSecondaryIndexItem.class, tableName); itemConfiguration.registerIndexes((Arrays.asList(new CompoundIndexDefinition("gsi", "gsiSupportingValue")))); final Collection<ItemConfiguration> itemConfigurations = Arrays.asList(itemConfiguration); when(mockDatabaseSchemaHolder.itemConfigurations()).thenReturn(itemConfigurations); final Table mockTable = mock(Table.class); when(mockDynamoDBClient.getTable(any(String.class))).thenReturn(mockTable); final DynamoDocumentStoreTemplate dynamoDocumentStoreTemplate = new DynamoDocumentStoreTemplate( mockDatabaseSchemaHolder); dynamoDocumentStoreTemplate.initialize(mockAmazonDynamoDbClient); final Index mockIndex = mock(Index.class); when(mockTable.getIndex(anyString())).thenReturn(mockIndex); final ItemCollection<QueryOutcome> mockOutcome = mock(ItemCollection.class); when(mockIndex.query(any(QuerySpec.class))).thenReturn(mockOutcome); final IteratorSupport<Item, QueryOutcome> mockIterator = mock(IteratorSupport.class); final Item mockItem = new Item(); mockItem.withString(randomString(), randomString()); when(mockOutcome.iterator()).thenReturn(mockIterator); when(mockIterator.hasNext()).thenReturn(true, false); when(mockIterator.next()).thenReturn(mockItem); // When final Collection<StubWithGlobalSecondaryIndexItem> stubWithGlobalSecondaryIndexItemCollection = dynamoDocumentStoreTemplate .fetch(new AttributeQuery("gsi", new Condition(Operators.EQUALS, itemId.value())), StubWithGlobalSecondaryIndexItem.class); // Then assertTrue(stubWithGlobalSecondaryIndexItemCollection.size() == 1); final ArgumentCaptor<QuerySpec> querySpecCaptor = ArgumentCaptor.forClass(QuerySpec.class); verify(mockIndex).query(querySpecCaptor.capture()); }
@Test public void shouldQueryIndex_withCompoundAttributeQuery() { // Given final ItemId itemId = new ItemId(randomId()); final ItemConfiguration itemConfiguration = new ItemConfiguration(StubWithGlobalSecondaryIndexItem.class, tableName); itemConfiguration.registerIndexes((Arrays.asList(new CompoundIndexDefinition("gsi", "gsiSupportingValue")))); final Collection<ItemConfiguration> itemConfigurations = Arrays.asList(itemConfiguration); when(mockDatabaseSchemaHolder.itemConfigurations()).thenReturn(itemConfigurations); final Table mockTable = mock(Table.class); when(mockDynamoDBClient.getTable(any(String.class))).thenReturn(mockTable); final DynamoDocumentStoreTemplate dynamoDocumentStoreTemplate = new DynamoDocumentStoreTemplate( mockDatabaseSchemaHolder); dynamoDocumentStoreTemplate.initialize(mockAmazonDynamoDbClient); final Index mockIndex = mock(Index.class); when(mockTable.getIndex(anyString())).thenReturn(mockIndex); final ItemCollection<QueryOutcome> mockOutcome = mock(ItemCollection.class); when(mockIndex.query(any(QuerySpec.class))).thenReturn(mockOutcome); final IteratorSupport<Item, QueryOutcome> mockIterator = mock(IteratorSupport.class); final Item mockItem = new Item(); mockItem.withString(randomString(), randomString()); when(mockOutcome.iterator()).thenReturn(mockIterator); when(mockIterator.hasNext()).thenReturn(true, false); when(mockIterator.next()).thenReturn(mockItem); // When final Collection<StubWithGlobalSecondaryIndexItem> stubWithGlobalSecondaryIndexItemCollection = dynamoDocumentStoreTemplate .fetch(new CompoundAttributeQuery("gsi", new Condition(Operators.EQUALS, itemId.value()), "gsiSupportingValue", new Condition(Operators.EQUALS, String.valueOf(randomInt(10)))), StubWithGlobalSecondaryIndexItem.class); // Then assertTrue(stubWithGlobalSecondaryIndexItemCollection.size() == 1); final ArgumentCaptor<QuerySpec> querySpecCaptor = ArgumentCaptor.forClass(QuerySpec.class); verify(mockIndex).query(querySpecCaptor.capture()); assertNotNull(querySpecCaptor.getValue().getRangeKeyCondition()); }
@Test public void shouldQueryIndex_withACompoundAttributeQueryOnACompoundGSIWithAHashValueTheSameAsThePrimaryKeyDefinition() { // Given final ItemId itemId = new ItemId(randomId()); final ItemConfiguration itemConfiguration = new ItemConfiguration(StubWithGlobalSecondaryIndexItem.class, tableName, new PrimaryKeyDefinition("gsi")); itemConfiguration.registerIndexes((Arrays.asList(new CompoundIndexDefinition("gsi", "gsiSupportingValue")))); final Collection<ItemConfiguration> itemConfigurations = Arrays.asList(itemConfiguration); when(mockDatabaseSchemaHolder.itemConfigurations()).thenReturn(itemConfigurations); final Table mockTable = mock(Table.class); when(mockDynamoDBClient.getTable(any(String.class))).thenReturn(mockTable); final DynamoDocumentStoreTemplate dynamoDocumentStoreTemplate = new DynamoDocumentStoreTemplate( mockDatabaseSchemaHolder); dynamoDocumentStoreTemplate.initialize(mockAmazonDynamoDbClient); final Index mockIndex = mock(Index.class); when(mockTable.getIndex(anyString())).thenReturn(mockIndex); final ItemCollection<QueryOutcome> mockOutcome = mock(ItemCollection.class); when(mockIndex.query(any(QuerySpec.class))).thenReturn(mockOutcome); final IteratorSupport<Item, QueryOutcome> mockIterator = mock(IteratorSupport.class); final Item mockItem = new Item(); mockItem.withString(randomString(), randomString()); when(mockOutcome.iterator()).thenReturn(mockIterator); when(mockIterator.hasNext()).thenReturn(true, false); when(mockIterator.next()).thenReturn(mockItem); // When final Collection<StubWithGlobalSecondaryIndexItem> stubWithGlobalSecondaryIndexItemCollection = dynamoDocumentStoreTemplate .fetch(new CompoundAttributeQuery("gsi", new Condition(Operators.EQUALS, itemId.value()), "gsiSupportingValue", new Condition(Operators.EQUALS, String.valueOf(randomInt(10)))), StubWithGlobalSecondaryIndexItem.class); // Then assertTrue(stubWithGlobalSecondaryIndexItemCollection.size() == 1); final ArgumentCaptor<QuerySpec> querySpecCaptor = ArgumentCaptor.forClass(QuerySpec.class); verify(mockIndex).query(querySpecCaptor.capture()); assertNotNull(querySpecCaptor.getValue().getRangeKeyCondition()); }
public static void main(String[] args) { AmazonDynamoDBClient client = new AmazonDynamoDBClient(); client.setEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); HashMap<String, String> nameMap = new HashMap<String, String>(); nameMap.put("#yr", "year"); HashMap<String, Object> valueMap = new HashMap<String, Object>(); valueMap.put(":yyyy", 1985); QuerySpec querySpec = new QuerySpec() .withKeyConditionExpression("#yr = :yyyy") .withNameMap(new NameMap().with("#yr", "year")) .withValueMap(valueMap); ItemCollection<QueryOutcome> items = table.query(querySpec); Iterator<Item> iterator = items.iterator(); Item item = null; System.out.println("Movies from 1985"); while (iterator.hasNext()) { item = iterator.next(); System.out.println(item.getNumber("year") + ": " + item.getString("title")); } valueMap.put(":yyyy", 1992); valueMap.put(":letter1", "A"); valueMap.put(":letter2", "L"); querySpec .withProjectionExpression("#yr, title, info.genres, info.actors[0]") .withKeyConditionExpression("#yr = :yyyy and title between :letter1 and :letter2") .withNameMap(nameMap) .withValueMap(valueMap); items = table.query(querySpec); iterator = items.iterator(); System.out.println("Movies from 1992 - titles A-L, with genres and lead actor"); while (iterator.hasNext()) { item = iterator.next(); System.out.println(item.toString()); } }
private static void findRepliesForAThread(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withKeyConditionExpression("Id = :v_id") .withValueMap(new ValueMap() .withString(":v_id", replyId)); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesForAThread results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } }
public static void queryIndex(String indexName) { Table table = dynamoDB.getTable(tableName); System.out.println ("\n***********************************************************\n"); System.out.print("Querying index " + indexName + "..."); Index index = table.getIndex(indexName); ItemCollection<QueryOutcome> items = null; QuerySpec querySpec = new QuerySpec(); if (indexName == "CreateDateIndex") { System.out.println("Issues filed on 2013-11-01"); querySpec.withKeyConditionExpression("CreateDate = :v_date and begins_with(IssueId, :v_issue)") .withValueMap(new ValueMap() .withString(":v_date","2013-11-01") .withString(":v_issue","A-")); items = index.query(querySpec); } else if (indexName == "TitleIndex") { System.out.println("Compilation errors"); querySpec.withKeyConditionExpression("Title = :v_title and begins_with(IssueId, :v_issue)") .withValueMap(new ValueMap() .withString(":v_title","Compilation error") .withString(":v_issue","A-")); items = index.query(querySpec); } else if (indexName == "DueDateIndex") { System.out.println("Items that are due on 2013-11-30"); querySpec.withKeyConditionExpression("DueDate = :v_date") .withValueMap(new ValueMap() .withString(":v_date","2013-11-30")); items = index.query(querySpec); } else { System.out.println("\nNo valid index name provided"); return; } Iterator<Item> iterator = items.iterator(); System.out.println("Query: printing results..."); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } }
public int countItems(QuerySpec spec, PageIterator iter);
public <V> List<V> listItems(QuerySpec spec, Class<V> type, PageIterator iter);