Example usage for io.vertx.core Future succeededFuture

List of usage examples for io.vertx.core Future succeededFuture

Introduction

In this page you can find the example usage for io.vertx.core Future succeededFuture.

Prototype

static <T> Future<T> succeededFuture(T result) 

Source Link

Document

Created a succeeded future with the specified result.

Usage

From source file:org.eclipse.hono.adapter.http.AbstractVertxBasedHttpProtocolAdapter.java

License:Open Source License

/**
 * Gets a registration assertion for a device.
 * <p>//from  w w w. ja va  2 s . c om
 * This method first tries to retrieve the assertion from request header {@link #HEADER_REGISTRATION_ASSERTION}.
 * If the header exists and contains a value representing a non-expired assertion, a completed future
 * containing the header field's value is returned.
 * Otherwise a new assertion is retrieved from the Device Registration service and included in the response
 * using the same header name.
 * 
 * @param ctx The routing context to use for getting/setting the cookie.
 * @param tenantId The tenant that the device belongs to.
 * @param deviceId The device to get the assertion for.
 * @return A future containing the assertion.
 */
protected final Future<String> getRegistrationAssertionHeader(final RoutingContext ctx, final String tenantId,
        final String deviceId) {

    String assertion = ctx.request().getHeader(HEADER_REGISTRATION_ASSERTION);
    if (assertion != null && !JwtHelper.isExpired(assertion, 5)) {
        return Future.succeededFuture(assertion);
    } else {
        return getRegistrationAssertion(tenantId, deviceId).compose(token -> {
            ctx.response().putHeader(HEADER_REGISTRATION_ASSERTION, token);
            return Future.succeededFuture(token);
        });
    }
}

From source file:org.eclipse.hono.adapter.http.HonoAuthHandlerImpl.java

License:Open Source License

@Override
public void parseCredentials(RoutingContext context, Handler<AsyncResult<JsonObject>> handler) {

    parseAuthorization(context, false, parseAuthorization -> {
        if (parseAuthorization.failed()) {
            handler.handle(Future.failedFuture(parseAuthorization.cause()));
            return;
        }/*  w ww .  jav a2s .  c o  m*/

        final String suser;
        final String spass;

        try {
            // decode the payload
            String decoded = new String(Base64.getDecoder().decode(parseAuthorization.result()));

            int colonIdx = decoded.indexOf(":");
            if (colonIdx != -1) {
                suser = decoded.substring(0, colonIdx);
                spass = decoded.substring(colonIdx + 1);
            } else {
                suser = decoded;
                spass = null;
            }
        } catch (RuntimeException e) {
            // IllegalArgumentException includes PatternSyntaxException
            context.fail(e);
            return;
        }

        handler.handle(Future.succeededFuture(new JsonObject().put("username", suser).put("password", spass)));
    });
}

From source file:org.eclipse.hono.adapter.http.HonoBasicAuthHandler.java

License:Open Source License

@Override
public void parseCredentials(final RoutingContext context, final Handler<AsyncResult<JsonObject>> handler) {

    parseAuthorization(context, false, parseAuthorization -> {
        if (parseAuthorization.failed()) {
            handler.handle(Future.failedFuture(parseAuthorization.cause()));
            return;
        }/*from  w w  w .ja  v  a  2 s .  c  o  m*/

        final String suser;
        final String spass;

        try {
            // decode the payload
            final String decoded = new String(Base64.getDecoder().decode(parseAuthorization.result()));

            final int colonIdx = decoded.indexOf(":");
            if (colonIdx != -1) {
                suser = decoded.substring(0, colonIdx);
                spass = decoded.substring(colonIdx + 1);
            } else {
                suser = decoded;
                spass = null;
            }
        } catch (RuntimeException e) {
            // IllegalArgumentException includes PatternSyntaxException
            context.fail(e);
            return;
        }

        handler.handle(Future.succeededFuture(new JsonObject().put("username", suser).put("password", spass)));
    });
}

From source file:org.eclipse.hono.adapter.http.X509AuthHandler.java

License:Open Source License

private Future<X509Certificate[]> getX509CertificateChain(final Certificate[] clientChain) {

    final List<X509Certificate> chain = new LinkedList<>();
    for (Certificate cert : clientChain) {
        if (cert instanceof X509Certificate) {
            chain.add((X509Certificate) cert);
        } else {//from  w w w.  ja v  a2  s . c o m
            LOG.info("cannot authenticate device using unsupported certificate type [{}]",
                    cert.getClass().getName());
            return Future.failedFuture(UNAUTHORIZED);
        }
    }
    return Future.succeededFuture(chain.toArray(new X509Certificate[chain.size()]));
}

From source file:org.eclipse.hono.adapter.http.X509AuthHandler.java

License:Open Source License

/**
 * Gets the authentication information for a device's client certificate.
 * <p>/*from w w w  .j  a va  2s.  c  o m*/
 * This default implementation returns a JSON object that contains two properties:
 * <ul>
 * <li>{@link RequestResponseApiConstants#FIELD_PAYLOAD_SUBJECT_DN} -
 * the subject DN from the certificate</li>
 * <li>{@link RequestResponseApiConstants#FIELD_PAYLOAD_TENANT_ID} -
 * the identifier of the tenant that the device belongs to</li>
 * </ul>
 * <p>
 * Subclasses may override this method in order to extract additional or other
 * information to be verified by e.g. a custom authentication provider.
 * 
 * @param clientCertChain The validated client certificate chain that the device has
 *                   presented during the TLS handshake. The device's end certificate
 *                   is contained at index 0.
 * @param tenant The tenant that the device belongs to.
 * @return A succeeded future containing the authentication information that will be passed on
 *         to the {@link HonoClientBasedAuthProvider} for verification. The future will be
 *         failed if the information cannot be extracted from the certificate chain.
 */
protected Future<JsonObject> getCredentials(final X509Certificate[] clientCertChain,
        final TenantObject tenant) {

    final String subjectDn = clientCertChain[0].getSubjectX500Principal().getName(X500Principal.RFC2253);
    LOG.debug("authenticating device of tenant [{}] using X509 certificate [subject DN: {}]",
            tenant.getTenantId(), subjectDn);
    return Future.succeededFuture(new JsonObject().put(CredentialsConstants.FIELD_PAYLOAD_SUBJECT_DN, subjectDn)
            .put(CredentialsConstants.FIELD_PAYLOAD_TENANT_ID, tenant.getTenantId()));
}

From source file:org.eclipse.hono.adapter.mqtt.AbstractVertxBasedMqttProtocolAdapter.java

License:Open Source License

/**
 * Create a future indicating an accepted connection with an authenticated device.
 * /*from  w  w  w .  ja va  2  s  .  c  o  m*/
 * @param authenticatedDevice The device that was authenticated, may be {@code null}
 * @return A future indicating an accepted connection.
 */
protected static Future<Device> accepted(final Device authenticatedDevice) {
    return Future.succeededFuture(authenticatedDevice);
}

From source file:org.eclipse.hono.adapter.mqtt.AbstractVertxBasedMqttProtocolAdapter.java

License:Open Source License

/**
 * Create a future indicating an accepted connection without an authenticated device.
 * /*from  w w  w  .  j  ava 2s . c  om*/
 * @return A future indicating an accepted connection.
 */
protected static Future<Device> accepted() {
    return Future.succeededFuture(null);
}

From source file:org.eclipse.hono.adapter.mqtt.AbstractVertxBasedMqttProtocolAdapter.java

License:Open Source License

private Future<Device> handleEndpointConnectionWithAuthentication(final MqttEndpoint endpoint) {

    if (endpoint.auth() == null) {

        LOG.debug("connection request from device [clientId: {}] rejected: {}", endpoint.clientIdentifier(),
                "device did not provide credentials in CONNECT packet");

        return rejected(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD);

    } else {//from w  ww  . j  a v  a2s .c o  m

        final DeviceCredentials credentials = getCredentials(endpoint.auth());

        if (credentials == null) {

            LOG.debug("connection request from device [clientId: {}] rejected: {}", endpoint.clientIdentifier(),
                    "device provided malformed credentials in CONNECT packet");
            return rejected(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD);

        } else {

            return getTenantConfiguration(credentials.getTenantId()).compose(tenantConfig -> {
                if (tenantConfig.isAdapterEnabled(getTypeName())) {
                    LOG.debug("protocol adapter [{}] is enabled for tenant [{}]", getTypeName(),
                            credentials.getTenantId());
                    return Future.succeededFuture(tenantConfig);
                } else {
                    LOG.debug("protocol adapter [{}] is disabled for tenant [{}]", getTypeName(),
                            credentials.getTenantId());
                    return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_FORBIDDEN,
                            "adapter disabled for tenant"));
                }
            }).compose(tenantConfig -> {
                final Future<Device> result = Future.future();
                usernamePasswordAuthProvider.authenticate(credentials, result.completer());
                return result;
            }).compose(authenticatedDevice -> {
                LOG.debug("successfully authenticated device [tenant-id: {}, auth-id: {}, device-id: {}]",
                        authenticatedDevice.getTenantId(), credentials.getAuthId(),
                        authenticatedDevice.getDeviceId());
                return triggerLinkCreation(authenticatedDevice.getTenantId()).map(done -> {
                    onAuthenticationSuccess(endpoint, authenticatedDevice);
                    return null;
                }).compose(ok -> accepted(authenticatedDevice));
            }).recover(t -> {
                LOG.debug("cannot establish connection with device [tenant-id: {}, auth-id: {}]",
                        credentials.getTenantId(), credentials.getAuthId(), t);
                if (t instanceof ServerErrorException) {
                    // one of the services we depend on might not be available (yet)
                    return rejected(MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE);
                } else {
                    // validation of credentials has failed
                    return rejected(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED);
                }
            });

        }
    }
}

From source file:org.eclipse.hono.adapter.mqtt.impl.VertxBasedMqttProtocolAdapter.java

License:Open Source License

Future<ResourceIdentifier> mapTopic(final MqttPublishMessage message) {

    try {//  w  w w .  j a v  a2s . c  o  m
        final ResourceIdentifier topic = ResourceIdentifier.fromString(message.topicName());

        switch (EndpointType.fromString(topic.getEndpoint())) {
        case TELEMETRY:
            if (MqttQoS.EXACTLY_ONCE.equals(message.qosLevel())) {
                // client tries to send telemetry message using QoS 2
                return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST,
                        "QoS 2 not supported for telemetry messages"));
            } else {
                return Future.succeededFuture(topic);
            }
        case EVENT:
            if (!MqttQoS.AT_LEAST_ONCE.equals(message.qosLevel())) {
                // client tries to send event message using QoS 0 or 2
                return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST,
                        "Only QoS 1 supported for event messages"));
            } else {
                return Future.succeededFuture(topic);
            }
        default:
            // MQTT client is trying to publish on a not supported endpoint
            LOG.debug("no such endpoint [{}]", topic.getEndpoint());
            return Future.failedFuture(
                    new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "no such endpoint"));
        }
    } catch (final IllegalArgumentException e) {
        return Future.failedFuture(
                new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST, "malformed topic name"));
    }
}

From source file:org.eclipse.hono.adapter.mqtt.VertxBasedMqttProtocolAdapter.java

License:Open Source License

private Future<String> getRegistrationAssertion(final MqttEndpoint endpoint, final String tenantId,
        final String logicalDeviceId) {
    String token = registrationAssertions.get(endpoint);
    if (token != null && !RegistrationAssertionHelperImpl.isExpired(token, 10)) {
        return Future.succeededFuture(token);
    } else {//from   w w  w. j av  a2 s . c o  m
        registrationAssertions.remove(endpoint);
        Future<String> result = Future.future();
        getRegistrationAssertion(tenantId, logicalDeviceId).compose(t -> {
            // if the client closes the connection right after publishing the messages and before that
            // the registration assertion has been returned, avoid to put it into the map
            if (endpoint.isConnected()) {
                LOG.trace("caching registration assertion for client [{}]", endpoint.clientIdentifier());
                registrationAssertions.put(endpoint, t);
            }
            result.complete(t);
        }, result);
        return result;
    }
}