use of org.eclipse.hono.service.base.jdbc.store.OptimisticLockingException in project hono by eclipse.
the class TableManagementStore method extractVersionForUpdate.
private static Future<String> extractVersionForUpdate(final ResultSet device, final Optional<String> resourceVersion) {
final Optional<String> version = device.getRows(true).stream().map(o -> o.getString("version")).findAny();
if (version.isEmpty()) {
log.debug("No version or no row found -> entity not found");
return Future.failedFuture(new EntityNotFoundException());
}
final var currentVersion = version.get();
return resourceVersion.<// if we expect a certain version
Future<String>>map(expected -> {
// check ...
if (expected.equals(currentVersion)) {
// version matches, continue with current version
return Future.succeededFuture(currentVersion);
} else {
// version does not match, abort
return Future.failedFuture(new OptimisticLockingException());
}
}).orElseGet(() -> Future.succeededFuture(currentVersion));
}
use of org.eclipse.hono.service.base.jdbc.store.OptimisticLockingException in project hono by eclipse.
the class TableManagementStore method setCredentials.
/**
* Set all credentials for a device.
* <p>
* This will set/update all credentials of the device. If the device does not exist, the result
* will be {@code false}. If the update was successful, then the result will be {@code true}.
* If the resource version was provided, but the provided version was no longer the current version,
* then the future will fail with a {@link OptimisticLockingException}.
*
* @param key The key of the device to update.
* @param credentials The credentials to set.
* @param resourceVersion The optional resource version to update.
* @param spanContext The span to contribute to.
* @return A future, tracking the outcome of the operation.
*/
public Future<Versioned<Boolean>> setCredentials(final DeviceKey key, final List<CommonCredential> credentials, final Optional<String> resourceVersion, final SpanContext spanContext) {
final Span span = TracingHelper.buildChildSpan(this.tracer, spanContext, "set credentials", getClass().getSimpleName()).withTag(TracingHelper.TAG_TENANT_ID, key.getTenantId()).withTag(TracingHelper.TAG_DEVICE_ID, key.getDeviceId()).withTag("num_credentials", credentials.size()).start();
resourceVersion.ifPresent(version -> span.setTag("version", version));
final String nextVersion = UUID.randomUUID().toString();
return SQL.runTransactionally(this.client, this.tracer, span.context(), (connection, context) -> readDeviceForUpdate(connection, key, context).compose(result -> extractVersionForUpdate(result, resourceVersion)).compose(version -> Future.succeededFuture().compose(x -> {
final Promise<CredentialsDto> result = Promise.promise();
final var updatedCredentialsDto = CredentialsDto.forUpdate(key.getTenantId(), key.getDeviceId(), credentials, nextVersion);
if (updatedCredentialsDto.requiresMerging()) {
getCredentialsDto(key, connection, span).map(updatedCredentialsDto::merge).onComplete(result);
} else {
// simply replace the existing credentials with the
// updated ones provided by the client
result.complete(updatedCredentialsDto);
}
return result.future();
}).compose(updatedCredentials -> this.deleteAllCredentialsStatement.expand(map -> {
map.put("tenant_id", key.getTenantId());
map.put("device_id", key.getDeviceId());
}).trace(this.tracer, span.context()).update(connection).map(updatedCredentials)).compose(updatedCredentials -> {
updatedCredentials.createMissingSecretIds();
return CompositeFuture.all(updatedCredentials.getData().stream().map(JsonObject::mapFrom).filter(c -> c.containsKey("type") && c.containsKey("auth-id")).map(c -> this.insertCredentialEntryStatement.expand(map -> {
map.put("tenant_id", key.getTenantId());
map.put("device_id", key.getDeviceId());
map.put("type", c.getString("type"));
map.put("auth_id", c.getString("auth-id"));
map.put("data", c.toString());
}).trace(this.tracer, span.context()).update(connection)).collect(Collectors.toList())).mapEmpty();
}).compose(x -> this.updateDeviceVersionStatement.expand(map -> {
map.put("tenant_id", key.getTenantId());
map.put("device_id", key.getDeviceId());
map.put("expected_version", version);
map.put("next_version", nextVersion);
}).trace(this.tracer, span.context()).update(connection).compose(TableManagementStore::checkUpdateOutcome)).map(true))).recover(err -> recoverNotFound(span, err, () -> false)).map(ok -> new Versioned<>(nextVersion, ok)).onComplete(x -> span.finish());
}
Aggregations