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);
}
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);
}
}
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;
}
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;
});
}
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());
});
}
Aggregations