} else { DynamoDBQueryExpression<EnvironmentDDBRecord> query = new DynamoDBQueryExpression<EnvironmentDDBRecord>() .withIndexName(EnvironmentDDBRecord.ENVIRONMENT_CLUSTER_GSI_NAME) .withHashKeyValues(EnvironmentDDBRecord.builder().accountId(accountId).build()) .withConsistentRead(false); query.withRangeKeyCondition( EnvironmentDDBRecord.ENVIRONMENT_CLUSTER_INDEX_RANGE_KEY, new Condition()
/** * Sets the name of the index to be used by this query. The hash key * and/or range key of the index must be specified by adding * {@link DynamoDBIndexHashKey} or {@code DynamoDBIndexRangeKey} * annotations to the appropriate getter methods of the mapped * object. * <p> * Returns a pointer to this object for method-chaining. */ public DynamoDBQueryExpression<T> withIndexName(String indexName) { setIndexName(indexName); return this; }
protected <T> QueryRequest createQueryRequestFromExpression(Class<T> clazz, DynamoDBQueryExpression<T> xpress, DynamoDBMapperConfig config) { final DynamoDBMapperTableModel<T> model = getTableModel(clazz, config); QueryRequest req = new QueryRequest(); req.setConsistentRead(xpress.isConsistentRead()); req.setTableName(getTableName(clazz, xpress.getHashKeyValues(), config)); req.setIndexName(xpress.getIndexName()); req.setKeyConditionExpression(xpress.getKeyConditionExpression()); processKeyConditions(req, xpress, model); req.withScanIndexForward(xpress.isScanIndexForward()) .withLimit(xpress.getLimit()) .withExclusiveStartKey(xpress.getExclusiveStartKey()) .withQueryFilter(xpress.getQueryFilter()) .withConditionalOperator(xpress.getConditionalOperator()) .withSelect(xpress.getSelect()) .withProjectionExpression(xpress.getProjectionExpression()) .withFilterExpression(xpress.getFilterExpression()) .withExpressionAttributeNames(xpress.getExpressionAttributeNames()) .withExpressionAttributeValues(xpress.getExpressionAttributeValues()) .withReturnConsumedCapacity(xpress.getReturnConsumedCapacity()) .withRequestMetricCollector(config.getRequestMetricCollector()) ; return applyUserAgent(req); }
@Override public List<EnvironmentRevision> listEnvironmentRevisions( @NonNull final EnvironmentId environmentId) throws InternalServiceException { try { return dynamoDBMapper .query( EnvironmentRevisionDDBRecord.class, new DynamoDBQueryExpression<EnvironmentRevisionDDBRecord>() .withHashKeyValues( EnvironmentRevisionDDBRecord.withHashKey( environmentId.generateAccountIdClusterEnvironmentName()))) .stream() .map(environmentMapper::toEnvironmentRevision) .collect(Collectors.toList()); } catch (final AmazonServiceException e) { throw new InternalServiceException( String.format( "Could not query environment revisions for environment %s", environmentId.toString()), e); } }
@Override public List<Environment> listEnvironments( @NonNull final Cluster cluster, final String environmentNamePrefix) throws InternalServiceException { try { final DynamoDBQueryExpression<EnvironmentDDBRecord> queryExpression = new DynamoDBQueryExpression<EnvironmentDDBRecord>() .withHashKeyValues( EnvironmentDDBRecord.withHashKeys(cluster.generateAccountIdCluster())); if (environmentNamePrefix != null) { queryExpression.withRangeKeyCondition( ENVIRONMENT_NAME_RANGE_KEY, new Condition() .withComparisonOperator(ComparisonOperator.BEGINS_WITH) .withAttributeValueList(new AttributeValue().withS(environmentNamePrefix))); } return dynamoDBMapper .query(EnvironmentDDBRecord.class, queryExpression) .stream() .map(environmentMapper::toEnvironment) .collect(Collectors.toList()); } catch (final AmazonServiceException e) { throw new InternalServiceException( String.format("Could not query environments for cluster %s", cluster.toString()), e); } }
public DynamoDBQueryExpression<T> buildQueryExpression() { DynamoDBQueryExpression<T> queryExpression = new DynamoDBQueryExpression<T>(); if (isHashKeySpecified()) { T hashKeyPrototype = entityInformation.getHashKeyPropotypeEntityForHashKey(getHashKeyPropertyValue()); queryExpression.withHashKeyValues(hashKeyPrototype); queryExpression.withRangeKeyConditions(new HashMap<String, Condition>()); Condition rangeKeyCondition = createSingleValueCondition(getRangeKeyPropertyName(), ComparisonOperator.EQ, getRangeKeyAttributeValue(), getRangeKeyAttributeValue().getClass(), true); queryExpression.withRangeKeyCondition(getRangeKeyAttributeName(), rangeKeyCondition); applySortIfSpecified(queryExpression, Arrays.asList(new String[]{getRangeKeyPropertyName()})); queryExpression.withRangeKeyCondition(singleAttributeConditions.getKey(), condition); queryExpression.setIndexName(getGlobalSecondaryIndexName()); queryExpression.setSelect(Select.SPECIFIC_ATTRIBUTES); queryExpression.setProjectionExpression(projection.get());
@Override public List<Event> findEventsByCity(String city) { Map<String, AttributeValue> eav = new HashMap<>(); eav.put(":v1", new AttributeValue().withS(city)); DynamoDBQueryExpression<Event> query = new DynamoDBQueryExpression<Event>() .withIndexName(Event.CITY_INDEX) .withConsistentRead(false) .withKeyConditionExpression("city = :v1") .withExpressionAttributeValues(eav); return mapper.query(Event.class, query); // NOTE: without an index, this query would require a full table scan with a filter: /* DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withFilterExpression("city = :val1") .withExpressionAttributeValues(eav); return mapper.scan(Event.class, scanExpression); */ }
public DynamoDBQueryExpression<T> buildQueryExpression() { DynamoDBQueryExpression<T> queryExpression = new DynamoDBQueryExpression<T>(); if (isHashKeySpecified()) { T hashKeyPrototype = entityInformation.getHashKeyPropotypeEntityForHashKey(getHashKeyPropertyValue()); queryExpression.withHashKeyValues(hashKeyPrototype); queryExpression.withRangeKeyConditions(new HashMap<String, Condition>()); Condition rangeKeyCondition = createSingleValueCondition(getRangeKeyPropertyName(), ComparisonOperator.EQ, getRangeKeyAttributeValue(), getRangeKeyAttributeValue().getClass(), true); queryExpression.withRangeKeyCondition(getRangeKeyAttributeName(), rangeKeyCondition); applySortIfSpecified(queryExpression, Arrays.asList(new String[] { getRangeKeyPropertyName() })); queryExpression.withRangeKeyCondition(singleAttributeConditions.getKey(), condition); queryExpression.setIndexName(getGlobalSecondaryIndexName());
if (expression.getHashKeyValues() != null) { for (final DynamoDBMapperFieldModel<T,Object> field : model.fields()) { if (field.keyType() == HASH || !field.globalSecondaryIndexNames(HASH).isEmpty()) { final Object value = field.get(expression.getHashKeyValues()); if (value != null) { hashKeyConditions.put(field.name(), field.eq(value)); final Map<String, Condition> rangeKeyConditions = expression.getRangeKeyConditions();
/** * Sets the hash key value(s) for this query. All hash key attributes for * the table must be specified with this key object. */ public DynamoDBQueryExpression<T> withHashKeyValues(T hashKObject) { setHashKeyValues(hashKObject); return this; }
protected void applySortIfSpecified(DynamoDBQueryExpression<T> queryExpression, List<String> permittedPropertyNames) { if (permittedPropertyNames.size() > 1) { throw new UnsupportedOperationException("Can only sort by at most a single range or index range key"); } boolean sortAlreadySet = false; for (Order order : sort) { if (permittedPropertyNames.contains(order.getProperty())) { if (sortAlreadySet) { throw new UnsupportedOperationException("Sorting by multiple attributes not possible"); } queryExpression.setScanIndexForward(order.getDirection().equals(Direction.ASC)); sortAlreadySet = true; } else { throw new UnsupportedOperationException( "Sorting only possible by " + permittedPropertyNames + " for the criteria specified"); } } }
private static void FindRepliesInLast15Days(DynamoDBMapper mapper, String forumName, String threadSubject) throws Exception { System.out.println("FindRepliesInLast15Days: Replies within last 15 days."); String hashKey = forumName + "#" + threadSubject; long twoWeeksAgoMilli = (new Date()).getTime() - (15L*24L*60L*60L*1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); String twoWeeksAgoStr = dateFormatter.format(twoWeeksAgo); Condition rangeKeyCondition = new Condition() .withComparisonOperator(ComparisonOperator.GT.toString()) .withAttributeValueList(new AttributeValue().withS(twoWeeksAgoStr.toString())); Reply replyKey = new Reply(); replyKey.setId(hashKey); DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>() .withHashKeyValues(replyKey) .withRangeKeyCondition("ReplyDateTime", rangeKeyCondition); List<Reply> latestReplies = mapper.query(Reply.class, queryExpression); for (Reply reply : latestReplies) { System.out.format("Id=%s, Message=%s, PostedBy=%s %n, ReplyDateTime=%s %n", reply.getId(), reply.getMessage(), reply.getPostedBy(), reply.getReplyDateTime() ); } }
@Override public List<Event> findEventsByTeam(String team) { DynamoDBQueryExpression<Event> homeQuery = new DynamoDBQueryExpression<>(); Event eventKey = new Event(); eventKey.setHomeTeam(team); homeQuery.setHashKeyValues(eventKey); List<Event> homeEvents = mapper.query(Event.class, homeQuery); Map<String, AttributeValue> eav = new HashMap<>(); eav.put(":v1", new AttributeValue().withS(team)); DynamoDBQueryExpression<Event> awayQuery = new DynamoDBQueryExpression<Event>() .withIndexName(Event.AWAY_TEAM_INDEX) .withConsistentRead(false) .withKeyConditionExpression("awayTeam = :v1") .withExpressionAttributeValues(eav); List<Event> awayEvents = mapper.query(Event.class, awayQuery); // need to create a new list because PaginatedList from query is immutable List<Event> allEvents = new LinkedList<>(); allEvents.addAll(homeEvents); allEvents.addAll(awayEvents); allEvents.sort( (e1, e2) -> e1.getEventDate() <= e2.getEventDate() ? -1 : 1 ); return allEvents; }
@Test public void testListEnvironmentsWithoutEnvironmentNamePrefix() throws Exception { when(environmentDDBRecords.stream()).thenReturn(Stream.of(environmentDDBRecord)); doReturn(environmentDDBRecords) .when(dynamoDBMapper) .query(eq(EnvironmentDDBRecord.class), any()); when(environmentMapper.toEnvironment(environmentDDBRecord)).thenReturn(environment); final List<Environment> result = environmentRepositoryDDB.listEnvironments(cluster, null); verify(dynamoDBMapper) .query(eq(EnvironmentDDBRecord.class), ddbQueryExpressionCaptor.capture()); verify(environmentMapper).toEnvironment(environmentDDBRecord); final EnvironmentDDBRecord queriedEnvironmentDDBRecord = ddbQueryExpressionCaptor.getValue().getHashKeyValues(); assertThat(ddbQueryExpressionCaptor.getValue().getRangeKeyConditions()).isNull(); assertThat(queriedEnvironmentDDBRecord.getAccountIdCluster()) .isEqualTo(cluster.generateAccountIdCluster()); assertThat(result.size()).isEqualTo(1); assertThat(result.get(0)).isEqualTo(environment); }
/** * Sets the hash key value(s) for this query. All hash key attributes for * the table must be specified with this key object. */ public DynamoDBQueryExpression<T> withHashKeyValues(T hashKObject) { setHashKeyValues(hashKObject); return this; }
protected void applySortIfSpecified(DynamoDBQueryExpression<T> queryExpression, List<String> permittedPropertyNames) { if (permittedPropertyNames.size() > 1) { throw new UnsupportedOperationException("Can only sort by at most a single range or index range key"); } if (sort != null) { boolean sortAlreadySet = false; for (Order order : sort) { if (permittedPropertyNames.contains(order.getProperty())) { if (sortAlreadySet) { throw new UnsupportedOperationException("Sorting by multiple attributes not possible"); } queryExpression.setScanIndexForward(order.getDirection().equals(Direction.ASC)); sortAlreadySet = true; } else { throw new UnsupportedOperationException("Sorting only possible by " + permittedPropertyNames + " for the criteria specified"); } } } }
protected <T> QueryRequest createQueryRequestFromExpression(Class<T> clazz, DynamoDBQueryExpression<T> xpress, DynamoDBMapperConfig config) { final DynamoDBMapperTableModel<T> model = getTableModel(clazz, config); QueryRequest req = new QueryRequest(); req.setConsistentRead(xpress.isConsistentRead()); req.setTableName(getTableName(clazz, xpress.getHashKeyValues(), config)); req.setIndexName(xpress.getIndexName()); req.setKeyConditionExpression(xpress.getKeyConditionExpression()); processKeyConditions(req, xpress, model); req.withScanIndexForward(xpress.isScanIndexForward()) .withLimit(xpress.getLimit()) .withExclusiveStartKey(xpress.getExclusiveStartKey()) .withQueryFilter(xpress.getQueryFilter()) .withConditionalOperator(xpress.getConditionalOperator()) .withSelect(xpress.getSelect()) .withProjectionExpression(xpress.getProjectionExpression()) .withFilterExpression(xpress.getFilterExpression()) .withExpressionAttributeNames(xpress.getExpressionAttributeNames()) .withExpressionAttributeValues(xpress.getExpressionAttributeValues()) .withReturnConsumedCapacity(xpress.getReturnConsumedCapacity()) .withRequestMetricCollector(config.getRequestMetricCollector()) ; return applyUserAgent(req); }
replyKey.setId(hashKey); DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>() .withHashKeyValues(replyKey) .withRangeKeyCondition("ReplyDateTime", rangeKeyCondition);
@Test public void testListEnvironmentsWithEnvironmentNamePrefix() throws Exception { final String environmentNamePrefix = "environmentNamePrefix"; when(environmentDDBRecords.stream()).thenReturn(Stream.of(environmentDDBRecord)); doReturn(environmentDDBRecords) .when(dynamoDBMapper) .query(eq(EnvironmentDDBRecord.class), any()); when(environmentMapper.toEnvironment(environmentDDBRecord)).thenReturn(environment); final List<Environment> result = environmentRepositoryDDB.listEnvironments(cluster, environmentNamePrefix); verify(dynamoDBMapper) .query(eq(EnvironmentDDBRecord.class), ddbQueryExpressionCaptor.capture()); verify(environmentMapper).toEnvironment(environmentDDBRecord); final EnvironmentDDBRecord queriedEnvironmentDDBRecord = ddbQueryExpressionCaptor.getValue().getHashKeyValues(); final Map<String, Condition> queryConditions = ddbQueryExpressionCaptor.getValue().getRangeKeyConditions(); assertThat(queriedEnvironmentDDBRecord.getAccountIdCluster()) .isEqualTo(cluster.generateAccountIdCluster()); assertThat(queryConditions).isNotEmpty().hasSize(1); assertThat(queryConditions).containsKey(ENVIRONMENT_NAME_RANGE_KEY); assertThat(queryConditions) .containsValue( new Condition() .withComparisonOperator(ComparisonOperator.BEGINS_WITH) .withAttributeValueList(new AttributeValue().withS(environmentNamePrefix))); assertThat(result.size()).isEqualTo(1); assertThat(result.get(0)).isEqualTo(environment); }
/** * Sets the name of the index to be used by this query. The hash key * and/or range key of the index must be specified by adding * {@link DynamoDBIndexHashKey} or {@code DynamoDBIndexRangeKey} * annotations to the appropriate getter methods of the mapped * object. * <p> * Returns a pointer to this object for method-chaining. */ public DynamoDBQueryExpression<T> withIndexName(String indexName) { setIndexName(indexName); return this; }