Search in sources :

Example 1 with ResourceInUseException

use of software.amazon.awssdk.services.dynamodb.model.ResourceInUseException in project automatiko-engine by automatiko-io.

the class DynamoDBJobService method createTable.

protected void createTable() {
    DynamoDbWaiter dbWaiter = dynamodb.waiter();
    List<KeySchemaElement> indexKeySchema = new ArrayList<KeySchemaElement>();
    indexKeySchema.add(KeySchemaElement.builder().attributeName(INSTANCE_ID_FIELD).keyType(KeyType.HASH).build());
    CreateTableRequest request = CreateTableRequest.builder().attributeDefinitions(AttributeDefinition.builder().attributeName(INSTANCE_ID_FIELD).attributeType(ScalarAttributeType.S).build()).keySchema(KeySchemaElement.builder().attributeName(INSTANCE_ID_FIELD).keyType(KeyType.HASH).build()).provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(config.readCapacity().orElse(Long.valueOf(10))).writeCapacityUnits(config.writeCapacity().orElse(Long.valueOf(10))).build()).tableName(tableName).build();
    try {
        CreateTableResponse response = dynamodb.createTable(request);
        if (response.sdkHttpResponse().isSuccessful()) {
            DescribeTableRequest tableRequest = DescribeTableRequest.builder().tableName(tableName).build();
            // Wait until the Amazon DynamoDB table is created
            WaiterResponse<DescribeTableResponse> waiterResponse = dbWaiter.waitUntilTableExists(tableRequest);
            waiterResponse.matched().response().ifPresent(r -> LOGGER.debug("Table for jobs created in DynamoDB {}", r.toString()));
        } else {
            throw new RuntimeException("Unable to create table for jobs reason " + response.sdkHttpResponse().statusText());
        }
    } catch (ResourceInUseException e) {
    // ignore as this means table exists
    } catch (DynamoDbException e) {
        throw new RuntimeException("Unable to create table for jobs", e);
    }
}
Also used : DynamoDbException(software.amazon.awssdk.services.dynamodb.model.DynamoDbException) ResourceInUseException(software.amazon.awssdk.services.dynamodb.model.ResourceInUseException) ArrayList(java.util.ArrayList) CreateTableResponse(software.amazon.awssdk.services.dynamodb.model.CreateTableResponse) DescribeTableResponse(software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse) DescribeTableRequest(software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest) DynamoDbWaiter(software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter) CreateTableRequest(software.amazon.awssdk.services.dynamodb.model.CreateTableRequest) KeySchemaElement(software.amazon.awssdk.services.dynamodb.model.KeySchemaElement)

Example 2 with ResourceInUseException

use of software.amazon.awssdk.services.dynamodb.model.ResourceInUseException in project openhab-addons by openhab.

the class TableCreatingPutItem method internalPutItemAsync.

private CompletableFuture<Void> internalPutItemAsync(boolean createTable, boolean recursionAllowed) {
    if (createTable) {
        // Try again, first creating the table
        Instant tableCreationStart = Instant.now();
        table.createTable(CreateTableEnhancedRequest.builder().provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(dbConfig.getReadCapacityUnits()).writeCapacityUnits(dbConfig.getWriteCapacityUnits()).build()).build()).whenCompleteAsync((resultTableCreation, exceptionTableCreation) -> {
            if (exceptionTableCreation == null) {
                logger.trace("PutItem: Table created in {} ms. Proceeding to TTL creation.", Duration.between(tableCreationStart, Instant.now()).toMillis());
                // 
                // Table creation OK. Configure TTL
                // 
                boolean legacy = tableNameResolver.getTableSchema() == ExpectedTableSchema.LEGACY;
                waitForTableToBeActive().thenComposeAsync(_void -> {
                    if (legacy) {
                        // We have legacy table schema. TTL configuration is skipped
                        return CompletableFuture.completedFuture(null);
                    } else {
                        // for the newly created table
                        return lowLevelClient.updateTimeToLive(req -> req.overrideConfiguration(this.service::overrideConfig).tableName(table.tableName()).timeToLiveSpecification(spec -> spec.attributeName(DynamoDBItem.ATTRIBUTE_NAME_EXPIRY).enabled(true)));
                    }
                }, executor).whenCompleteAsync((resultTTL, exceptionTTL) -> {
                    if (exceptionTTL == null) {
                        // 
                        // TTL configuration OK, continue with PutItem
                        // 
                        logger.trace("PutItem: TTL configured successfully");
                        internalPutItemAsync(false, false);
                    } else {
                        // 
                        // TTL configuration failed, abort
                        // 
                        logger.trace("PutItem: TTL configuration failed");
                        Throwable exceptionTTLCause = exceptionTTL.getCause();
                        aggregateFuture.completeExceptionally(exceptionTTLCause == null ? exceptionTTL : exceptionTTLCause);
                    }
                }, executor);
            } else {
                // Table creation failed. We give up and complete the aggregate
                // future -- unless the error was ResourceInUseException, in which case wait for
                // table to become active and try again
                Throwable cause = exceptionTableCreation.getCause();
                if (cause instanceof ResourceInUseException) {
                    logger.trace("PutItem: table creation failed (will be retried) with {} {}. Perhaps tried to create table that already exists. Trying one more time without creating table.", cause.getClass().getSimpleName(), cause.getMessage());
                    // Wait table to be active, then retry PutItem
                    waitForTableToBeActive().whenCompleteAsync((_tableWaitResponse, tableWaitException) -> {
                        if (tableWaitException != null) {
                            // error when waiting for table to become active
                            Throwable tableWaitExceptionCause = tableWaitException.getCause();
                            logger.warn("PutItem: failed (final) with {} {} when waiting to become active. Aborting.", tableWaitExceptionCause == null ? tableWaitException.getClass().getSimpleName() : tableWaitExceptionCause.getClass().getSimpleName(), tableWaitExceptionCause == null ? tableWaitException.getMessage() : tableWaitExceptionCause.getMessage());
                            aggregateFuture.completeExceptionally(tableWaitExceptionCause == null ? tableWaitException : tableWaitExceptionCause);
                        }
                    }, executor).thenRunAsync(() -> internalPutItemAsync(false, false), executor);
                } else {
                    logger.warn("PutItem: failed (final) with {} {}. Aborting.", cause == null ? exceptionTableCreation.getClass().getSimpleName() : cause.getClass().getSimpleName(), cause == null ? exceptionTableCreation.getMessage() : cause.getMessage());
                    aggregateFuture.completeExceptionally(cause == null ? exceptionTableCreation : cause);
                }
            }
        }, executor);
    } else {
        // First try, optimistically assuming that table exists
        table.putItem(dto).whenCompleteAsync((result, exception) -> {
            if (exception == null) {
                logger.trace("PutItem: DTO {} was successfully written in {} ms.", dto, Duration.between(start, Instant.now()).toMillis());
                aggregateFuture.complete(result);
            } else {
                // With other errors, we abort.
                if (!(exception instanceof CompletionException)) {
                    logger.error("PutItem: Expecting only CompletionException, got {} {}. BUG", exception.getClass().getName(), exception.getMessage());
                    aggregateFuture.completeExceptionally(new IllegalStateException("unexpected exception"));
                }
                Throwable cause = exception.getCause();
                if (cause instanceof ResourceNotFoundException && recursionAllowed) {
                    logger.trace("PutItem: Table '{}' was not present. Retrying, this time creating the table first", table.tableName());
                    internalPutItemAsync(true, true);
                } else {
                    logger.warn("PutItem: failed (final) with {} {}. Aborting.", cause == null ? exception.getClass().getSimpleName() : cause.getClass().getSimpleName(), cause == null ? exception.getMessage() : cause.getMessage());
                    aggregateFuture.completeExceptionally(cause == null ? exception : cause);
                }
            }
        }, executor);
    }
    return aggregateFuture;
}
Also used : DescribeTableResponse(software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse) NonNullByDefault(org.eclipse.jdt.annotation.NonNullByDefault) Logger(org.slf4j.Logger) LoggerFactory(org.slf4j.LoggerFactory) DynamoDbAsyncClient(software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient) CompletableFuture(java.util.concurrent.CompletableFuture) CompletionException(java.util.concurrent.CompletionException) Instant(java.time.Instant) ResponseOrException(software.amazon.awssdk.core.internal.waiters.ResponseOrException) ResourceNotFoundException(software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException) CreateTableEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.CreateTableEnhancedRequest) ProvisionedThroughput(software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput) Duration(java.time.Duration) DynamoDbAsyncTable(software.amazon.awssdk.enhanced.dynamodb.DynamoDbAsyncTable) ExecutorService(java.util.concurrent.ExecutorService) ResourceInUseException(software.amazon.awssdk.services.dynamodb.model.ResourceInUseException) Instant(java.time.Instant) ResourceInUseException(software.amazon.awssdk.services.dynamodb.model.ResourceInUseException) CompletionException(java.util.concurrent.CompletionException) ResourceNotFoundException(software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException)

Example 3 with ResourceInUseException

use of software.amazon.awssdk.services.dynamodb.model.ResourceInUseException in project iep by Netflix.

the class DynamoDbLeaderDatabase method initialize.

@Override
public void initialize() {
    final Collection<AttributeDefinition> attributeDefinitions = Lists.newArrayList(AttributeDefinition.builder().attributeName(hashKeyName).attributeType(ScalarAttributeType.S).build());
    final Collection<KeySchemaElement> keySchemaElements = Lists.newArrayList(KeySchemaElement.builder().attributeName(hashKeyName).keyType(KeyType.HASH).build());
    final ProvisionedThroughput provisionedThroughput = ProvisionedThroughput.builder().readCapacityUnits(readCapacityUnits).writeCapacityUnits(writeCapacityUnits).build();
    final CreateTableRequest createTableRequest = CreateTableRequest.builder().tableName(tableName).keySchema(keySchemaElements).attributeDefinitions(attributeDefinitions).provisionedThroughput(provisionedThroughput).build();
    try {
        CreateTableResponse tableResult = db.createTable(createTableRequest);
        logger.info("Created table '{}': Table Status = {}, SDK HTTP Response = {}", tableName, tableResult.tableDescription().tableStatusAsString(), tableResult.sdkHttpResponse().statusCode());
    } catch (ResourceInUseException e) {
        logger.debug("Did not create table '{}'; it already exists", tableName);
    }
    waitUntilTableIsActive(db, tableName, tableActiveTimeout);
}
Also used : ResourceInUseException(software.amazon.awssdk.services.dynamodb.model.ResourceInUseException) CreateTableResponse(software.amazon.awssdk.services.dynamodb.model.CreateTableResponse) AttributeDefinition(software.amazon.awssdk.services.dynamodb.model.AttributeDefinition) ProvisionedThroughput(software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput) CreateTableRequest(software.amazon.awssdk.services.dynamodb.model.CreateTableRequest) KeySchemaElement(software.amazon.awssdk.services.dynamodb.model.KeySchemaElement)

Example 4 with ResourceInUseException

use of software.amazon.awssdk.services.dynamodb.model.ResourceInUseException in project automatiko-engine by automatiko-io.

the class DynamoDBProcessInstances method createTable.

protected void createTable() {
    DynamoDbWaiter dbWaiter = dynamodb.waiter();
    CreateTableRequest request = CreateTableRequest.builder().attributeDefinitions(AttributeDefinition.builder().attributeName(INSTANCE_ID_FIELD).attributeType(ScalarAttributeType.S).build()).keySchema(KeySchemaElement.builder().attributeName(INSTANCE_ID_FIELD).keyType(KeyType.HASH).build()).provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(config.readCapacity().orElse(Long.valueOf(10))).writeCapacityUnits(config.writeCapacity().orElse(Long.valueOf(10))).build()).tableName(tableName).build();
    try {
        CreateTableResponse response = dynamodb.createTable(request);
        if (response.sdkHttpResponse().isSuccessful()) {
            DescribeTableRequest tableRequest = DescribeTableRequest.builder().tableName(tableName).build();
            // Wait until the Amazon DynamoDB table is created
            WaiterResponse<DescribeTableResponse> waiterResponse = dbWaiter.waitUntilTableExists(tableRequest);
            waiterResponse.matched().response().ifPresent(r -> LOGGER.debug("Table for process {} created in DynamoDB {}", process.id(), r.toString()));
        } else {
            throw new RuntimeException("Unable to create table for process " + process.id() + " reason " + response.sdkHttpResponse().statusText());
        }
    } catch (ResourceInUseException e) {
    // ignore as this means table exists
    } catch (DynamoDbException e) {
        throw new RuntimeException("Unable to create table for process " + process.id(), e);
    }
}
Also used : DynamoDbException(software.amazon.awssdk.services.dynamodb.model.DynamoDbException) ResourceInUseException(software.amazon.awssdk.services.dynamodb.model.ResourceInUseException) CreateTableResponse(software.amazon.awssdk.services.dynamodb.model.CreateTableResponse) DescribeTableResponse(software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse) DescribeTableRequest(software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest) DynamoDbWaiter(software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter) CreateTableRequest(software.amazon.awssdk.services.dynamodb.model.CreateTableRequest)

Aggregations

ResourceInUseException (software.amazon.awssdk.services.dynamodb.model.ResourceInUseException)4 CreateTableRequest (software.amazon.awssdk.services.dynamodb.model.CreateTableRequest)3 CreateTableResponse (software.amazon.awssdk.services.dynamodb.model.CreateTableResponse)3 DescribeTableResponse (software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse)3 DescribeTableRequest (software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest)2 DynamoDbException (software.amazon.awssdk.services.dynamodb.model.DynamoDbException)2 KeySchemaElement (software.amazon.awssdk.services.dynamodb.model.KeySchemaElement)2 ProvisionedThroughput (software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput)2 DynamoDbWaiter (software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter)2 Duration (java.time.Duration)1 Instant (java.time.Instant)1 ArrayList (java.util.ArrayList)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 CompletionException (java.util.concurrent.CompletionException)1 ExecutorService (java.util.concurrent.ExecutorService)1 NonNullByDefault (org.eclipse.jdt.annotation.NonNullByDefault)1 Logger (org.slf4j.Logger)1 LoggerFactory (org.slf4j.LoggerFactory)1 ResponseOrException (software.amazon.awssdk.core.internal.waiters.ResponseOrException)1 DynamoDbAsyncTable (software.amazon.awssdk.enhanced.dynamodb.DynamoDbAsyncTable)1