Search in sources :

Example 11 with ConditionalCheckFailedException

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

the class DynamoDBProcessInstances method update.

@Override
public void update(String id, ProcessInstance instance) {
    String resolvedId = resolveId(id, instance);
    if (isActive(instance)) {
        LOGGER.debug("update() called for instance {}", resolvedId);
        byte[] data = codec.encode(marshaller.marhsallProcessInstance(instance));
        if (data == null) {
            return;
        }
        HashMap<String, AttributeValue> itemKey = new HashMap<String, AttributeValue>();
        itemKey.put(INSTANCE_ID_FIELD, AttributeValue.builder().s(resolvedId).build());
        Map<String, AttributeValueUpdate> updatedValues = new HashMap<String, AttributeValueUpdate>();
        updatedValues.put(CONTENT_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().b(SdkBytes.fromByteArray(data)).build()).action(AttributeAction.PUT).build());
        updatedValues.put(VERSION_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().n(String.valueOf(((AbstractProcessInstance<?>) instance).getVersionTracker() + 1)).build()).action(AttributeAction.PUT).build());
        updatedValues.put(STATUS_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().n(String.valueOf(((AbstractProcessInstance<?>) instance).status())).build()).action(AttributeAction.PUT).build());
        if (instance.endDate() != null) {
            updatedValues.put(END_DATE_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().n(DateTimeFormatter.ISO_INSTANT.format(instance.endDate().toInstant())).build()).action(AttributeAction.PUT).build());
            if (instance.expiresAtDate() != null) {
                updatedValues.put(EXPIRED_AT_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().n(DateTimeFormatter.ISO_INSTANT.format(instance.expiresAtDate().toInstant())).build()).action(AttributeAction.PUT).build());
            }
        }
        Collection<String> tags = new ArrayList(instance.tags().values());
        tags.add(resolvedId);
        if (instance.businessKey() != null) {
            tags.add(instance.businessKey());
        }
        updatedValues.put(TAGS_FIELD, AttributeValueUpdate.builder().value(AttributeValue.builder().ss(tags).build()).action(AttributeAction.PUT).build());
        UpdateItemRequest request = UpdateItemRequest.builder().tableName(tableName).key(itemKey).attributeUpdates(updatedValues).conditionExpression(VERSION_FIELD + " = " + ((AbstractProcessInstance<?>) instance).getVersionTracker()).build();
        try {
            dynamodb.updateItem(request);
            Supplier<AuditEntry> entry = () -> BaseAuditEntry.persitenceWrite(instance).add("message", "Workflow instance updated in the DynamoDB based data store");
            auditor.publish(entry);
        } catch (ConditionalCheckFailedException e) {
            throw new ConflictingVersionException("Process instance with id '" + instance.id() + "' has older version than the stored one");
        } finally {
            disconnect(instance);
        }
    }
    cachedInstances.remove(resolvedId);
}
Also used : AbstractProcessInstance(io.automatiko.engine.workflow.AbstractProcessInstance) ConflictingVersionException(io.automatiko.engine.api.workflow.ConflictingVersionException) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) UpdateItemRequest(software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest) AttributeValueUpdate(software.amazon.awssdk.services.dynamodb.model.AttributeValueUpdate) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AuditEntry(io.automatiko.engine.api.audit.AuditEntry) BaseAuditEntry(io.automatiko.engine.workflow.audit.BaseAuditEntry) ConditionalCheckFailedException(software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException)

Example 12 with ConditionalCheckFailedException

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

the class DynamoDBProcessInstances method create.

@Override
public void create(String id, ProcessInstance instance) {
    String resolvedId = resolveId(id, instance);
    if (isActive(instance)) {
        LOGGER.debug("create() called for instance {}", resolvedId);
        byte[] data = codec.encode(marshaller.marhsallProcessInstance(instance));
        if (data == null) {
            return;
        }
        Map<String, AttributeValue> itemValues = new HashMap<String, AttributeValue>();
        itemValues.put(INSTANCE_ID_FIELD, AttributeValue.builder().s(resolvedId).build());
        itemValues.put(VERSION_FIELD, AttributeValue.builder().n(String.valueOf(((AbstractProcessInstance<?>) instance).getVersionTracker())).build());
        itemValues.put(STATUS_FIELD, AttributeValue.builder().n(String.valueOf(((AbstractProcessInstance<?>) instance).status())).build());
        itemValues.put(CONTENT_FIELD, AttributeValue.builder().b(SdkBytes.fromByteArray(data)).build());
        itemValues.put(START_DATE_FIELD, AttributeValue.builder().s(DateTimeFormatter.ISO_INSTANT.format(instance.startDate().toInstant())).build());
        Collection<String> tags = new ArrayList(instance.tags().values());
        tags.add(resolvedId);
        if (instance.businessKey() != null) {
            tags.add(instance.businessKey());
        }
        itemValues.put(TAGS_FIELD, AttributeValue.builder().ss(tags).build());
        PutItemRequest request = PutItemRequest.builder().tableName(tableName).conditionExpression("attribute_not_exists(" + INSTANCE_ID_FIELD + ")").item(itemValues).build();
        try {
            dynamodb.putItem(request);
            Supplier<AuditEntry> entry = () -> BaseAuditEntry.persitenceWrite(instance).add("message", "Workflow instance created in the DynamoDB based data store");
            auditor.publish(entry);
        } catch (ConditionalCheckFailedException e) {
            throw new ProcessInstanceDuplicatedException(id);
        } finally {
            cachedInstances.remove(resolvedId);
            cachedInstances.remove(id);
            disconnect(instance);
        }
    } else if (isPending(instance)) {
        if (cachedInstances.putIfAbsent(resolvedId, instance) != null) {
            throw new ProcessInstanceDuplicatedException(id);
        }
    } else {
        cachedInstances.remove(resolvedId);
        cachedInstances.remove(id);
    }
}
Also used : AbstractProcessInstance(io.automatiko.engine.workflow.AbstractProcessInstance) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ProcessInstanceDuplicatedException(io.automatiko.engine.api.workflow.ProcessInstanceDuplicatedException) AuditEntry(io.automatiko.engine.api.audit.AuditEntry) BaseAuditEntry(io.automatiko.engine.workflow.audit.BaseAuditEntry) PutItemRequest(software.amazon.awssdk.services.dynamodb.model.PutItemRequest) ConditionalCheckFailedException(software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException)

Example 13 with ConditionalCheckFailedException

use of software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException in project para by Erudika.

the class AWSDynamoDAO method updateRow.

private boolean updateRow(String key, String appid, Map<String, AttributeValue> row) {
    if (StringUtils.isBlank(key) || StringUtils.isBlank(appid) || row == null || row.isEmpty()) {
        return false;
    }
    String table = getTableNameForAppid(appid);
    try {
        UpdateItemRequest.Builder updateRequest = UpdateItemRequest.builder();
        StringBuilder updateExpression = new StringBuilder("SET ");
        Map<String, String> names = new HashMap<>(row.size() + 1);
        Map<String, AttributeValue> values = new HashMap<>(row.size() + 1);
        boolean isLockingEnabledForRow = false;
        // ignore the version field here
        AttributeValue version = row.remove(Config._VERSION);
        if (version == null || version.n() == null) {
            version = AttributeValue.builder().n("0").build();
        }
        if (Long.parseLong(version.n()) > 0L) {
            isLockingEnabledForRow = true;
        }
        for (Entry<String, AttributeValue> attr : row.entrySet()) {
            String name = "#" + attr.getKey();
            String value = ":" + attr.getKey();
            updateExpression.append(name).append("=").append(value).append(",");
            names.put(name, attr.getKey());
            values.put(value, attr.getValue());
        }
        // remove comma at the end
        updateExpression.setLength(updateExpression.length() - 1);
        if (isLockingEnabledForRow) {
            names.put("#" + Config._VERSION, Config._VERSION);
            values.put(":" + Config._VERSION, version);
            values.put(":plusOne", AttributeValue.builder().n("1").build());
            updateRequest.conditionExpression("#" + Config._VERSION + " = :" + Config._VERSION);
            updateExpression.append(" ADD #").append(Config._VERSION).append(" :plusOne");
        }
        updateRequest.tableName(table);
        updateRequest.key(rowKey(key, appid));
        updateRequest.expressionAttributeNames(names);
        updateRequest.expressionAttributeValues(values);
        updateRequest.updateExpression(updateExpression.toString());
        client().updateItem(updateRequest.build());
        return true;
    } catch (ConditionalCheckFailedException ex) {
        logger.warn("Item not updated - versions don't match. table={}, appid={}, key={}.", table, appid, key);
    } catch (Exception e) {
        logger.error("Could not update row in DB - table={}, appid={}, key={}:", table, appid, key, e);
        throwIfNecessary(e);
    }
    return false;
}
Also used : UpdateItemRequest(software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ConditionalCheckFailedException(software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException) ConditionalCheckFailedException(software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException)

Example 14 with ConditionalCheckFailedException

use of software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException in project Signal-Server by signalapp.

the class IssuedReceiptsManager method recordIssuance.

/**
 * Returns a future that completes normally if either this stripe item was never issued a receipt credential
 * previously OR if it was issued a receipt credential previously for the exact same receipt credential request
 * enabling clients to retry in case they missed the original response.
 *
 * If this stripe item has already been used to issue another receipt, throws a 409 conflict web application
 * exception.
 *
 * Stripe item is expected to refer to an invoice line item (subscriptions) or a payment intent (one-time).
 */
public CompletableFuture<Void> recordIssuance(String stripeId, ReceiptCredentialRequest request, Instant now) {
    UpdateItemRequest updateItemRequest = UpdateItemRequest.builder().tableName(table).key(Map.of(KEY_STRIPE_ID, s(stripeId))).conditionExpression("attribute_not_exists(#key) OR #tag = :tag").returnValues(ReturnValue.NONE).updateExpression("SET " + "#tag = if_not_exists(#tag, :tag), " + "#exp = if_not_exists(#exp, :exp)").expressionAttributeNames(Map.of("#key", KEY_STRIPE_ID, "#tag", KEY_ISSUED_RECEIPT_TAG, "#exp", KEY_EXPIRATION)).expressionAttributeValues(Map.of(":tag", b(generateIssuedReceiptTag(request)), ":exp", n(now.plus(expiration).getEpochSecond()))).build();
    return dynamoDbAsyncClient.updateItem(updateItemRequest).handle((updateItemResponse, throwable) -> {
        if (throwable != null) {
            Throwable rootCause = Throwables.getRootCause(throwable);
            if (rootCause instanceof ConditionalCheckFailedException) {
                throw new ClientErrorException(Status.CONFLICT, rootCause);
            }
            Throwables.throwIfUnchecked(throwable);
            throw new CompletionException(throwable);
        }
        return null;
    });
}
Also used : UpdateItemRequest(software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest) CompletionException(java.util.concurrent.CompletionException) ClientErrorException(javax.ws.rs.ClientErrorException) ConditionalCheckFailedException(software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException)

Example 15 with ConditionalCheckFailedException

use of software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException in project Signal-Server by signalapp.

the class SubscriptionManager method create.

public CompletableFuture<Record> create(byte[] user, byte[] password, String customerId, Instant createdAt) {
    checkUserLength(user);
    UpdateItemRequest request = UpdateItemRequest.builder().tableName(table).key(Map.of(KEY_USER, b(user))).returnValues(ReturnValue.ALL_NEW).conditionExpression("attribute_not_exists(#user) OR #password = :password").updateExpression("SET " + "#password = if_not_exists(#password, :password), " + "#customer_id = if_not_exists(#customer_id, :customer_id), " + "#created_at = if_not_exists(#created_at, :created_at), " + "#accessed_at = if_not_exists(#accessed_at, :accessed_at)").expressionAttributeNames(Map.of("#user", KEY_USER, "#password", KEY_PASSWORD, "#customer_id", KEY_CUSTOMER_ID, "#created_at", KEY_CREATED_AT, "#accessed_at", KEY_ACCESSED_AT)).expressionAttributeValues(Map.of(":password", b(password), ":customer_id", s(customerId), ":created_at", n(createdAt.getEpochSecond()), ":accessed_at", n(createdAt.getEpochSecond()))).build();
    return client.updateItem(request).handle((updateItemResponse, throwable) -> {
        if (throwable != null) {
            if (Throwables.getRootCause(throwable) instanceof ConditionalCheckFailedException) {
                return null;
            }
            Throwables.throwIfUnchecked(throwable);
            throw new CompletionException(throwable);
        }
        return Record.from(user, updateItemResponse.attributes());
    });
}
Also used : UpdateItemRequest(software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest) CompletionException(java.util.concurrent.CompletionException) ConditionalCheckFailedException(software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException)

Aggregations

ConditionalCheckFailedException (software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException)20 AttributeValue (software.amazon.awssdk.services.dynamodb.model.AttributeValue)14 UpdateItemRequest (software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest)8 HashMap (java.util.HashMap)7 GetItemResponse (software.amazon.awssdk.services.dynamodb.model.GetItemResponse)3 PutItemRequest (software.amazon.awssdk.services.dynamodb.model.PutItemRequest)3 Delete (com.scalar.db.api.Delete)2 Put (com.scalar.db.api.Put)2 TableMetadata (com.scalar.db.api.TableMetadata)2 ExecutionException (com.scalar.db.exception.storage.ExecutionException)2 NoMutationException (com.scalar.db.exception.storage.NoMutationException)2 RetriableExecutionException (com.scalar.db.exception.storage.RetriableExecutionException)2 AuditEntry (io.automatiko.engine.api.audit.AuditEntry)2 AbstractProcessInstance (io.automatiko.engine.workflow.AbstractProcessInstance)2 BaseAuditEntry (io.automatiko.engine.workflow.audit.BaseAuditEntry)2 Instant (java.time.Instant)2 ArrayList (java.util.ArrayList)2 CompletionException (java.util.concurrent.CompletionException)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 Nonnull (javax.annotation.Nonnull)2