All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nimbusds.infinispan.persistence.dynamodb.query.SimpleMatchQueryExecutor Maven / Gradle / Ivy

There is a newer version: 7.0
Show newest version
package com.nimbusds.infinispan.persistence.dynamodb.query;


import java.util.Map;
import java.util.function.Consumer;

import com.amazonaws.services.dynamodbv2.document.Index;
import com.amazonaws.services.dynamodbv2.document.ItemCollection;
import com.amazonaws.services.dynamodbv2.document.QueryOutcome;
import com.amazonaws.services.dynamodbv2.document.ScanOutcome;
import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;
import com.amazonaws.services.dynamodbv2.document.spec.ScanSpec;
import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
import com.nimbusds.infinispan.persistence.common.InfinispanEntry;
import com.nimbusds.infinispan.persistence.common.query.MatchQuery;
import com.nimbusds.infinispan.persistence.common.query.Query;
import com.nimbusds.infinispan.persistence.common.query.SimpleMatchQuery;
import com.nimbusds.infinispan.persistence.common.query.UnsupportedQueryException;
import net.jcip.annotations.ThreadSafe;


/**
 * Simple match DynamoDB query executor. Accepts queries of type
 * {@link SimpleMatchQuery} and {@link MatchQuery} (converts it to
 * {@link SimpleMatchQuery by taking the first match pair}, where both key name
 * and value must be of type {@link String}.
 */
@ThreadSafe
public class SimpleMatchQueryExecutor implements DynamoDBQueryExecutor {
	
	
	/**
	 * The initialisation context.
	 */
	private DynamoDBQueryExecutorInitContext initCtx;
	
	
	@Override
	public void init(final DynamoDBQueryExecutorInitContext initCtx) {
		if (initCtx == null) {
			throw new IllegalArgumentException("The init context must not be null");
		}
		this.initCtx = initCtx;
	}
	
	
	/**
	 * Returns the DynamoDB query spec for the specified simple match
	 * query.
	 *
	 * @param simpleMatchQuery The simple match query. Must not be
	 *                         {@code null}.
	 *
	 * @return The DynamoDB query spec.
	 */
	static QuerySpec toQuerySpec(final SimpleMatchQuery simpleMatchQuery) {
		
		return new QuerySpec()
			.withKeyConditionExpression("#k = :value")
			.withNameMap(new NameMap()
				.with("#k", simpleMatchQuery.getKey()))
			.withValueMap(new ValueMap()
				.withString(":value", simpleMatchQuery.getValue()));
	}
	
	/**
	 * Returns the DynamoDB scan spec for the specified simple match
	 * query.
	 *
	 * @param simpleMatchQuery The simple match query. Must not be
	 *                         {@code null}.
	 *
	 * @return The DynamoDB scan spec.
	 */
	static ScanSpec toScanSpec(final SimpleMatchQuery simpleMatchQuery) {
		
		return new ScanSpec()
			.withFilterExpression("#k = :value")
			.withNameMap(new NameMap()
				.with("#k", simpleMatchQuery.getKey()))
			.withValueMap(new ValueMap()
				.withString(":value", simpleMatchQuery.getValue()))
			.withConsistentRead(false);
	}
	
	
	/**
	 * Converts the specified match query to a simple match query.
	 *
	 * @param matchQuery The match query.
	 *
	 * @return The simple match query.
	 */
	static SimpleMatchQuery toSimpleMatchQuery(final MatchQuery matchQuery) {
		
		if (matchQuery instanceof SimpleMatchQuery) {
			return (SimpleMatchQuery)matchQuery;
		}
		
		Map.Entry entry = matchQuery.getMatchMap().entrySet().iterator().next();
		
		return new SimpleMatchQuery<>(entry.getKey(), entry.getValue());
	}
	
	
	@Override
	@SuppressWarnings("unchecked")
	public void executeQuery(final Query query, final Consumer> consumer) {
		
		if (! (query instanceof MatchQuery)) {
			throw new UnsupportedQueryException(query);
		}
		
		MatchQuery matchQuery = (MatchQuery)query;
		
		if (matchQuery.getMatchMap().isEmpty()) {
			throw new UnsupportedQueryException(query);
		}
		
		SimpleMatchQuery simpleMatchQuery = toSimpleMatchQuery(matchQuery);
		
		Index index = initCtx.getDynamoDBIndex(simpleMatchQuery.getKey());
		
		if (index != null) {
			// Query via GSI
			ItemCollection items = index.query(toQuerySpec(simpleMatchQuery));
			items.forEach(item -> consumer.accept(initCtx.getDynamoDBItemTransformer().toInfinispanEntry(item)));
		} else {
			// Fall back to scan with filter expression
			ItemCollection scanOutcome = initCtx.getDynamoDBTable().scan(toScanSpec(simpleMatchQuery));
			scanOutcome.forEach(item -> consumer.accept(initCtx.getDynamoDBItemTransformer().toInfinispanEntry(item)));
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy