Search in sources :

Example 16 with ExecutionException

use of com.scalar.db.exception.storage.ExecutionException in project scalardb by scalar-labs.

the class BatchHandler method handle.

/**
 * Execute the specified list of {@link Mutation}s in batch. All the {@link Mutation}s in the list
 * must be for the same partition.
 *
 * @param mutations a list of {@code Mutation}s to execute
 * @throws NoMutationException if at least one of conditional {@code Mutation}s failed because it
 *     didn't meet the condition
 */
public void handle(List<? extends Mutation> mutations) throws ExecutionException {
    if (mutations.size() > 25) {
        throw new IllegalArgumentException("DynamoDB cannot batch more than 25 mutations at once.");
    }
    TableMetadata tableMetadata = metadataManager.getTableMetadata(mutations.get(0));
    TransactWriteItemsRequest.Builder builder = TransactWriteItemsRequest.builder();
    List<TransactWriteItem> transactItems = new ArrayList<>();
    mutations.forEach(m -> transactItems.add(makeWriteItem(m, tableMetadata)));
    builder.transactItems(transactItems);
    try {
        client.transactWriteItems(builder.build());
    } catch (TransactionCanceledException e) {
        boolean allReasonsAreTransactionConflicts = true;
        for (CancellationReason reason : e.cancellationReasons()) {
            if (reason.code().equals("ConditionalCheckFailed")) {
                throw new NoMutationException("no mutation was applied.", e);
            }
            if (!reason.code().equals("TransactionConflict") && !reason.code().equals("None")) {
                allReasonsAreTransactionConflicts = false;
            }
        }
        if (allReasonsAreTransactionConflicts) {
            // RetriableExecutionException
            throw new RetriableExecutionException(e.getMessage(), e);
        }
        throw new ExecutionException(e.getMessage(), e);
    } catch (DynamoDbException e) {
        throw new ExecutionException(e.getMessage(), e);
    }
}
Also used : TableMetadata(com.scalar.db.api.TableMetadata) CancellationReason(software.amazon.awssdk.services.dynamodb.model.CancellationReason) TransactWriteItemsRequest(software.amazon.awssdk.services.dynamodb.model.TransactWriteItemsRequest) ArrayList(java.util.ArrayList) RetriableExecutionException(com.scalar.db.exception.storage.RetriableExecutionException) TransactionCanceledException(software.amazon.awssdk.services.dynamodb.model.TransactionCanceledException) DynamoDbException(software.amazon.awssdk.services.dynamodb.model.DynamoDbException) TransactWriteItem(software.amazon.awssdk.services.dynamodb.model.TransactWriteItem) ExecutionException(com.scalar.db.exception.storage.ExecutionException) RetriableExecutionException(com.scalar.db.exception.storage.RetriableExecutionException) NoMutationException(com.scalar.db.exception.storage.NoMutationException)

Example 17 with ExecutionException

use of com.scalar.db.exception.storage.ExecutionException in project scalardb by scalar-labs.

the class DynamoAdmin method createIndex.

@Override
public void createIndex(String namespace, String table, String columnName, Map<String, String> options) throws ExecutionException {
    long ru = Long.parseLong(options.getOrDefault(REQUEST_UNIT, DEFAULT_REQUEST_UNIT));
    TableMetadata metadata = getTableMetadata(namespace, table);
    try {
        client.updateTable(UpdateTableRequest.builder().tableName(getFullTableName(namespace, table)).attributeDefinitions(AttributeDefinition.builder().attributeName(columnName).attributeType(SECONDARY_INDEX_DATATYPE_MAP.get(metadata.getColumnDataType(columnName))).build()).globalSecondaryIndexUpdates(GlobalSecondaryIndexUpdate.builder().create(CreateGlobalSecondaryIndexAction.builder().indexName(getGlobalIndexName(namespace, table, columnName)).keySchema(KeySchemaElement.builder().attributeName(columnName).keyType(KeyType.HASH).build()).projection(Projection.builder().projectionType(ProjectionType.ALL).build()).provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(ru).writeCapacityUnits(ru).build()).build()).build()).build());
    } catch (Exception e) {
        throw new ExecutionException("creating the secondary index failed", e);
    }
    waitForIndexCreation(namespace, table, columnName);
    // enable auto scaling
    boolean noScaling = Boolean.parseBoolean(options.getOrDefault(NO_SCALING, DEFAULT_NO_SCALING));
    if (!noScaling) {
        List<RegisterScalableTargetRequest> registerScalableTargetRequestList = new ArrayList<>();
        List<PutScalingPolicyRequest> putScalingPolicyRequestList = new ArrayList<>();
        // write, read scaling of global indexes (secondary indexes)
        for (String scalingType : SECONDARY_INDEX_SCALING_TYPE_SET) {
            registerScalableTargetRequestList.add(buildRegisterScalableTargetRequest(getGlobalIndexResourceID(namespace, table, columnName), scalingType, (int) ru));
            putScalingPolicyRequestList.add(buildPutScalingPolicyRequest(getGlobalIndexResourceID(namespace, table, columnName), scalingType));
        }
        registerScalableTarget(registerScalableTargetRequestList);
        putScalingPolicy(putScalingPolicyRequestList);
    }
    // update metadata
    TableMetadata tableMetadata = getTableMetadata(namespace, table);
    putTableMetadata(namespace, table, TableMetadata.newBuilder(tableMetadata).addSecondaryIndex(columnName).build());
}
Also used : TableMetadata(com.scalar.db.api.TableMetadata) RegisterScalableTargetRequest(software.amazon.awssdk.services.applicationautoscaling.model.RegisterScalableTargetRequest) PutScalingPolicyRequest(software.amazon.awssdk.services.applicationautoscaling.model.PutScalingPolicyRequest) ArrayList(java.util.ArrayList) ExecutionException(com.scalar.db.exception.storage.ExecutionException) ExecutionException(com.scalar.db.exception.storage.ExecutionException) ObjectNotFoundException(software.amazon.awssdk.services.applicationautoscaling.model.ObjectNotFoundException) ResourceNotFoundException(software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException) DynamoDbException(software.amazon.awssdk.services.dynamodb.model.DynamoDbException)

Example 18 with ExecutionException

use of com.scalar.db.exception.storage.ExecutionException in project scalardb by scalar-labs.

the class DynamoAdmin method truncateTable.

@Override
public void truncateTable(String namespace, String table) throws ExecutionException {
    String fullTableName = getFullTableName(namespace, table);
    Map<String, AttributeValue> lastKeyEvaluated = null;
    do {
        ScanResponse scanResponse;
        try {
            scanResponse = client.scan(ScanRequest.builder().tableName(fullTableName).limit(DELETE_BATCH_SIZE).exclusiveStartKey(lastKeyEvaluated).build());
        } catch (Exception e) {
            throw new ExecutionException("scanning items from table " + fullTableName + " failed.", e);
        }
        for (Map<String, AttributeValue> item : scanResponse.items()) {
            Map<String, AttributeValue> keyToDelete = new HashMap<>();
            keyToDelete.put(PARTITION_KEY, item.get(PARTITION_KEY));
            if (item.containsKey(CLUSTERING_KEY)) {
                keyToDelete.put(CLUSTERING_KEY, item.get(CLUSTERING_KEY));
            }
            try {
                client.deleteItem(DeleteItemRequest.builder().tableName(fullTableName).key(keyToDelete).build());
            } catch (Exception e) {
                throw new ExecutionException("deleting item from table " + fullTableName + " failed.", e);
            }
        }
        lastKeyEvaluated = scanResponse.lastEvaluatedKey();
    } while (!lastKeyEvaluated.isEmpty());
}
Also used : AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) HashMap(java.util.HashMap) ScanResponse(software.amazon.awssdk.services.dynamodb.model.ScanResponse) ExecutionException(com.scalar.db.exception.storage.ExecutionException) ExecutionException(com.scalar.db.exception.storage.ExecutionException) ObjectNotFoundException(software.amazon.awssdk.services.applicationautoscaling.model.ObjectNotFoundException) ResourceNotFoundException(software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException) DynamoDbException(software.amazon.awssdk.services.dynamodb.model.DynamoDbException)

Example 19 with ExecutionException

use of com.scalar.db.exception.storage.ExecutionException in project scalardb by scalar-labs.

the class DynamoAdmin method createMetadataTableIfNotExists.

private void createMetadataTableIfNotExists(boolean noBackup) throws ExecutionException {
    if (metadataTableExists()) {
        return;
    }
    List<AttributeDefinition> columnsToAttributeDefinitions = new ArrayList<>();
    columnsToAttributeDefinitions.add(AttributeDefinition.builder().attributeName(METADATA_ATTR_TABLE).attributeType(ScalarAttributeType.S).build());
    try {
        client.createTable(CreateTableRequest.builder().attributeDefinitions(columnsToAttributeDefinitions).keySchema(KeySchemaElement.builder().attributeName(METADATA_ATTR_TABLE).keyType(KeyType.HASH).build()).provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(METADATA_TABLE_REQUEST_UNIT).writeCapacityUnits(METADATA_TABLE_REQUEST_UNIT).build()).tableName(getFullTableName(metadataNamespace, METADATA_TABLE)).build());
    } catch (Exception e) {
        throw new ExecutionException("creating the metadata table failed", e);
    }
    waitForTableCreation(metadataNamespace, METADATA_TABLE);
    if (!noBackup) {
        enableContinuousBackup(metadataNamespace, METADATA_TABLE);
    }
}
Also used : ArrayList(java.util.ArrayList) AttributeDefinition(software.amazon.awssdk.services.dynamodb.model.AttributeDefinition) ExecutionException(com.scalar.db.exception.storage.ExecutionException) ExecutionException(com.scalar.db.exception.storage.ExecutionException) ObjectNotFoundException(software.amazon.awssdk.services.applicationautoscaling.model.ObjectNotFoundException) ResourceNotFoundException(software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException) DynamoDbException(software.amazon.awssdk.services.dynamodb.model.DynamoDbException)

Example 20 with ExecutionException

use of com.scalar.db.exception.storage.ExecutionException in project scalardb by scalar-labs.

the class DynamoAdmin method namespaceExists.

@Override
public boolean namespaceExists(String namespace) throws ExecutionException {
    try {
        boolean namespaceExists = false;
        String lastEvaluatedTableName = null;
        do {
            ListTablesRequest listTablesRequest = ListTablesRequest.builder().exclusiveStartTableName(lastEvaluatedTableName).build();
            ListTablesResponse listTablesResponse = client.listTables(listTablesRequest);
            lastEvaluatedTableName = listTablesResponse.lastEvaluatedTableName();
            List<String> tableNames = listTablesResponse.tableNames();
            for (String tableName : tableNames) {
                if (tableName.startsWith(namespace)) {
                    namespaceExists = true;
                    break;
                }
            }
        } while (lastEvaluatedTableName != null);
        return namespaceExists;
    } catch (DynamoDbException e) {
        throw new ExecutionException("checking the namespace existence failed", e);
    }
}
Also used : DynamoDbException(software.amazon.awssdk.services.dynamodb.model.DynamoDbException) ListTablesRequest(software.amazon.awssdk.services.dynamodb.model.ListTablesRequest) ListTablesResponse(software.amazon.awssdk.services.dynamodb.model.ListTablesResponse) ExecutionException(com.scalar.db.exception.storage.ExecutionException)

Aggregations

ExecutionException (com.scalar.db.exception.storage.ExecutionException)78 DynamoDbException (software.amazon.awssdk.services.dynamodb.model.DynamoDbException)23 RetriableExecutionException (com.scalar.db.exception.storage.RetriableExecutionException)18 ObjectNotFoundException (software.amazon.awssdk.services.applicationautoscaling.model.ObjectNotFoundException)18 ResourceNotFoundException (software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException)18 SQLException (java.sql.SQLException)14 ArrayList (java.util.ArrayList)14 Connection (java.sql.Connection)12 Test (org.junit.jupiter.api.Test)11 HashSet (java.util.HashSet)10 NoMutationException (com.scalar.db.exception.storage.NoMutationException)9 TableMetadata (com.scalar.db.api.TableMetadata)8 Value (com.scalar.db.io.Value)8 Put (com.scalar.db.api.Put)7 TransactionState (com.scalar.db.api.TransactionState)6 CrudException (com.scalar.db.exception.transaction.CrudException)6 HashMap (java.util.HashMap)6 AttributeValue (software.amazon.awssdk.services.dynamodb.model.AttributeValue)5 CosmosDatabase (com.azure.cosmos.CosmosDatabase)4 Get (com.scalar.db.api.Get)4