io.vertx.core.CompositeFuture Java Examples

The following examples show how to use io.vertx.core.CompositeFuture. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DelegatingDeviceManagementHttpEndpoint.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
private void doGetDevice(final RoutingContext ctx) {

        final Span span = TracingHelper.buildServerChildSpan(
                tracer,
                TracingHandler.serverSpanContext(ctx),
                SPAN_NAME_GET_DEVICE,
                getClass().getSimpleName()
        ).start();

        final Future<String> tenantId = getRequestParameter(ctx, PARAM_TENANT_ID, getPredicate(config.getTenantIdPattern(), false));
        final Future<String> deviceId = getRequestParameter(ctx, PARAM_DEVICE_ID, getPredicate(config.getDeviceIdPattern(), false));

        CompositeFuture.all(tenantId, deviceId)
            .compose(ok -> {
                logger.debug("retrieving device [tenant: {}, device-id: {}]", tenantId.result(), deviceId.result());
                return getService().readDevice(tenantId.result(), deviceId.result(), span);
            })
            .onSuccess(operationResult -> writeResponse(ctx, operationResult, span))
            .onFailure(t -> failRequest(ctx, t, span))
            .onComplete(s -> span.finish());
    }
 
Example #2
Source File: RegistrationServiceTests.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Helps asserting device data.
 *
 * @param tenant The tenant.
 * @param deviceId The device ID.
 * @param gatewayId The optional gateway ID
 * @param managementAssertions assertions for the management data.
 * @param adapterAssertions assertions for the adapter data.
 * @return A new future that will succeed when the read/get operations succeed and the assertions are valid.
 *         Otherwise the future must fail.
 */
protected Future<?> assertDevice(final String tenant, final String deviceId, final Optional<String> gatewayId,
        final Handler<OperationResult<Device>> managementAssertions,
        final Handler<RegistrationResult> adapterAssertions) {

    // read management data

    final Future<OperationResult<Device>> f1 = getDeviceManagementService()
            .readDevice(tenant, deviceId, NoopSpan.INSTANCE);

    // read adapter data

    final Future<RegistrationResult> f2 = gatewayId
            .map(id -> getRegistrationService().assertRegistration(tenant, deviceId, id))
            .orElseGet(() -> getRegistrationService().assertRegistration(tenant, deviceId));
    return CompositeFuture.all(
            f1.map(r -> {
                managementAssertions.handle(r);
                return null;
            }),
            f2.map(r -> {
                adapterAssertions.handle(r);
                return null;
            }));
}
 
Example #3
Source File: DataLoader.java    From vertx-dataloader with Apache License 2.0 6 votes vote down vote up
/**
 * Requests to load the data with the specified key asynchronously, and returns a future of the resulting value.
 * <p>
 * If batching is enabled (the default), you'll have to call {@link DataLoader#dispatch()} at a later stage to
 * start batch execution. If you forget this call the future will never be completed (unless already completed,
 * and returned from cache).
 *
 * @param key the key to load
 * @return the future of the value
 */
public Future<V> load(K key) {
    Objects.requireNonNull(key, "Key cannot be null");
    Object cacheKey = getCacheKey(key);
    if (loaderOptions.cachingEnabled() && futureCache.containsKey(cacheKey)) {
        return futureCache.get(cacheKey);
    }

    Future<V> future = Future.future();
    if (loaderOptions.batchingEnabled()) {
        loaderQueue.put(key, future);
    } else {
        CompositeFuture compositeFuture = batchLoadFunction.load(Collections.singleton(key));
        if (compositeFuture.succeeded()) {
            future.complete(compositeFuture.result().resultAt(0));
        } else {
            future.fail(compositeFuture.cause());
        }
    }
    if (loaderOptions.cachingEnabled()) {
        futureCache.set(cacheKey, future);
    }
    return future;
}
 
Example #4
Source File: Application.java    From enmasse with Apache License 2.0 6 votes vote down vote up
@Override
protected final Future<?> deployVerticles() {

    return super.deployVerticles().compose(ok -> {

        @SuppressWarnings("rawtypes")
        final List<Future> futures = new LinkedList<>();

        for (final Verticle verticle : this.verticles) {
            log.info("Deploying: {}", verticle);
            final Promise<String> result = Promise.promise();
            getVertx().deployVerticle(verticle, result);
            futures.add(result.future());
        }

        return CompositeFuture.all(futures);

    });

}
 
Example #5
Source File: AbstractNonNamespacedResourceOperator.java    From strimzi-kafka-operator with Apache License 2.0 6 votes vote down vote up
/**
 * Asynchronously deletes the resource with the given {@code name}.
 * @param name The resource to be deleted.
 * @return A future which will be completed on the context thread
 * once the resource has been deleted.
 */
private Future<ReconcileResult<T>> internalDelete(String name) {
    Future<ReconcileResult<T>> watchForDeleteFuture = new ResourceSupport(vertx).selfClosingWatch(operation().withName(name),
        (action, resource) -> {
            if (action == Watcher.Action.DELETED) {
                log.debug("{} {} has been deleted", resourceKind, name);
                return ReconcileResult.deleted();
            } else {
                return null;
            }
        }, operationTimeoutMs);

    Future<Void> deleteFuture = deleteAsync(name);

    return CompositeFuture.join(watchForDeleteFuture, deleteFuture).map(ReconcileResult.deleted());
}
 
Example #6
Source File: OpenAPIHolderImpl.java    From vertx-web with Apache License 2.0 6 votes vote down vote up
private Future<Void> walkAndSolve(JsonObject obj, URI scope) {
  List<JsonObject> candidateRefs = new ArrayList<>();
  Set<URI> refsToSolve = new HashSet<>();
  deepGetAllRefs(obj, candidateRefs);
  if (candidateRefs.isEmpty()) return Future.succeededFuture();

  for (JsonObject ref : candidateRefs) { // Make refs absolutes and check what refs must be solved
    JsonPointer parsedRef = JsonPointer.fromURI(URI.create(ref.getString("$ref")));
    if (!parsedRef.getURIWithoutFragment().isAbsolute()) // Ref not absolute, make it absolute based on scope
      parsedRef = JsonPointer.fromURI(
        URIUtils.replaceFragment(
          resolveRefResolutionURIWithoutFragment(parsedRef.getURIWithoutFragment(), scope),
          parsedRef.toURI().getFragment()
        )
      );
    URI solvedURI = parsedRef.toURI();
    ref.put("$ref", solvedURI.toString()); // Replace ref
    if (!absolutePaths.containsKey(parsedRef.getURIWithoutFragment()))
      refsToSolve.add(parsedRef.getURIWithoutFragment());
  }
  return CompositeFuture
    .all(refsToSolve.stream().map(this::resolveExternalRef).collect(Collectors.toList()))
    .compose(cf -> Future.succeededFuture());
}
 
Example #7
Source File: KafkaAssemblyOperator.java    From strimzi-kafka-operator with Apache License 2.0 6 votes vote down vote up
/**
 * Internal method for deleting PVCs after scale-downs or disk removal from JBOD storage. It gets list of
 * existing and desired PVCs, diffs them and removes those wioch should not exist.
 *
 * @param maybeDeletePvcs   List of existing PVCs
 * @param desiredPvcs       List of PVCs whcih should exist
 * @return
 */
Future<ReconciliationState> persistentClaimDeletion(List<String> maybeDeletePvcs, List<String> desiredPvcs) {
    List<Future> futures = new ArrayList<>();

    maybeDeletePvcs.removeAll(desiredPvcs);

    for (String pvcName : maybeDeletePvcs)  {
        log.debug("{}: Considering PVC {} for deletion", reconciliation, pvcName);

        if (Annotations.booleanAnnotation(pvcOperations.get(namespace, pvcName), AbstractModel.ANNO_STRIMZI_IO_DELETE_CLAIM, false)) {
            log.debug("{}: Deleting PVC {}", reconciliation, pvcName);
            futures.add(pvcOperations.reconcile(namespace, pvcName, null));
        }
    }

    return withVoid(CompositeFuture.all(futures));
}
 
Example #8
Source File: GreetingVerticle.java    From vertx-config with Apache License 2.0 6 votes vote down vote up
@Override
public void start(Promise<Void> future) {
  message = config().getString("message");
  String address = config().getString("address");

  Promise<Void> endpointReady = Promise.promise();
  Promise<Void> updateReady = Promise.promise();

  vertx.eventBus().<JsonObject>consumer(address + "/update")
    .handler(json -> {
      message = json.body().getString("message");
      json.reply("OK");
    })
    .completionHandler(updateReady);

  vertx.eventBus().consumer(address)
    .handler(msg -> msg.reply(message))
    .completionHandler(endpointReady);

  CompositeFuture.all(endpointReady.future(), updateReady.future()).onComplete(x -> future.handle(x.mapEmpty()));
}
 
Example #9
Source File: MongoDbBasedTenantService.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
@Override
public Future<Void> start() {
    // initialize indexes
    return CompositeFuture.all(
            mongoDbCallExecutor.createCollectionIndex(config.getCollectionName(),
                    new JsonObject().put(
                            RegistryManagementConstants.FIELD_PAYLOAD_TENANT_ID, 1),
                    new IndexOptions().unique(true), INDEX_CREATION_MAX_RETRIES),
            // add unique index predicate for tenants with field of trusted-ca inside tenant object
            // to ensure that no tenants have the same trusted-ca but only if trusted-ca exist
            // to to deal with creating/updating tenants containing unique ids.
            mongoDbCallExecutor.createCollectionIndex(config.getCollectionName(),
                    new JsonObject().put(RegistryManagementConstants.FIELD_TENANT + "." +
                            RegistryManagementConstants.FIELD_PAYLOAD_TRUSTED_CA + "." +
                            RegistryManagementConstants.FIELD_PAYLOAD_SUBJECT_DN, 1),
                    new IndexOptions().unique(true)
                            .partialFilterExpression(new JsonObject().put(
                                    RegistryManagementConstants.FIELD_TENANT + "." +
                                            RegistryManagementConstants.FIELD_PAYLOAD_TRUSTED_CA,
                                    new JsonObject().put("$exists", true))),
                    INDEX_CREATION_MAX_RETRIES))
            .map(ok -> null);
}
 
Example #10
Source File: KafkaImpl.java    From strimzi-kafka-operator with Apache License 2.0 6 votes vote down vote up
/**
 * Completes the returned Future on the Vertx event loop
 * with the topic config obtained from the Kafka AdminClient API.
 * The Future completes with a null result a topic with the given {@code topicName} does not exist.
 */
@Override
public Future<TopicMetadata> topicMetadata(TopicName topicName) {
    LOGGER.debug("Getting metadata for topic {}", topicName);
    ConfigResource resource = new ConfigResource(ConfigResource.Type.TOPIC, topicName.toString());
    Future<TopicDescription> topicDescriptionFuture = mapFuture(adminClient.describeTopics(
            singleton(topicName.toString())).values().get(topicName.toString()));
    Future<Config> configFuture = mapFuture(adminClient.describeConfigs(
            singleton(resource)).values().get(resource));
    return CompositeFuture.all(topicDescriptionFuture, configFuture)
    .map(compositeFuture ->
        new TopicMetadata(compositeFuture.resultAt(0), compositeFuture.resultAt(1)))
        .recover(error -> {
            if (error instanceof UnknownTopicOrPartitionException) {
                return Future.succeededFuture(null);
            } else {
                return Future.failedFuture(error);
            }
        });
}
 
Example #11
Source File: SimpleAclOperator.java    From strimzi-kafka-operator with Apache License 2.0 6 votes vote down vote up
/**
 * Update all ACLs for given user.
 * SimpleAclAuthorizer doesn't support modification of existing rules.
 * This class is using Sets to decide which rules need to be added and which need to be deleted.
 * It delagates to {@link #internalCreate internalCreate} and {@link #internalDelete internalDelete} methods for the actual addition or deletion.
 */
protected Future<ReconcileResult<Set<SimpleAclRule>>> internalUpdate(String username, Set<SimpleAclRule> desired, Set<SimpleAclRule> current) {
    Set<SimpleAclRule> toBeDeleted = new HashSet<>(current);
    toBeDeleted.removeAll(desired);

    Set<SimpleAclRule> toBeAdded = new HashSet<>(desired);
    toBeAdded.removeAll(current);

    List<Future> updates = new ArrayList<>(2);
    updates.add(internalDelete(username, toBeDeleted));
    updates.add(internalCreate(username, toBeAdded));

    Promise<ReconcileResult<Set<SimpleAclRule>>> promise = Promise.promise();

    CompositeFuture.all(updates).onComplete(res -> {
        if (res.succeeded())    {
            promise.complete(ReconcileResult.patched(desired));
        } else  {
            log.error("Updating Acl rules for user {} failed", username, res.cause());
            promise.fail(res.cause());
        }
    });

    return promise.future();
}
 
Example #12
Source File: DockerLinksServiceImporter.java    From vertx-service-discovery with Apache License 2.0 6 votes vote down vote up
@Override
public void close(Handler<Void> completionHandler) {
  List<Future> list = new ArrayList<>();
  for (Record record : records) {
    publisher.unpublish(record.getRegistration(),
        v -> list.add(v.succeeded() ? Future.succeededFuture() : Future.failedFuture(v.cause())));
  }

  CompositeFuture.all(list).onComplete(ar -> {
        if (ar.succeeded()) {
          LOGGER.info("Successfully closed the service importer " + this);
        } else {
          LOGGER.error("A failure has been caught while stopping " + this, ar.cause());
        }
        if (completionHandler != null) {
          completionHandler.handle(null);
        }
      }
  );
}
 
Example #13
Source File: SharedGlobalDataRegistry.java    From apiman with Apache License 2.0 6 votes vote down vote up
@Override
public void unregisterClient(Client client, IAsyncResultHandler<Void> resultHandler) {
    String clientIndex = getClientIndex(client);
    objectMap.get(clientIndex, handleSuccessfulResult(resultHandler, oldClientRaw -> {
        Client oldClient = (Client) oldClientRaw;
        if (oldClient == null) {
            Exception ex = new ClientNotFoundException(Messages.i18n.format("InMemoryRegistry.ClientNotFound"));
            resultHandler.handle(AsyncResultImpl.create(ex));
        } else {
            Future<Object> future1 = Future.future();
            Future<Object> future2 = Future.future();

            objectMap.remove(clientIndex, future1.completer());
            objectMap.remove(oldClient.getApiKey(), future2.completer());

            CompositeFuture.all(future1, future2).setHandler(handleCompositeResult(resultHandler));
        }
    }));
}
 
Example #14
Source File: StatefulSetOperator.java    From strimzi-kafka-operator with Apache License 2.0 6 votes vote down vote up
/**
 * Asynchronously perform a rolling update of all the pods in the StatefulSet identified by the given
 * {@code namespace} and {@code name}, returning a Future that will complete when the rolling update
 * is complete. Starting with pod 0, each pod will be deleted and re-created automatically by the ReplicaSet,
 * once the pod has been recreated then given {@code isReady} function will be polled until it returns true,
 * before the process proceeds with the pod with the next higher number.
 * @param sts The StatefulSet
 * @param podNeedsRestart Predicate for deciding whether the pod needs to be restarted.
 * @return A future that completes when any necessary rolling has been completed.
 */
public Future<Void> maybeRollingUpdate(StatefulSet sts, Function<Pod, String> podNeedsRestart) {
    String cluster = sts.getMetadata().getLabels().get(Labels.STRIMZI_CLUSTER_LABEL);
    String namespace = sts.getMetadata().getNamespace();
    Future<Secret> clusterCaKeySecretFuture = secretOperations.getAsync(
            namespace, KafkaResources.clusterCaCertificateSecretName(cluster));
    Future<Secret> coKeySecretFuture = secretOperations.getAsync(
            namespace, ClusterOperator.secretName(cluster));
    return CompositeFuture.join(clusterCaKeySecretFuture, coKeySecretFuture).compose(compositeFuture -> {
        Secret clusterCaKeySecret = compositeFuture.resultAt(0);
        if (clusterCaKeySecret == null) {
            return Future.failedFuture(Util.missingSecretException(namespace, KafkaCluster.clusterCaKeySecretName(cluster)));
        }
        Secret coKeySecret = compositeFuture.resultAt(1);
        if (coKeySecret == null) {
            return Future.failedFuture(Util.missingSecretException(namespace, ClusterOperator.secretName(cluster)));
        }
        return maybeRollingUpdate(sts, podNeedsRestart, clusterCaKeySecret, coKeySecret);
    });
}
 
Example #15
Source File: VertxBasedHealthCheckServer.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Closes the HTTP server exposing the health checks.
 * <p>
 * This method usually does not need to be invoked explicitly because
 * the HTTP server will be closed implicitly when the vert.x instance
 * is closed.
 *
 * @return A Future indicating the outcome of the operation.
 */
@Override
public Future<Void> stop() {
    final Promise<Void> serverStopTracker = Promise.promise();
    if (server != null) {
        LOG.info("closing secure health check HTTP server [{}:{}]", config.getBindAddress(), server.actualPort());
        server.close(serverStopTracker);
    } else {
        serverStopTracker.complete();
    }

    final Promise<Void> insecureServerStopTracker = Promise.promise();
    if (insecureServer != null) {
        LOG.info("closing insecure health check HTTP server [{}:{}]", config.getInsecurePortBindAddress(),
                insecureServer.actualPort());
        insecureServer.close(insecureServerStopTracker);
    } else {
        insecureServerStopTracker.complete();
    }

    return CompositeFuture.all(serverStopTracker.future(), insecureServerStopTracker.future())
            .map(ok -> (Void) null)
            .recover(t -> Future.failedFuture(t));
}
 
Example #16
Source File: DataLoaderTest.java    From vertx-dataloader with Apache License 2.0 6 votes vote down vote up
@Test
public void should_Support_loading_multiple_keys_in_one_call() {
    AtomicBoolean success = new AtomicBoolean();
    DataLoader<Integer, Integer> identityLoader = new DataLoader<>(keys ->
            CompositeFuture.join(keys.stream()
                    .map(Future::succeededFuture)
                    .collect(Collectors.toCollection(ArrayList::new))));

    CompositeFuture futureAll = identityLoader.loadMany(asList(1, 2));
    futureAll.setHandler(rh -> {
        assertThat(rh.result().size(), is(2));
        success.set(rh.succeeded());
    });
    identityLoader.dispatch();
    await().untilAtomic(success, is(true));
    assertThat(futureAll.list(), equalTo(asList(1, 2)));
}
 
Example #17
Source File: AbstractApplication.java    From hono with Eclipse Public License 2.0 6 votes vote down vote up
/**
 * Deploys the service instances.
 *
 * @param maxInstances The number of instances to deploy.
 * @return A future indicating the outcome of the operation. The future will
 *         be succeeded if the service instances have been deployed successfully.
 */
private Future<?> deployServiceVerticles(final int maxInstances) {

    @SuppressWarnings("rawtypes")
    final List<Future> deploymentTracker = new ArrayList<>();

    for (final ObjectFactory<? extends AbstractServiceBase<?>> serviceFactory : serviceFactories) {

        for (int i = 1; i <= maxInstances; i++) {
            final Promise<String> deployPromise = Promise.promise();
            final AbstractServiceBase<?> serviceInstance = serviceFactory.getObject();
            preDeploy(serviceInstance);
            log.debug("deploying service instance #{} [type: {}]", i, serviceInstance.getClass().getName());
            getVertx().deployVerticle(serviceInstance, deployPromise);
            deploymentTracker.add(deployPromise.future().map(id -> {
                postDeploy(serviceInstance);
                return id;
            }));
        }
    }

    return CompositeFuture.all(deploymentTracker);
}
 
Example #18
Source File: DataLoader.java    From vertx-dataloader with Apache License 2.0 6 votes vote down vote up
/**
 * Dispatches the queued load requests to the batch execution function and returns a composite future of the result.
 * <p>
 * If batching is disabled, or there are no queued requests, then a succeeded composite future is returned.
 *
 * @return the composite future of the queued load requests
 */
public CompositeFuture dispatch() {
    if (!loaderOptions.batchingEnabled() || loaderQueue.size() == 0) {
        return CompositeFuture.join(Collections.emptyList());
    }
    CompositeFuture batch = batchLoadFunction.load(loaderQueue.keySet());
    dispatchedQueues.put(batch, new LinkedHashMap<>(loaderQueue));
    batch.setHandler(rh -> {
        AtomicInteger index = new AtomicInteger(0);
        dispatchedQueues.get(batch).forEach((key, future) -> {
            if (batch.succeeded(index.get())) {
                future.complete(batch.resultAt(index.get()));
            } else {
                future.fail(batch.cause(index.get()));
            }
            index.incrementAndGet();
        });
        dispatchedQueues.remove(batch);
    });
    loaderQueue.clear();
    return batch;
}
 
Example #19
Source File: PreBidRequestContextFactory.java    From prebid-server-java with Apache License 2.0 6 votes vote down vote up
private Future<List<AdapterRequest>> extractBidders(PreBidRequest preBidRequest, Timeout timeout) {
    // this is a List<Future<Stream<AdUnitBid>>> actually
    final List<Future> adUnitBidFutures = preBidRequest.getAdUnits().stream()
            .filter(PreBidRequestContextFactory::isValidAdUnit)
            .map(unit -> resolveUnitBids(unit, timeout)
                    .map(bids -> bids.stream().map(bid -> toAdUnitBid(unit, bid))))
            .collect(Collectors.toList());

    return CompositeFuture.join(adUnitBidFutures)
            .map(future -> future.<Stream<AdUnitBid>>list().stream()
                    .flatMap(Function.identity())
                    .collect(Collectors.groupingBy(AdUnitBid::getBidderCode))
                    .entrySet().stream()
                    .map(e -> AdapterRequest.of(e.getKey(), e.getValue()))
                    .collect(Collectors.toList()));
}
 
Example #20
Source File: TopicOperator.java    From strimzi-kafka-operator with Apache License 2.0 6 votes vote down vote up
private Future<Void> reconcileWithKubeTopic(LogContext logContext, HasMetadata involvedObject,
                                            String reconciliationType, ResourceName kubeName, TopicName topicName) {
    return executeWithTopicLockHeld(logContext, topicName, new Reconciliation("reconcile-with-kube") {
        @Override
        public Future<Void> execute() {
            Reconciliation self = this;
            return CompositeFuture.all(
                    k8s.getFromName(kubeName).map(kt -> {
                        observedTopicFuture(kt);
                        return kt;
                    }),
                    getFromKafka(topicName),
                    getFromTopicStore(topicName))
                .compose(compositeResult -> {
                    KafkaTopic ktr = compositeResult.resultAt(0);
                    logContext.withKubeTopic(ktr);
                    Topic k8sTopic = TopicSerialization.fromTopicResource(ktr);
                    Topic kafkaTopic = compositeResult.resultAt(1);
                    Topic privateTopic = compositeResult.resultAt(2);
                    return reconcile(self, logContext, involvedObject, k8sTopic, kafkaTopic, privateTopic);
                });
        }
    });
}
 
Example #21
Source File: BaseMicroserviceVerticle.java    From vertx-blueprint-microservice with Apache License 2.0 6 votes vote down vote up
@Override
public void stop(Future<Void> future) throws Exception {
  // In current design, the publisher is responsible for removing the service
  List<Future> futures = new ArrayList<>();
  registeredRecords.forEach(record -> {
    Future<Void> cleanupFuture = Future.future();
    futures.add(cleanupFuture);
    discovery.unpublish(record.getRegistration(), cleanupFuture.completer());
  });

  if (futures.isEmpty()) {
    discovery.close();
    future.complete();
  } else {
    CompositeFuture.all(futures)
      .setHandler(ar -> {
        discovery.close();
        if (ar.failed()) {
          future.fail(ar.cause());
        } else {
          future.complete();
        }
      });
  }
}
 
Example #22
Source File: VertxBasedHealthCheckServer.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Starts the health check server.
 *
 * @return a future indicating the output of the operation.
 */
@Override
public Future<Void> start() {

    registerAdditionalResources();

    return CompositeFuture.any(bindSecureHttpServer(), bindInsecureHttpServer())
            .map(ok -> (Void) null)
            .recover(error -> {
                LOG.error("failed to start Health Check server", error);
                return Future.failedFuture(error);
            });
}
 
Example #23
Source File: DelegatingTenantManagementHttpEndpoint.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private void createTenant(final RoutingContext ctx) {

        final Span span = TracingHelper.buildServerChildSpan(
                tracer,
                TracingHandler.serverSpanContext(ctx),
                SPAN_NAME_CREATE_TENANT,
                getClass().getSimpleName()
        ).start();

        final Future<String> tenantId = getRequestParameter(ctx, PARAM_TENANT_ID, getPredicate(config.getTenantIdPattern(), true));
        final Future<Tenant> payload = fromPayload(ctx);

        CompositeFuture.all(tenantId, payload)
            .compose(ok -> {
                final Optional<String> tid = Optional.ofNullable(tenantId.result());
                logger.debug("creating tenant [{}]", tid.orElse("<auto>"));
                return getService().createTenant(tid, payload.result(), span);
            })
            .onSuccess(operationResult -> writeResponse(ctx, operationResult, (responseHeaders, status) -> {
                if (status == HttpURLConnection.HTTP_CREATED) {
                    Optional.ofNullable(operationResult.getPayload())
                        .map(Id::getId)
                        .ifPresent(id -> {
                            final String location = String.format("/%s/%s", getName(), id);
                            responseHeaders.set(HttpHeaders.LOCATION, location);
                        });
                }
            }, span))
            .onFailure(t -> failRequest(ctx, t, span))
            .onComplete(s -> span.finish());
    }
 
Example #24
Source File: DelegatingDeviceManagementHttpEndpoint.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private void doCreateDevice(final RoutingContext ctx) {

        final Span span = TracingHelper.buildServerChildSpan(
                tracer,
                TracingHandler.serverSpanContext(ctx),
                SPAN_NAME_CREATE_DEVICE,
                getClass().getSimpleName()
        ).start();

        final Future<String> tenantId = getRequestParameter(ctx, PARAM_TENANT_ID, getPredicate(config.getTenantIdPattern(), false));
        final Future<String> deviceId = getRequestParameter(ctx, PARAM_DEVICE_ID, getPredicate(config.getDeviceIdPattern(), true));
        final Future<Device> device = fromPayload(ctx);

        CompositeFuture.all(tenantId, deviceId, device)
            .compose(ok -> {
                final Optional<String> did = Optional.ofNullable(deviceId.result());
                logger.debug("creating device [tenant: {}, device-id: {}]", tenantId.result(), did.orElse("<auto>"));
                return getService().createDevice(tenantId.result(), did, device.result(), span);
            })
            .onSuccess(operationResult -> writeResponse(ctx, operationResult, (responseHeaders, status) -> {
                    Optional.ofNullable(operationResult.getPayload())
                        .map(Id::getId)
                        .ifPresent(id -> responseHeaders.set(
                                HttpHeaders.LOCATION,
                                String.format("/%s/%s/%s", getName(), tenantId.result(), id)));
                }, span))
            .onFailure(t -> failRequest(ctx, t, span))
            .onComplete(s -> span.finish());
    }
 
Example #25
Source File: FileBasedCredentialsServiceTest.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private void start(final Promise<?> startupTracker) {

        CompositeFuture.all(registrationService.start(), credentialsService.start())
            .onComplete(result -> {
                LOG.debug("Startup complete", result.cause());
                if (result.failed()) {
                    startupTracker.fail(result.cause());
                } else {
                    startupTracker.complete();
                }
            });
    }
 
Example #26
Source File: AbstractVertxBasedMqttProtocolAdapter.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Closes a connection to a client.
 *
 * @param endpoint The connection to close.
 * @param authenticatedDevice Optional authenticated device information, may be {@code null}.
 * @param cmdSubscriptionsManager The CommandSubscriptionsManager to track command subscriptions, unsubscriptions
 *                                and handle PUBACKs.
 * @param traceSamplingPriority The sampling priority to be applied on the <em>OpenTracing</em> span
 *                              created for this operation.
 * @throws NullPointerException if any of the parameters except authenticatedDevice is {@code null}.
 */
protected final void close(final MqttEndpoint endpoint, final Device authenticatedDevice,
        final CommandSubscriptionsManager<T> cmdSubscriptionsManager, final OptionalInt traceSamplingPriority) {

    Objects.requireNonNull(endpoint);
    Objects.requireNonNull(cmdSubscriptionsManager);
    Objects.requireNonNull(traceSamplingPriority);

    final Span span = newSpan("CLOSE", endpoint, authenticatedDevice, traceSamplingPriority);
    onClose(endpoint);
    final CompositeFuture removalDoneFuture = cmdSubscriptionsManager.removeAllSubscriptions(
            (tenant, device) -> sendDisconnectedTtdEvent(tenant, device, authenticatedDevice, endpoint, span),
            span.context());
    sendDisconnectedEvent(endpoint.clientIdentifier(), authenticatedDevice);
    if (authenticatedDevice == null) {
        log.debug("connection to anonymous device [clientId: {}] closed", endpoint.clientIdentifier());
        metrics.decrementUnauthenticatedConnections();
    } else {
        log.debug("connection to device [tenant-id: {}, device-id: {}] closed",
                authenticatedDevice.getTenantId(), authenticatedDevice.getDeviceId());
        metrics.decrementConnections(authenticatedDevice.getTenantId());
    }
    if (endpoint.isConnected()) {
        log.debug("closing connection with client [client ID: {}]", endpoint.clientIdentifier());
        endpoint.close();
    } else {
        log.trace("connection to client is already closed");
    }
    removalDoneFuture.onComplete(r -> span.finish());
}
 
Example #27
Source File: AmqpServiceBase.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private Future<Void> stopEndpoints() {

        @SuppressWarnings("rawtypes")
        final
        List<Future> endpointFutures = new ArrayList<>(endpoints.size());
        for (final AmqpEndpoint ep : endpoints.values()) {
            log.info("stopping endpoint [name: {}, class: {}]", ep.getName(), ep.getClass().getName());
            endpointFutures.add(ep.stop());
        }
        return CompositeFuture.all(endpointFutures)
                .map(ok -> (Void) null)
                .recover(t -> Future.failedFuture(t));
    }
 
Example #28
Source File: CommandSubscriptionsManager.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Closes the command consumer and removes the subscription entry for the given topic.
 *
 * @param topic The topic string to unsubscribe.
 * @param onConsumerRemovedFunction The function to be invoked if not {@code null} during removal of a subscription.
 *                                  The first parameter is the tenant id, the second parameter the device id.
 *                                  To be returned is a future indicating the outcome of the function.
 * @param spanContext The span context (may be {@code null}).
 * @throws NullPointerException if topic is {@code null}.
 * @return A future indicating the outcome of the operation.
 **/
public Future<Void> removeSubscription(final String topic,
        final BiFunction<String, String, Future<Void>> onConsumerRemovedFunction, final SpanContext spanContext) {
    Objects.requireNonNull(topic);

    final TriTuple<CommandSubscription, ProtocolAdapterCommandConsumer, Object> removed = subscriptions.remove(topic);
    if (removed != null) {
        final CommandSubscription subscription = removed.one();
        final Future<Void> functionFuture = onConsumerRemovedFunction != null
                ? onConsumerRemovedFunction.apply(subscription.getTenant(), subscription.getDeviceId())
                : Future.succeededFuture();
        final ProtocolAdapterCommandConsumer commandConsumer = removed.two();
        return CompositeFuture
                .join(functionFuture, closeCommandConsumer(subscription, commandConsumer, spanContext)).mapEmpty();
    } else {
        LOG.debug("Cannot remove subscription; none registered for topic [{}]", topic);
        return Future.failedFuture(String.format("Cannot remove subscription; none registered for topic [%s]", topic));
    }
}
 
Example #29
Source File: ProtocolAdapterCommandConsumerFactoryImpl.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private void recreateConsumers() {
    if (recreatingConsumers.compareAndSet(false, true)) {
        log.debug("recreate command consumer links");
        connection.isConnected(getDefaultConnectionCheckTimeout())
                .compose(res -> {
                    @SuppressWarnings("rawtypes")
                    final List<Future> consumerCreationFutures = new ArrayList<>();
                    // recreate adapter specific consumer
                    if (adapterSpecificConsumer == null || !adapterSpecificConsumer.isOpen()) {
                        log.debug("recreate adapter specific command consumer link");
                        consumerCreationFutures.add(createAdapterSpecificConsumer());
                    }
                    // recreate mappingAndDelegatingCommandConsumers
                    adapterInstanceCommandHandler.getDeviceSpecificCommandHandlers().stream()
                            .map(CommandHandlerWrapper::getTenantId).distinct().forEach(tenantId -> {
                                log.debug("recreate command consumer link for tenant {}", tenantId);
                                consumerCreationFutures.add(
                                        getOrCreateMappingAndDelegatingCommandConsumer(tenantId));
                            });
                    return CompositeFuture.join(consumerCreationFutures);
                }).onComplete(ar -> {
                    recreatingConsumers.set(false);
                    if (tryAgainRecreatingConsumers.compareAndSet(true, false) || ar.failed()) {
                        if (ar.succeeded()) {
                            // tryAgainRecreatingConsumers was set - try again immediately
                            recreateConsumers();
                        } else {
                            invokeRecreateConsumersWithDelay();
                        }
                    }
                });
    } else {
        // if recreateConsumers() was triggered by a remote link closing, that might have occurred after that link was dealt with above;
        // therefore be sure recreateConsumers() gets called again once the current invocation has finished.
        log.debug("already recreating consumers");
        tryAgainRecreatingConsumers.set(true);
    }
}
 
Example #30
Source File: AbstractProtocolAdapterBase.java    From hono with Eclipse Public License 2.0 5 votes vote down vote up
private Future<?> closeServiceClients() {

        @SuppressWarnings("rawtypes")
        final List<Future> results = new ArrayList<>();
        results.add(disconnectFromService(downstreamSenderFactory));
        results.add(disconnectFromService(tenantClientFactory));
        results.add(disconnectFromService(registrationClientFactory));
        results.add(disconnectFromService(credentialsClientFactory));
        results.add(disconnectFromService(commandConsumerFactory));
        if (deviceConnectionClientFactory instanceof ConnectionLifecycle) {
            results.add(disconnectFromService((ConnectionLifecycle<?>) deviceConnectionClientFactory));
        }
        return CompositeFuture.all(results);
    }