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

com.amazonaws.services.dynamodbv2.document.Index Maven / Gradle / Ivy

Go to download

The AWS SDK for Java with support for OSGi. The AWS SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).

There is a newer version: 1.11.60
Show newest version
/*
 * Copyright 2014-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file 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.amazonaws.services.dynamodbv2.document;

import java.util.List;
import java.util.Map;

import org.apache.http.annotation.ThreadSafe;

import com.amazonaws.annotation.Beta;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.document.api.QueryApi;
import com.amazonaws.services.dynamodbv2.document.api.ScanApi;
import com.amazonaws.services.dynamodbv2.document.internal.IndexQueryImpl;
import com.amazonaws.services.dynamodbv2.document.internal.IndexScanImpl;
import com.amazonaws.services.dynamodbv2.document.internal.ScanImpl;
import com.amazonaws.services.dynamodbv2.document.spec.QuerySpec;
import com.amazonaws.services.dynamodbv2.document.spec.ScanSpec;
import com.amazonaws.services.dynamodbv2.document.spec.UpdateTableSpec;
import com.amazonaws.services.dynamodbv2.model.DeleteGlobalSecondaryIndexAction;
import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndexDescription;
import com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndexUpdate;
import com.amazonaws.services.dynamodbv2.model.IndexStatus;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ResourceNotFoundException;
import com.amazonaws.services.dynamodbv2.model.TableDescription;
import com.amazonaws.services.dynamodbv2.model.UpdateGlobalSecondaryIndexAction;
import com.amazonaws.services.dynamodbv2.xspec.QueryExpressionSpec;
import com.amazonaws.services.dynamodbv2.xspec.ScanExpressionSpec;

/**
 * Represents a secondary index on a DynamoDB table. This covers
 * both GSI (Global Secondary Index) and LSI (Local Secondary Index). Instance
 * of this class can be obtained via {@link Table#getIndex(String)}.
 */
@ThreadSafe
public class Index implements QueryApi, ScanApi {
    private static final long SLEEP_TIME_MILLIS = 5000;
    private final Table table;
    private final String indexName;
    private final QueryApi queryDelegate;
    private final ScanImpl scanDelegate;

    Index(AmazonDynamoDB client, String indexName, Table table) {
        if (client == null)
            throw new IllegalArgumentException("client must be specified");
        if (indexName == null || indexName.trim().length() == 0)
            throw new IllegalArgumentException("index name must not be null or empty");
        if (table == null)
            throw new IllegalArgumentException("table must be specified");
        this.table = table;
        this.indexName = indexName;
        this.queryDelegate = new IndexQueryImpl(client, this);
        this.scanDelegate  = new IndexScanImpl(client, this);
    }

    /**
     * Returns the owning table.
     */
    public final Table getTable() {
        return table;
    }

    /**
     * @return the name of this index
     */
    public final String getIndexName() {
        return indexName;
    }

    @Override
    public ItemCollection query(KeyAttribute hashKey,
            RangeKeyCondition rangeKeyCondition) {
        return queryDelegate.query(hashKey, rangeKeyCondition);
    }

    @Override
    public ItemCollection query(KeyAttribute hashKey,
            RangeKeyCondition rangeKeyCondition, QueryFilter... queryFilters) {
        return queryDelegate.query(hashKey, rangeKeyCondition, queryFilters);
    }

    @Override
    public ItemCollection query(KeyAttribute hashKey,
            RangeKeyCondition rangeKeyCondition, String filterExpression,
            Map nameMap, Map valueMap) {
        return queryDelegate.query(hashKey, rangeKeyCondition,
                filterExpression, nameMap, valueMap);
    }

    @Override
    public ItemCollection query(KeyAttribute hashKey,
            RangeKeyCondition rangeKeyCondition, String projectionExpression,
            String filterExpression, Map nameMap,
            Map valueMap) {
        return queryDelegate.query(hashKey, rangeKeyCondition,
                projectionExpression, filterExpression, nameMap, valueMap);
    }

    @Beta
    public ItemCollection query(KeyAttribute hashKey,
            RangeKeyCondition rangeKeyCondition, QueryExpressionSpec queryExpressions) {
        return queryDelegate.query(hashKey, rangeKeyCondition,
                queryExpressions.getProjectionExpression(),
                queryExpressions.getFilterExpression(),
                queryExpressions.getNameMap(), queryExpressions.getValueMap());
    }

    @Override
    public ItemCollection query(QuerySpec spec) {
        return queryDelegate.query(spec);
    }

    @Override
    public ItemCollection query(
            String hashKeyName, Object hashKeyValue) {
        return queryDelegate.query(hashKeyName, hashKeyValue);
    }

    @Override
    public ItemCollection query(String hashKeyName,
            Object hashKeyValue, RangeKeyCondition rangeKeyCondition) {
        return queryDelegate.query(hashKeyName, hashKeyValue, rangeKeyCondition);
    }

    @Override
    public ItemCollection query(String hashKeyName,
            Object hashKeyValue, RangeKeyCondition rangeKeyCondition,
            QueryFilter... queryFilters) {
        return queryDelegate.query(hashKeyName, hashKeyValue,
                rangeKeyCondition, queryFilters);
    }

    @Override
    public ItemCollection query(String hashKeyName,
            Object hashKeyValue, RangeKeyCondition rangeKeyCondition,
            String filterExpression, Map nameMap,
            Map valueMap) {
        return queryDelegate.query(hashKeyName, hashKeyValue,
                rangeKeyCondition, filterExpression, nameMap, valueMap);
    }

    @Override
    public ItemCollection query(String hashKeyName,
            Object hashKeyValue, RangeKeyCondition rangeKeyCondition,
            String filterExpression, String projectionExpression,
            Map nameMap, Map valueMap) {
        return queryDelegate.query(hashKeyName, hashKeyValue,
                rangeKeyCondition, filterExpression, projectionExpression,
                nameMap, valueMap);
    }

    @Override
    public ItemCollection query(KeyAttribute hashKey) {
        return queryDelegate.query(hashKey);
    }

    /**
     * Updates the provisioned throughput for this global secondary index (GSI).
     * Setting the throughput for an index helps you manage performance and is
     * part of the provisioned throughput feature of DynamoDB.
     * 

* The provisioned throughput values can be upgraded or downgraded based on * the maximums and minimums listed in the Limits section in the Amazon DynamoDB Developer Guide. *

* This index must be a global secondary index and in the * ACTIVE state for this operation to succeed. Updating a GSI * is an asynchronous operation; while executing the operation, the index is * in the UPDATING state. While the index is in the * UPDATING state, the index still has the provisioned * throughput from before the call. The new provisioned throughput setting * is in effect only when the index returns to the ACTIVE state * after the update is complete. * * @param provisionedThroughput * target provisioned throughput * * @return the updated table description returned from DynamoDB. */ public TableDescription updateGSI( ProvisionedThroughput provisionedThroughput) { return table.updateTable(new UpdateTableSpec() .withGlobalSecondaryIndexUpdates( new GlobalSecondaryIndexUpdate().withUpdate( new UpdateGlobalSecondaryIndexAction() .withIndexName(indexName) .withProvisionedThroughput(provisionedThroughput)))); } /** * Deletes this global secondary index (GSI) from the DynamoDB table. * Involves network calls. *

* This index must be a global secondary index and in the * ACTIVE state for this operation to succeed. Deleting a GSI * is an asynchronous operation; while executing the operation, the index is * in the DELETING state. * * @return the updated table description returned from DynamoDB. */ public TableDescription deleteGSI() { return table.updateTable(new UpdateTableSpec() .withGlobalSecondaryIndexUpdates( new GlobalSecondaryIndexUpdate().withDelete( new DeleteGlobalSecondaryIndexAction() .withIndexName(indexName)))); } /** * A convenient blocking call that can be used, typically during index * creation, to wait for the index to become active by polling the table * every 5 seconds. *

* Currently online index creation is only supported for Global Secondary * Index (GSI). Calling this method on a Local Secondary Index (LSI) would * result in IllegalArgumentException. * * @return the table description when the index has become active * * @throws IllegalArgumentException if the table is being deleted, or if * the GSI is not being created or updated, or if the GSI doesn't exist * @throws ResourceNotFoundException if the table doesn't exist */ public TableDescription waitForActive() throws InterruptedException { final Table table = getTable(); final String tableName = table.getTableName(); final String indexName = getIndexName(); retry: for (;;) { TableDescription desc = table.waitForActive(); final List list = desc.getGlobalSecondaryIndexes(); if (list != null) { for (GlobalSecondaryIndexDescription d: list) { if (d.getIndexName().equals(indexName)) { final String status = d.getIndexStatus(); switch(IndexStatus.fromValue(status)) { case ACTIVE: return desc; case CREATING: case UPDATING: Thread.sleep(SLEEP_TIME_MILLIS); continue retry; default: throw new IllegalArgumentException( "Global Secondary Index " + indexName + " is not being created or updated (with status=" + status + ")"); } } } } throw new IllegalArgumentException("Global Secondary Index " + indexName + " does not exist in Table " + tableName + ")"); } } /** * A convenient blocking call that can be used, typically during index * deletion on an active table, to wait for the index to become deleted by * polling the table every 5 seconds. *

* Currently online index deletion is only supported for Global Secondary * Index (GSI). The behavior of calling this method on a Local Secondary * Index (LSI) would result in returning the latest table description. * * @return the table description if this GSI has been deleted; or null if * the underlying table has been deleted. * * @throws IllegalArgumentException if the table is being deleted, or if the * GSI is not being deleted. * @throws ResourceNotFoundException if the table doesn't exist */ public TableDescription waitForDelete() throws InterruptedException { final String indexName = getIndexName(); retry: for (;;) { final TableDescription desc = getTable().waitForActive(); List list = desc.getGlobalSecondaryIndexes(); if (list != null) { for (GlobalSecondaryIndexDescription d: list) { if (d.getIndexName().equals(indexName)) { final String status = d.getIndexStatus(); if (IndexStatus.fromValue(status) == IndexStatus.DELETING) { Thread.sleep(SLEEP_TIME_MILLIS); continue retry; } throw new IllegalArgumentException( "Global Secondary Index " + indexName + " is not being deleted (with status=" + status + ")"); } } } return desc; } } /** * A convenient blocking call that can be used to wait on an index until it * has either become active or deleted (ie no longer exists) by polling the * table every 5 seconds. *

* Currently online index creation/deletion is only supported for Global * Secondary Index (GSI). The behavior of calling this method on a Local * Secondary Index (LSI) would result in returning the latest table * description. * * @return the table description when the index has become either active * or deleted * * @throws IllegalArgumentException if the table is being deleted * @throws ResourceNotFoundException if the table doesn't exist */ public TableDescription waitForActiveOrDelete() throws InterruptedException { final Table table = getTable(); final String indexName = getIndexName(); retry: for (;;) { TableDescription desc = table.waitForActive(); List list = desc.getGlobalSecondaryIndexes(); if (list != null) { for (GlobalSecondaryIndexDescription d: desc.getGlobalSecondaryIndexes()) { if (d.getIndexName().equals(indexName)) { final String status = d.getIndexStatus(); if (IndexStatus.fromValue(status) == IndexStatus.ACTIVE) return desc; Thread.sleep(SLEEP_TIME_MILLIS); continue retry; } } } return desc; } } @Override public ItemCollection scan(ScanFilter... scanFilters) { return scanDelegate.scan(scanFilters); } @Override public ItemCollection scan(String filterExpression, Map nameMap, Map valueMap) { return scanDelegate.scan(filterExpression, nameMap, valueMap); } @Override public ItemCollection scan(String filterExpression, String projectionExpression, Map nameMap, Map valueMap) { return scanDelegate.scan(filterExpression, projectionExpression, nameMap, valueMap); } @Beta public ItemCollection scan(ScanExpressionSpec xspec) { return scanDelegate.scan(xspec.getFilterExpression(), xspec.getProjectionExpression(), xspec.getNameMap(), xspec.getValueMap()); } @Override public ItemCollection scan(ScanSpec params) { return scanDelegate.scan(params); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy