001package com.nimbusds.infinispan.persistence.dynamodb.query;
002
003
004import java.util.function.Consumer;
005
006import com.amazonaws.services.dynamodbv2.document.Index;
007import com.amazonaws.services.dynamodbv2.document.ItemCollection;
008import com.amazonaws.services.dynamodbv2.document.QueryOutcome;
009import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;
010import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
011import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
012import com.nimbusds.infinispan.persistence.common.InfinispanEntry;
013import com.nimbusds.infinispan.persistence.common.query.Query;
014import com.nimbusds.infinispan.persistence.common.query.SimpleMatchQuery;
015import com.nimbusds.infinispan.persistence.common.query.UnsupportedQueryException;
016import net.jcip.annotations.ThreadSafe;
017
018
019/**
020 * Simple match DynamoDB query executor. Accepts queries of type
021 * {@link SimpleMatchQuery} where both key name and value must be of type
022 * {@link String}.
023 */
024@ThreadSafe
025public class SimpleMatchQueryExecutor<K, V> implements DynamoDBQueryExecutor<K, V> {
026        
027        
028        /**
029         * The initialisation context.
030         */
031        private DynamoDBQueryExecutorInitContext<K, V> initCtx;
032        
033        
034        @Override
035        public void init(final DynamoDBQueryExecutorInitContext<K, V> initCtx) {
036                this.initCtx = initCtx;
037        }
038        
039        
040        /**
041         * Returns the DynamoDB query spec for the specified simple match
042         * query.
043         *
044         * @param simpleMatchQuery The simple match query. Must not be
045         *                         {@code null}.
046         *
047         * @return The DynamoDB query spec.
048         */
049        private static QuerySpec toQuerySpec(final SimpleMatchQuery<String, String> simpleMatchQuery) {
050                
051                return new QuerySpec()
052                        .withKeyConditionExpression("#k = :value")
053                        .withNameMap(new NameMap()
054                                .with("#k", simpleMatchQuery.getKey()))
055                        .withValueMap(new ValueMap()
056                                .withString(":value", simpleMatchQuery.getValue()));
057        }
058        
059        
060        @Override
061        @SuppressWarnings("unchecked")
062        public void executeQuery(final Query query, final Consumer<InfinispanEntry<K, V>> consumer) {
063                
064                if (! (query instanceof SimpleMatchQuery)) {
065                        throw new UnsupportedQueryException(query);
066                }
067                
068                SimpleMatchQuery<String, String> simpleMatchQuery = (SimpleMatchQuery<String, String>)query;
069                
070                QuerySpec querySpec = toQuerySpec(simpleMatchQuery);
071                
072                Index index = initCtx.getDynamoDBIndex(simpleMatchQuery.getKey());
073                
074                ItemCollection<QueryOutcome> items = index.query(querySpec);
075                
076                items.forEach(item -> consumer.accept(initCtx.getDynamoDBItemTransformer().toInfinispanEntry(item)));
077        }
078}