Search in sources :

Example 41 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class HonoConnectionImpl method createReceiver.

@Override
public Future<ProtonReceiver> createReceiver(final String sourceAddress, final ProtonQoS qos, final ProtonMessageHandler messageHandler, final int preFetchSize, final boolean autoAccept, final Handler<String> remoteCloseHook) {
    Objects.requireNonNull(sourceAddress);
    Objects.requireNonNull(qos);
    Objects.requireNonNull(messageHandler);
    if (preFetchSize < 0) {
        throw new IllegalArgumentException("pre-fetch size must be >= 0");
    }
    return executeOnContext(result -> {
        checkConnected().compose(v -> {
            final Promise<ProtonReceiver> receiverPromise = Promise.promise();
            final ProtonReceiver receiver = session.createReceiver(sourceAddress);
            if (clientConfigProperties.getMaxMessageSize() > ClientConfigProperties.MAX_MESSAGE_SIZE_UNLIMITED) {
                receiver.setMaxMessageSize(new UnsignedLong(clientConfigProperties.getMaxMessageSize()));
            }
            receiver.setAutoAccept(autoAccept);
            receiver.setQoS(qos);
            receiver.setPrefetch(preFetchSize);
            receiver.handler((delivery, message) -> {
                HonoProtonHelper.onReceivedMessageDeliveryUpdatedFromRemote(delivery, d -> log.debug("got unexpected disposition update for received message [remote state: {}]", delivery.getRemoteState()));
                try {
                    messageHandler.handle(delivery, message);
                    if (log.isTraceEnabled()) {
                        final int remainingCredits = receiver.getCredit() - receiver.getQueued();
                        log.trace("handling message [remotely settled: {}, queued messages: {}, remaining credit: {}]", delivery.remotelySettled(), receiver.getQueued(), remainingCredits);
                    }
                } catch (final Exception ex) {
                    log.warn("error handling message", ex);
                    ProtonHelper.released(delivery, true);
                }
            });
            final DisconnectListener<HonoConnection> disconnectBeforeOpenListener = (con) -> {
                log.debug("opening receiver [{}] failed: got disconnected", sourceAddress);
                receiverPromise.tryFail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE, "not connected"));
            };
            oneTimeDisconnectListeners.add(disconnectBeforeOpenListener);
            receiver.openHandler(recvOpen -> {
                oneTimeDisconnectListeners.remove(disconnectBeforeOpenListener);
                // the result future may have already been completed here in case of a link establishment timeout
                if (receiverPromise.future().isComplete()) {
                    log.debug("ignoring server response for opening receiver [{}]: receiver creation already timed out", sourceAddress);
                } else if (recvOpen.failed()) {
                    // this means that we have received the peer's attach
                    // and the subsequent detach frame in one TCP read
                    final ErrorCondition error = receiver.getRemoteCondition();
                    if (error == null) {
                        log.debug("opening receiver [{}] failed", sourceAddress, recvOpen.cause());
                        receiverPromise.tryFail(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND, "cannot open receiver", recvOpen.cause()));
                    } else {
                        log.debug("opening receiver [{}] failed: {} - {}", sourceAddress, error.getCondition(), error.getDescription());
                        receiverPromise.tryFail(StatusCodeMapper.fromAttachError(error));
                    }
                } else if (HonoProtonHelper.isLinkEstablished(receiver)) {
                    log.debug("receiver open [source: {}]", sourceAddress);
                    receiverPromise.tryComplete(recvOpen.result());
                } else {
                    // this means that the peer did not create a local terminus for the link
                    // and will send a detach frame for closing the link very shortly
                    // see AMQP 1.0 spec section 2.6.3
                    log.debug("peer did not create terminus for source [{}] and will detach the link", sourceAddress);
                    receiverPromise.tryFail(new ServerErrorException(HttpURLConnection.HTTP_UNAVAILABLE));
                }
            });
            HonoProtonHelper.setDetachHandler(receiver, remoteDetached -> onRemoteDetach(receiver, connection.getRemoteContainer(), false, remoteCloseHook));
            HonoProtonHelper.setCloseHandler(receiver, remoteClosed -> onRemoteDetach(receiver, connection.getRemoteContainer(), true, remoteCloseHook));
            receiver.open();
            vertx.setTimer(clientConfigProperties.getLinkEstablishmentTimeout(), tid -> {
                final boolean notOpenedAndNotDisconnectedYet = oneTimeDisconnectListeners.remove(disconnectBeforeOpenListener);
                if (notOpenedAndNotDisconnectedYet) {
                    onLinkEstablishmentTimeout(receiver, clientConfigProperties, receiverPromise);
                }
            });
            return receiverPromise.future();
        }).onComplete(result);
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) Arrays(java.util.Arrays) LoggerFactory(org.slf4j.LoggerFactory) Context(io.vertx.core.Context) HonoProtonHelper(org.eclipse.hono.util.HonoProtonHelper) ConnectionFactory(org.eclipse.hono.connection.ConnectionFactory) SaslSystemException(io.vertx.proton.sasl.SaslSystemException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) DisconnectListener(org.eclipse.hono.client.DisconnectListener) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) MechanismMismatchException(io.vertx.proton.sasl.MechanismMismatchException) ProtonQoS(io.vertx.proton.ProtonQoS) UUID(java.util.UUID) Future(io.vertx.core.Future) Objects(java.util.Objects) CountDownLatch(java.util.concurrent.CountDownLatch) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ReconnectListener(org.eclipse.hono.client.ReconnectListener) List(java.util.List) SSLException(javax.net.ssl.SSLException) Optional(java.util.Optional) ProtonSender(io.vertx.proton.ProtonSender) AuthenticationException(javax.security.sasl.AuthenticationException) ProtonLink(io.vertx.proton.ProtonLink) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Constants(org.eclipse.hono.util.Constants) ArrayList(java.util.ArrayList) ProtonSession(io.vertx.proton.ProtonSession) ProtonClientOptions(io.vertx.proton.ProtonClientOptions) Symbol(org.apache.qpid.proton.amqp.Symbol) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) AsyncResult(io.vertx.core.AsyncResult) HonoConnection(org.eclipse.hono.client.HonoConnection) Logger(org.slf4j.Logger) VertxInternal(io.vertx.core.impl.VertxInternal) Iterator(java.util.Iterator) Tracer(io.opentracing.Tracer) NoopTracerFactory(io.opentracing.noop.NoopTracerFactory) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) TimeUnit(java.util.concurrent.TimeUnit) Handler(io.vertx.core.Handler) Collections(java.util.Collections) ProtonReceiver(io.vertx.proton.ProtonReceiver) Promise(io.vertx.core.Promise) DisconnectListener(org.eclipse.hono.client.DisconnectListener) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServerErrorException(org.eclipse.hono.client.ServerErrorException) SaslSystemException(io.vertx.proton.sasl.SaslSystemException) MechanismMismatchException(io.vertx.proton.sasl.MechanismMismatchException) SSLException(javax.net.ssl.SSLException) AuthenticationException(javax.security.sasl.AuthenticationException) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) ServerErrorException(org.eclipse.hono.client.ServerErrorException)

Example 42 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class GenericSenderLink method sendMessageAndWaitForOutcome.

private Future<ProtonDelivery> sendMessageAndWaitForOutcome(final Message message, final Span currentSpan, final boolean mapUnacceptedOutcomeToErrorResult) {
    Objects.requireNonNull(message);
    Objects.requireNonNull(currentSpan);
    final AtomicReference<ProtonDelivery> deliveryRef = new AtomicReference<>();
    final Promise<ProtonDelivery> result = Promise.promise();
    final String messageId = String.format("%s-%d", getClass().getSimpleName(), MESSAGE_COUNTER.getAndIncrement());
    message.setMessageId(messageId);
    logMessageIdAndSenderInfo(currentSpan, messageId);
    final SendMessageSampler.Sample sample = sampler.start(tenantId);
    final ClientConfigProperties config = connection.getConfig();
    final Long timerId = config.getSendMessageTimeout() > 0 ? connection.getVertx().setTimer(config.getSendMessageTimeout(), id -> {
        if (!result.future().isComplete()) {
            handleSendMessageTimeout(message, config.getSendMessageTimeout(), deliveryRef.get(), sample, result, null);
        }
    }) : null;
    deliveryRef.set(sender.send(message, deliveryUpdated -> {
        if (timerId != null) {
            connection.getVertx().cancelTimer(timerId);
        }
        final DeliveryState remoteState = deliveryUpdated.getRemoteState();
        if (result.future().isComplete()) {
            log.debug("ignoring received delivery update for message [ID: {}, address: {}]: waiting for the update has already timed out", messageId, getMessageAddress(message));
        } else if (deliveryUpdated.remotelySettled()) {
            logUpdatedDeliveryState(currentSpan, message, deliveryUpdated);
            sample.completed(remoteState);
            if (Accepted.class.isInstance(remoteState)) {
                result.complete(deliveryUpdated);
            } else {
                if (mapUnacceptedOutcomeToErrorResult) {
                    result.handle(mapUnacceptedOutcomeToErrorResult(deliveryUpdated));
                } else {
                    result.complete(deliveryUpdated);
                }
            }
        } else {
            logMessageSendingError("peer did not settle message [ID: {}, address: {}, remote state: {}], failing delivery", messageId, getMessageAddress(message), remoteState.getClass().getSimpleName());
            final ServiceInvocationException e = new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR, "peer did not settle message, failing delivery");
            result.fail(e);
        }
    }));
    log.trace("sent AT_LEAST_ONCE message [ID: {}, address: {}], remaining credit: {}, queued messages: {}", messageId, getMessageAddress(message), sender.getCredit(), sender.getQueued());
    return result.future().onSuccess(delivery -> Tags.HTTP_STATUS.set(currentSpan, HttpURLConnection.HTTP_ACCEPTED)).onFailure(t -> {
        TracingHelper.logError(currentSpan, t);
        Tags.HTTP_STATUS.set(currentSpan, ServiceInvocationException.extractStatusCode(t));
    }).onComplete(r -> currentSpan.finish());
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonDelivery(io.vertx.proton.ProtonDelivery) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) Tags(io.opentracing.tag.Tags) NoConsumerException(org.eclipse.hono.client.NoConsumerException) HonoProtonHelper(org.eclipse.hono.util.HonoProtonHelper) MessageUndeliverableException(org.eclipse.hono.client.MessageUndeliverableException) Modified(org.apache.qpid.proton.amqp.messaging.Modified) StatusCodeMapper(org.eclipse.hono.client.StatusCodeMapper) Map(java.util.Map) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) Message(org.apache.qpid.proton.message.Message) Fields(io.opentracing.log.Fields) TracingHelper(org.eclipse.hono.tracing.TracingHelper) HonoConnection(org.eclipse.hono.client.HonoConnection) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) Logger(org.slf4j.Logger) Promise(io.vertx.core.Promise) AddressHelper(org.eclipse.hono.util.AddressHelper) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) ProtonQoS(io.vertx.proton.ProtonQoS) MessageHelper(org.eclipse.hono.util.MessageHelper) Released(org.apache.qpid.proton.amqp.messaging.Released) Future(io.vertx.core.Future) Objects(java.util.Objects) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Optional(java.util.Optional) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) Span(io.opentracing.Span) ProtonSender(io.vertx.proton.ProtonSender) SendMessageSampler(org.eclipse.hono.client.SendMessageSampler) Handler(io.vertx.core.Handler) Collections(java.util.Collections) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) MessageNotProcessedException(org.eclipse.hono.client.MessageNotProcessedException) ProtonDelivery(io.vertx.proton.ProtonDelivery) AtomicReference(java.util.concurrent.atomic.AtomicReference) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) AtomicLong(java.util.concurrent.atomic.AtomicLong) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) SendMessageSampler(org.eclipse.hono.client.SendMessageSampler)

Example 43 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class MongoDbBasedCredentialServiceTest method testCredentialsDaoUsesIndex.

/**
 * Verifies that the credentials DAO uses a proper index to retrieve credentials by auth-id and type.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testCredentialsDaoUsesIndex(final VertxTestContext ctx) {
    final var tenantId = UUID.randomUUID().toString();
    final MongoClient mongoClient = MongoDbTestUtils.getMongoClient(vertx, DB_NAME);
    final var dto1 = CredentialsDto.forCreation(tenantId, UUID.randomUUID().toString(), List.of(Credentials.createPasswordCredential("device1a", "secret"), Credentials.createPSKCredential("device1b", "shared-secret")), UUID.randomUUID().toString());
    final var dto2 = CredentialsDto.forCreation(tenantId, UUID.randomUUID().toString(), List.of(Credentials.createPasswordCredential("device2a", "secret"), Credentials.createPSKCredential("device2b", "shared-secret")), UUID.randomUUID().toString());
    final var dto3 = CredentialsDto.forCreation(tenantId, UUID.randomUUID().toString(), List.of(Credentials.createPasswordCredential("device3a", "secret"), Credentials.createPSKCredential("device3b", "shared-secret")), UUID.randomUUID().toString());
    final var dto4 = CredentialsDto.forCreation(UUID.randomUUID().toString(), UUID.randomUUID().toString(), List.of(Credentials.createPasswordCredential("device1a", "secret"), Credentials.createPSKCredential("device1b", "shared-secret")), UUID.randomUUID().toString());
    credentialsDao.create(dto1, NoopSpan.INSTANCE.context()).compose(ok -> credentialsDao.create(dto2, NoopSpan.INSTANCE.context())).compose(ok -> credentialsDao.create(dto3, NoopSpan.INSTANCE.context())).compose(ok -> credentialsDao.create(dto4, NoopSpan.INSTANCE.context())).compose(ok -> {
        final Promise<JsonObject> resultHandler = Promise.promise();
        final var filter = MongoDbDocumentBuilder.builder().withTenantId(tenantId).withAuthId("device1a").withType(CredentialsConstants.SECRETS_TYPE_HASHED_PASSWORD).document();
        final var commandRight = new JsonObject().put("find", "credentials").put("batchSize", 1).put("singleBatch", true).put("filter", filter).put("projection", MongoDbBasedCredentialsDao.PROJECTION_CREDS_BY_TYPE_AND_AUTH_ID);
        final var explain = new JsonObject().put("explain", commandRight).put("verbosity", "executionStats");
        mongoClient.runCommand("explain", explain, resultHandler);
        return resultHandler.future();
    }).onComplete(ctx.succeeding(result -> {
        if (LOG.isTraceEnabled()) {
            LOG.trace("result:{}{}", System.lineSeparator(), result.encodePrettily());
        }
        ctx.verify(() -> {
            final var indexScan = (JsonObject) JsonPointer.from("/queryPlanner/winningPlan/inputStage/inputStage").queryJson(result);
            assertThat(indexScan.getString("indexName")).isEqualTo(MongoDbBasedCredentialsDao.IDX_CREDENTIALS_TYPE_AND_AUTH_ID);
            final var executionStats = result.getJsonObject("executionStats", new JsonObject());
            // there are two credentials with auth-id "device1a" and type "hashed-password"
            assertThat(executionStats.getInteger("totalKeysExamined")).isEqualTo(2);
            assertThat(executionStats.getInteger("totalDocsExamined")).isEqualTo(2);
        });
        ctx.completeNow();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) BeforeEach(org.junit.jupiter.api.BeforeEach) CredentialsManagementService(org.eclipse.hono.service.management.credentials.CredentialsManagementService) LoggerFactory(org.slf4j.LoggerFactory) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Timeout(io.vertx.junit5.Timeout) AfterAll(org.junit.jupiter.api.AfterAll) TestInstance(org.junit.jupiter.api.TestInstance) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) BeforeAll(org.junit.jupiter.api.BeforeAll) JsonObject(io.vertx.core.json.JsonObject) TenantInformationService(org.eclipse.hono.deviceregistry.service.tenant.TenantInformationService) MongoClient(io.vertx.ext.mongo.MongoClient) MongoDbBasedRegistrationConfigProperties(org.eclipse.hono.deviceregistry.mongodb.config.MongoDbBasedRegistrationConfigProperties) UUID(java.util.UUID) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) TestInfo(org.junit.jupiter.api.TestInfo) Test(org.junit.jupiter.api.Test) List(java.util.List) SpringBasedHonoPasswordEncoder(org.eclipse.hono.auth.SpringBasedHonoPasswordEncoder) Optional(java.util.Optional) TenantKey(org.eclipse.hono.deviceregistry.service.tenant.TenantKey) Assertions(org.eclipse.hono.deviceregistry.util.Assertions) OperationResult(org.eclipse.hono.service.management.OperationResult) Checkpoint(io.vertx.junit5.Checkpoint) JsonPointer(io.vertx.core.json.pointer.JsonPointer) Mockito.mock(org.mockito.Mockito.mock) MongoDbDocumentBuilder(org.eclipse.hono.deviceregistry.mongodb.utils.MongoDbDocumentBuilder) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) VertxTestContext(io.vertx.junit5.VertxTestContext) Credentials(org.eclipse.hono.service.management.credentials.Credentials) CredentialsServiceTestBase(org.eclipse.hono.service.credentials.CredentialsServiceTestBase) DeviceManagementService(org.eclipse.hono.service.management.device.DeviceManagementService) CompositeFuture(io.vertx.core.CompositeFuture) MongoDbBasedCredentialsDao(org.eclipse.hono.deviceregistry.mongodb.model.MongoDbBasedCredentialsDao) RegistrationLimits(org.eclipse.hono.service.management.tenant.RegistrationLimits) Logger(org.slf4j.Logger) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) MongoDbBasedCredentialsConfigProperties(org.eclipse.hono.deviceregistry.mongodb.config.MongoDbBasedCredentialsConfigProperties) CredentialsConstants(org.eclipse.hono.util.CredentialsConstants) TimeUnit(java.util.concurrent.TimeUnit) AfterEach(org.junit.jupiter.api.AfterEach) CredentialsDto(org.eclipse.hono.service.management.credentials.CredentialsDto) CredentialsService(org.eclipse.hono.service.credentials.CredentialsService) MongoDbBasedDeviceDao(org.eclipse.hono.deviceregistry.mongodb.model.MongoDbBasedDeviceDao) NoopSpan(io.opentracing.noop.NoopSpan) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) MongoClient(io.vertx.ext.mongo.MongoClient) Promise(io.vertx.core.Promise) JsonObject(io.vertx.core.json.JsonObject) Test(org.junit.jupiter.api.Test)

Example 44 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class MongoDbBasedDao method processSearchResource.

/**
 * Finds resources such as tenant or device from the given MongoDB collection with the provided
 * paging, filtering and sorting options.
 * <p>
 * A MongoDB aggregation pipeline is used to find the resources from the given MongoDB collection.
 *
 * @param pageSize The maximum number of results to include in a response.
 * @param pageOffset The offset into the result set from which to include objects in the response.
 *                   This allows to retrieve the whole result set page by page.
 * @param filterDocument The document used for filtering the resources in a MongoDB aggregation pipeline.
 * @param sortDocument The document used for sorting the resources in a MongoDB aggregation pipeline.
 * @param resultMapper The mapper used for mapping the result for the search operation.
 * @param <T> The type of the result namely {@link org.eclipse.hono.service.management.device.DeviceWithId} or
 *           {@link org.eclipse.hono.service.management.tenant.TenantWithId}
 * @return A future indicating the outcome of the operation. The future will succeed if the search operation
 *         is successful and some resources are found. If no resources are found then the future will fail
 *         with a {@link ClientErrorException} with status {@link HttpURLConnection#HTTP_NOT_FOUND}.
 *         The future will be failed with a {@link ServiceInvocationException} if the query could not be executed.
 * @throws NullPointerException if any of the parameters is {@code null}.
 * @throws IllegalArgumentException if page size is &lt;= 0 or page offset is &lt; 0.
 * @see <a href="https://docs.mongodb.com/manual/core/aggregation-pipeline">MongoDB Aggregation Pipeline</a>
 */
protected <T> Future<SearchResult<T>> processSearchResource(final int pageSize, final int pageOffset, final JsonObject filterDocument, final JsonObject sortDocument, final Function<JsonObject, List<T>> resultMapper) {
    if (pageSize <= 0) {
        throw new IllegalArgumentException("page size must be a positive integer");
    }
    if (pageOffset < 0) {
        throw new IllegalArgumentException("page offset must not be negative");
    }
    Objects.requireNonNull(filterDocument);
    Objects.requireNonNull(sortDocument);
    Objects.requireNonNull(resultMapper);
    final JsonArray aggregationPipelineQuery = getSearchResourceQuery(pageSize, pageOffset, filterDocument, sortDocument);
    final Promise<JsonObject> searchPromise = Promise.promise();
    if (LOG.isTraceEnabled()) {
        LOG.trace("searching resources using aggregation pipeline:{}{}", System.lineSeparator(), aggregationPipelineQuery.encodePrettily());
    }
    mongoClient.aggregate(collectionName, aggregationPipelineQuery).exceptionHandler(searchPromise::fail).handler(searchPromise::complete);
    return searchPromise.future().onSuccess(searchResult -> {
        if (LOG.isTraceEnabled()) {
            LOG.trace("search result:{}{}", System.lineSeparator(), searchResult.encodePrettily());
        }
    }).map(result -> Optional.ofNullable(result.getInteger(RegistryManagementConstants.FIELD_RESULT_SET_SIZE)).filter(total -> total > 0).map(total -> new SearchResult<>(total, resultMapper.apply(result))).orElseThrow(() -> new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND))).recover(this::mapError);
}
Also used : JsonArray(io.vertx.core.json.JsonArray) HttpURLConnection(java.net.HttpURLConnection) LoggerFactory(org.slf4j.LoggerFactory) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) Function(java.util.function.Function) PreDestroy(javax.annotation.PreDestroy) FieldLevelEncryption(org.eclipse.hono.deviceregistry.util.FieldLevelEncryption) SearchResult(org.eclipse.hono.service.management.SearchResult) JsonObject(io.vertx.core.json.JsonObject) AsyncResult(io.vertx.core.AsyncResult) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) MongoException(com.mongodb.MongoException) NoopTracerFactory(io.opentracing.noop.NoopTracerFactory) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) MongoClient(io.vertx.ext.mongo.MongoClient) Future(io.vertx.core.Future) Objects(java.util.Objects) JsonArray(io.vertx.core.json.JsonArray) List(java.util.List) BaseDto(org.eclipse.hono.service.management.BaseDto) IndexOptions(io.vertx.ext.mongo.IndexOptions) Optional(java.util.Optional) Handler(io.vertx.core.Handler) ErrorCategory(com.mongodb.ErrorCategory) JsonObject(io.vertx.core.json.JsonObject) ClientErrorException(org.eclipse.hono.client.ClientErrorException) SearchResult(org.eclipse.hono.service.management.SearchResult)

Example 45 with Promise

use of io.vertx.core.Promise in project hono by eclipse.

the class ClasspathSchemaCreator method runScript.

private Future<Void> runScript(final JdbcProperties jdbcProperties, final String script, final SpanContext ctx) {
    final JDBCClient jdbcClient = JdbcProperties.dataSource(vertx, jdbcProperties);
    final Promise<Void> clientCloseTracker = Promise.promise();
    SQL.runTransactionally(jdbcClient, tracer, ctx, (connection, context) -> {
        final var expanded = Statement.statement(script).expand();
        log.debug("Creating database schema in [{}] with script: {}", jdbcProperties.getUrl(), expanded);
        return expanded.query(jdbcClient).recover(SQL::translateException);
    }).onComplete(ar -> jdbcClient.close(clientCloseTracker));
    return clientCloseTracker.future();
}
Also used : SQL(org.eclipse.hono.service.base.jdbc.store.SQL) JdbcProperties(org.eclipse.hono.service.base.jdbc.config.JdbcProperties) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Promise(io.vertx.core.Promise) LoggerFactory(org.slf4j.LoggerFactory) Vertx(io.vertx.core.Vertx) Future(io.vertx.core.Future) Statement(org.eclipse.hono.service.base.jdbc.store.Statement) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) JDBCClient(io.vertx.ext.jdbc.JDBCClient) Buffer(io.vertx.core.buffer.Buffer) SchemaCreator(org.eclipse.hono.deviceregistry.jdbc.SchemaCreator) Span(io.opentracing.Span) TracingHelper(org.eclipse.hono.tracing.TracingHelper) JDBCClient(io.vertx.ext.jdbc.JDBCClient)

Aggregations

Promise (io.vertx.core.Promise)155 Future (io.vertx.core.Future)122 Handler (io.vertx.core.Handler)95 List (java.util.List)86 Vertx (io.vertx.core.Vertx)85 Buffer (io.vertx.core.buffer.Buffer)83 TimeUnit (java.util.concurrent.TimeUnit)79 HttpURLConnection (java.net.HttpURLConnection)66 Logger (org.slf4j.Logger)63 LoggerFactory (org.slf4j.LoggerFactory)63 Optional (java.util.Optional)62 AsyncResult (io.vertx.core.AsyncResult)61 Truth.assertThat (com.google.common.truth.Truth.assertThat)60 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)60 VertxTestContext (io.vertx.junit5.VertxTestContext)59 Test (org.junit.jupiter.api.Test)58 Map (java.util.Map)54 UUID (java.util.UUID)52 ArrayList (java.util.ArrayList)51 JsonObject (io.vertx.core.json.JsonObject)50