Search in sources :

Example 1 with OptimisticLockingException

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));
}
Also used : SQL(org.eclipse.hono.service.base.jdbc.store.SQL) Json(io.vertx.core.json.Json) JdbcBasedDeviceDto(org.eclipse.hono.service.base.jdbc.store.model.JdbcBasedDeviceDto) LoggerFactory(org.slf4j.LoggerFactory) Supplier(java.util.function.Supplier) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Statement(org.eclipse.hono.service.base.jdbc.store.Statement) HashSet(java.util.HashSet) CompositeFuture(io.vertx.core.CompositeFuture) Versioned(org.eclipse.hono.deviceregistry.util.Versioned) Map(java.util.Map) Fields(io.opentracing.log.Fields) JsonObject(io.vertx.core.json.JsonObject) TracingHelper(org.eclipse.hono.tracing.TracingHelper) Device(org.eclipse.hono.service.management.device.Device) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Timestamp(java.sql.Timestamp) Promise(io.vertx.core.Promise) Set(java.util.Set) DeviceKey(org.eclipse.hono.deviceregistry.service.device.DeviceKey) OptimisticLockingException(org.eclipse.hono.service.base.jdbc.store.OptimisticLockingException) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) List(java.util.List) CommonCredential(org.eclipse.hono.service.management.credentials.CommonCredential) JDBCClient(io.vertx.ext.jdbc.JDBCClient) CredentialsDto(org.eclipse.hono.service.management.credentials.CredentialsDto) UpdateResult(io.vertx.ext.sql.UpdateResult) EntityNotFoundException(org.eclipse.hono.service.base.jdbc.store.EntityNotFoundException) ResultSet(io.vertx.ext.sql.ResultSet) SQLConnection(io.vertx.ext.sql.SQLConnection) Optional(java.util.Optional) Span(io.opentracing.Span) DeviceRegistryUtils(org.eclipse.hono.deviceregistry.util.DeviceRegistryUtils) Collections(java.util.Collections) StatementConfiguration(org.eclipse.hono.service.base.jdbc.store.StatementConfiguration) OptimisticLockingException(org.eclipse.hono.service.base.jdbc.store.OptimisticLockingException) EntityNotFoundException(org.eclipse.hono.service.base.jdbc.store.EntityNotFoundException)

Example 2 with OptimisticLockingException

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());
}
Also used : SQL(org.eclipse.hono.service.base.jdbc.store.SQL) Json(io.vertx.core.json.Json) JdbcBasedDeviceDto(org.eclipse.hono.service.base.jdbc.store.model.JdbcBasedDeviceDto) LoggerFactory(org.slf4j.LoggerFactory) Supplier(java.util.function.Supplier) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Statement(org.eclipse.hono.service.base.jdbc.store.Statement) HashSet(java.util.HashSet) CompositeFuture(io.vertx.core.CompositeFuture) Versioned(org.eclipse.hono.deviceregistry.util.Versioned) Map(java.util.Map) Fields(io.opentracing.log.Fields) JsonObject(io.vertx.core.json.JsonObject) TracingHelper(org.eclipse.hono.tracing.TracingHelper) Device(org.eclipse.hono.service.management.device.Device) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Timestamp(java.sql.Timestamp) Promise(io.vertx.core.Promise) Set(java.util.Set) DeviceKey(org.eclipse.hono.deviceregistry.service.device.DeviceKey) OptimisticLockingException(org.eclipse.hono.service.base.jdbc.store.OptimisticLockingException) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) List(java.util.List) CommonCredential(org.eclipse.hono.service.management.credentials.CommonCredential) JDBCClient(io.vertx.ext.jdbc.JDBCClient) CredentialsDto(org.eclipse.hono.service.management.credentials.CredentialsDto) UpdateResult(io.vertx.ext.sql.UpdateResult) EntityNotFoundException(org.eclipse.hono.service.base.jdbc.store.EntityNotFoundException) ResultSet(io.vertx.ext.sql.ResultSet) SQLConnection(io.vertx.ext.sql.SQLConnection) Optional(java.util.Optional) Span(io.opentracing.Span) DeviceRegistryUtils(org.eclipse.hono.deviceregistry.util.DeviceRegistryUtils) Collections(java.util.Collections) StatementConfiguration(org.eclipse.hono.service.base.jdbc.store.StatementConfiguration) Promise(io.vertx.core.Promise) Versioned(org.eclipse.hono.deviceregistry.util.Versioned) JsonObject(io.vertx.core.json.JsonObject) Span(io.opentracing.Span)

Aggregations

Span (io.opentracing.Span)2 SpanContext (io.opentracing.SpanContext)2 Tracer (io.opentracing.Tracer)2 Fields (io.opentracing.log.Fields)2 CompositeFuture (io.vertx.core.CompositeFuture)2 Future (io.vertx.core.Future)2 Promise (io.vertx.core.Promise)2 Json (io.vertx.core.json.Json)2 JsonObject (io.vertx.core.json.JsonObject)2 JDBCClient (io.vertx.ext.jdbc.JDBCClient)2 ResultSet (io.vertx.ext.sql.ResultSet)2 SQLConnection (io.vertx.ext.sql.SQLConnection)2 UpdateResult (io.vertx.ext.sql.UpdateResult)2 Timestamp (java.sql.Timestamp)2 Collections (java.util.Collections)2 HashSet (java.util.HashSet)2 List (java.util.List)2 Map (java.util.Map)2 Objects (java.util.Objects)2 Optional (java.util.Optional)2