Search in sources :

Example 6 with Single

use of io.helidon.common.reactive.Single in project helidon by oracle.

the class RestApiBase method requestBytesPayload.

/**
 * Create a supplier for a response with publisher request.
 * Defaults to "{@code () -> clientRequest.submit(publisher)}".
 * Also configures content type and accept headers.
 *
 * @param path path requested
 * @param request API request
 * @param method HTTP method
 * @param requestId ID of this request
 * @param requestBuilder {@link io.helidon.webclient.WebClient} request builder
 * @param publisher publisher to be used as request entity
 *
 * @return supplier of a web client response
 */
protected Supplier<Single<WebClientResponse>> requestBytesPayload(String path, ApiRequest<?> request, Http.RequestMethod method, String requestId, WebClientRequestBuilder requestBuilder, Flow.Publisher<DataChunk> publisher) {
    requestBuilder.accept(request.responseMediaType().orElse(MediaType.APPLICATION_JSON));
    requestBuilder.contentType(request.requestMediaType().orElse(MediaType.APPLICATION_OCTET_STREAM));
    AtomicBoolean updated = new AtomicBoolean();
    return () -> {
        if (updated.compareAndSet(false, true)) {
            return updateRequestBuilderBytesPayload(requestBuilder, path, request, method, requestId).flatMapSingle(it -> it.submit(publisher));
        } else {
            return requestBuilder.submit(publisher);
        }
    };
}
Also used : JsonWriterFactory(jakarta.json.JsonWriterFactory) ByteArrayOutputStream(java.io.ByteArrayOutputStream) WebClient(io.helidon.webclient.WebClient) WebClientResponse(io.helidon.webclient.WebClientResponse) JsonReaderFactory(jakarta.json.JsonReaderFactory) DataChunk(io.helidon.common.http.DataChunk) JsonBuilderFactory(jakarta.json.JsonBuilderFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Supplier(java.util.function.Supplier) MediaType(io.helidon.common.http.MediaType) Flow(java.util.concurrent.Flow) JsonObject(jakarta.json.JsonObject) Single(io.helidon.common.reactive.Single) Http(io.helidon.common.http.Http) Multi(io.helidon.common.reactive.Multi) FtHandler(io.helidon.faulttolerance.FtHandler) Collector(io.helidon.common.reactive.Collector) UUID(java.util.UUID) Logger(java.util.logging.Logger) WebClientRequestHeaders(io.helidon.webclient.WebClientRequestHeaders) Contexts(io.helidon.common.context.Contexts) SpanContext(io.opentracing.SpanContext) StringReader(java.io.StringReader) Optional(java.util.Optional) WebClientRequestBuilder(io.helidon.webclient.WebClientRequestBuilder) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 7 with Single

use of io.helidon.common.reactive.Single in project helidon by oracle.

the class RestApiBase method errorResponse.

/**
 * Create an error response.
 * This method attempts to read the response entity as a string, parse it into a JsonObject and
 * depending on result, calls methods to create a proper exception.
 *
 * @param path requested path
 * @param request original request
 * @param method HTTP method
 * @param requestId ID of the request
 * @param response actual response where we do not expect an entity
 * @param <T> type of the response
 *
 * @return future with error
 */
protected <T extends ApiResponse> Single<T> errorResponse(String path, ApiRequest<?> request, Http.RequestMethod method, String requestId, WebClientResponse response) {
    if (response.headers().contentLength().orElse(-1L) == 0) {
        // explicitly no content
        return Single.error(readError(path, request, method, requestId, response));
    } else {
        AtomicBoolean processedError = new AtomicBoolean();
        return response.content().as(String.class).flatMapSingle(string -> {
            try {
                JsonObject json = jsonReaderFactory.createReader(new StringReader(string)).readObject();
                Single<T> error = Single.error(readError(path, request, method, requestId, response, json));
                processedError.set(true);
                return error;
            } catch (Exception e) {
                Single<T> error = Single.error(readError(path, request, method, requestId, response, string));
                processedError.set(true);
                return error;
            }
        }).onErrorResumeWithSingle(it -> {
            if (processedError.get()) {
                return Single.error(it);
            }
            return Single.error(readErrorFailedEntity(path, request, method, requestId, response, it));
        });
    }
}
Also used : JsonWriterFactory(jakarta.json.JsonWriterFactory) ByteArrayOutputStream(java.io.ByteArrayOutputStream) WebClient(io.helidon.webclient.WebClient) WebClientResponse(io.helidon.webclient.WebClientResponse) JsonReaderFactory(jakarta.json.JsonReaderFactory) DataChunk(io.helidon.common.http.DataChunk) JsonBuilderFactory(jakarta.json.JsonBuilderFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Supplier(java.util.function.Supplier) MediaType(io.helidon.common.http.MediaType) Flow(java.util.concurrent.Flow) JsonObject(jakarta.json.JsonObject) Single(io.helidon.common.reactive.Single) Http(io.helidon.common.http.Http) Multi(io.helidon.common.reactive.Multi) FtHandler(io.helidon.faulttolerance.FtHandler) Collector(io.helidon.common.reactive.Collector) UUID(java.util.UUID) Logger(java.util.logging.Logger) WebClientRequestHeaders(io.helidon.webclient.WebClientRequestHeaders) Contexts(io.helidon.common.context.Contexts) SpanContext(io.opentracing.SpanContext) StringReader(java.io.StringReader) Optional(java.util.Optional) WebClientRequestBuilder(io.helidon.webclient.WebClientRequestBuilder) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Single(io.helidon.common.reactive.Single) StringReader(java.io.StringReader) JsonObject(jakarta.json.JsonObject)

Example 8 with Single

use of io.helidon.common.reactive.Single in project helidon by oracle.

the class OciRestApi method requestJsonPayload.

@Override
protected Supplier<Single<WebClientResponse>> requestJsonPayload(String path, ApiRequest<?> request, Http.RequestMethod method, String requestId, WebClientRequestBuilder requestBuilder, JsonObject jsonObject) {
    requestBuilder.accept(request.responseMediaType().orElse(MediaType.APPLICATION_JSON));
    requestBuilder.contentType(request.requestMediaType().orElse(MediaType.APPLICATION_JSON));
    // common stuff
    updateRequestBuilder(requestBuilder, request, requestId);
    // signature requirement
    // this requires a content length and hash
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    jsonWriterFactory().createWriter(baos).write(jsonObject);
    byte[] requestBytes = baos.toByteArray();
    String sha256 = HASH_DIGEST.digest(Base64Value.create(requestBytes)).toBase64();
    requestBuilder.headers(headers -> {
        headers.contentLength(requestBytes.length);
        headers.add("x-content-sha256", sha256);
        return headers;
    }).contentType(request.requestMediaType().orElse(MediaType.APPLICATION_JSON));
    return () -> requestBuilder.submit(requestBytes);
}
Also used : ApiRequest(io.helidon.integrations.common.rest.ApiRequest) Security(io.helidon.security.Security) ByteArrayOutputStream(java.io.ByteArrayOutputStream) WebClientResponse(io.helidon.webclient.WebClientResponse) BiFunction(java.util.function.BiFunction) DataChunk(io.helidon.common.http.DataChunk) Supplier(java.util.function.Supplier) Level(java.util.logging.Level) MediaType(io.helidon.common.http.MediaType) Base64Value(io.helidon.common.Base64Value) Flow(java.util.concurrent.Flow) JsonObject(jakarta.json.JsonObject) Single(io.helidon.common.reactive.Single) URI(java.net.URI) Http(io.helidon.common.http.Http) HashDigest(io.helidon.common.crypto.HashDigest) Config(io.helidon.config.Config) WebClientSecurity(io.helidon.webclient.security.WebClientSecurity) Logger(java.util.logging.Logger) StandardCharsets(java.nio.charset.StandardCharsets) RestApiBase(io.helidon.integrations.common.rest.RestApiBase) URLEncoder(java.net.URLEncoder) RestApi(io.helidon.integrations.common.rest.RestApi) Version(io.helidon.common.Version) Optional(java.util.Optional) WebClientRequestBuilder(io.helidon.webclient.WebClientRequestBuilder) ByteArrayOutputStream(java.io.ByteArrayOutputStream)

Example 9 with Single

use of io.helidon.common.reactive.Single in project helidon by oracle.

the class OciConfigInstancePrincipal method refresh.

@Override
public Single<OciSignatureData> refresh() {
    // we must use future, as there may be multiple singles created from it
    CompletableFuture<OciSignatureData> nextFuture = new CompletableFuture<>();
    CompletionStage<OciSignatureData> inProgress = refreshFuture.compareAndExchange(null, nextFuture);
    if (inProgress != null) {
        LOGGER.fine("Refresh already in progress.");
        // I do not own this refresh
        return Single.create(inProgress);
    }
    Instant instant = lastSuccessfulRefresh.get();
    if (instant != null && instant.plus(1, ChronoUnit.MINUTES).isAfter(Instant.now())) {
        LOGGER.fine("Refresh requested within one minute of last successful refresh, ignoring");
        refreshFuture.set(null);
        return Single.just(currentSignatureData.get());
    }
    LOGGER.fine("Refresh of signature data initialized");
    nextFuture.handle((it, throwable) -> {
        if (throwable != null) {
            LOGGER.fine("Finished refresh with exception: " + throwable.getMessage() + ", stack trace available in FINEST");
            LOGGER.log(Level.FINEST, "Exception", throwable);
        } else {
            lastSuccessfulRefresh.set(Instant.now());
            LOGGER.fine("Finished refresh successfully. New kid: " + it.keyId());
        }
        // now we can open for next refresh command
        refreshFuture.set(null);
        return null;
    });
    // we may have parallel requests to refresh under heavy load
    KeyPair keyPair = sessionKeys.refresh();
    // trigger read in parallel
    Single<PrivateKey> pkSingle = privateKeySupplier.get();
    Single<X509Certificate> certSingle = certificateSupplier.get();
    Single<X509Certificate> intermediateSingle = intermediateCertificateSupplier.get();
    pkSingle.flatMapSingle(privateKey -> certSingle.flatMapSingle(certificate -> intermediateSingle.flatMapSingle(intermediateCert -> refresh(keyPair, privateKey, certificate, intermediateCert)))).forSingle(nextFuture::complete).exceptionallyAccept(nextFuture::completeExceptionally);
    return Single.create(nextFuture);
}
Also used : X509Certificate(java.security.cert.X509Certificate) KeyPair(java.security.KeyPair) JsonWriterFactory(jakarta.json.JsonWriterFactory) Security(io.helidon.security.Security) ByteArrayOutputStream(java.io.ByteArrayOutputStream) CertificateFactory(java.security.cert.CertificateFactory) WebClient(io.helidon.webclient.WebClient) WebClientResponse(io.helidon.webclient.WebClientResponse) JsonBuilderFactory(jakarta.json.JsonBuilderFactory) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) MediaType(io.helidon.common.http.MediaType) JsonpSupport(io.helidon.media.jsonp.JsonpSupport) ByteArrayInputStream(java.io.ByteArrayInputStream) Base64Value(io.helidon.common.Base64Value) Map(java.util.Map) KeyConfig(io.helidon.common.pki.KeyConfig) JsonObject(jakarta.json.JsonObject) Single(io.helidon.common.reactive.Single) URI(java.net.URI) LinkedList(java.util.LinkedList) Http(io.helidon.common.http.Http) HashDigest(io.helidon.common.crypto.HashDigest) WebClientSecurity(io.helidon.webclient.security.WebClientSecurity) RSAPrivateKey(java.security.interfaces.RSAPrivateKey) PublicKey(java.security.PublicKey) CertificateException(java.security.cert.CertificateException) Instant(java.time.Instant) Logger(java.util.logging.Logger) Resource(io.helidon.common.configurable.Resource) StandardCharsets(java.nio.charset.StandardCharsets) Json(jakarta.json.Json) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Base64(java.util.Base64) List(java.util.List) ChronoUnit(java.time.temporal.ChronoUnit) CompletionStage(java.util.concurrent.CompletionStage) PrivateKey(java.security.PrivateKey) Version(io.helidon.common.Version) Optional(java.util.Optional) CertificateEncodingException(java.security.cert.CertificateEncodingException) CompletableFuture(java.util.concurrent.CompletableFuture) KeyPair(java.security.KeyPair) RSAPrivateKey(java.security.interfaces.RSAPrivateKey) PrivateKey(java.security.PrivateKey) Instant(java.time.Instant) X509Certificate(java.security.cert.X509Certificate)

Example 10 with Single

use of io.helidon.common.reactive.Single in project helidon by oracle.

the class OciConfigInstancePrincipal method getData.

// only get the new signature data
private Single<OciSignatureData> getData(KeyPair keyPair, X509Certificate leafCertificate, X509Certificate intermediateCert) {
    LOGGER.fine("Getting signature data");
    PublicKey publicKey = keyPair.getPublic();
    String publicKeyPem = toPem(publicKey);
    String leafCertificatePem = toPem(leafCertificate);
    String intermediatePem = toPem(intermediateCert);
    String purpose = "DEFAULT";
    String fingerprintAlgorithm = "SHA256";
    JsonObject jsonRequest = JSON.createObjectBuilder().add("publicKey", publicKeyPem).add("certificate", leafCertificatePem).add("intermediateCertificates", JSON.createArrayBuilder().add(intermediatePem)).add("purpose", purpose).add("fingerprintAlgorithm", fingerprintAlgorithm).build();
    // this requires a content length and hash
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    JSON_WRITER_FACTORY.createWriter(baos).write(jsonRequest);
    byte[] requestBytes = baos.toByteArray();
    String sha256 = HASH_DIGEST.digest(Base64Value.create(requestBytes)).toBase64();
    return federationClient.post().path("/v1/x509").contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).headers(headers -> {
        headers.contentLength(requestBytes.length);
        headers.add("x-content-sha256", sha256);
        return headers;
    }).submit(requestBytes).flatMapSingle(it -> {
        if (it.status().family() != Http.ResponseStatus.Family.SUCCESSFUL) {
            return readError(it);
        }
        return it.content().as(JsonObject.class);
    }).map(it -> it.getString("token")).map(newToken -> toData(newToken, keyPair));
}
Also used : X509Certificate(java.security.cert.X509Certificate) KeyPair(java.security.KeyPair) JsonWriterFactory(jakarta.json.JsonWriterFactory) Security(io.helidon.security.Security) ByteArrayOutputStream(java.io.ByteArrayOutputStream) CertificateFactory(java.security.cert.CertificateFactory) WebClient(io.helidon.webclient.WebClient) WebClientResponse(io.helidon.webclient.WebClientResponse) JsonBuilderFactory(jakarta.json.JsonBuilderFactory) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) MediaType(io.helidon.common.http.MediaType) JsonpSupport(io.helidon.media.jsonp.JsonpSupport) ByteArrayInputStream(java.io.ByteArrayInputStream) Base64Value(io.helidon.common.Base64Value) Map(java.util.Map) KeyConfig(io.helidon.common.pki.KeyConfig) JsonObject(jakarta.json.JsonObject) Single(io.helidon.common.reactive.Single) URI(java.net.URI) LinkedList(java.util.LinkedList) Http(io.helidon.common.http.Http) HashDigest(io.helidon.common.crypto.HashDigest) WebClientSecurity(io.helidon.webclient.security.WebClientSecurity) RSAPrivateKey(java.security.interfaces.RSAPrivateKey) PublicKey(java.security.PublicKey) CertificateException(java.security.cert.CertificateException) Instant(java.time.Instant) Logger(java.util.logging.Logger) Resource(io.helidon.common.configurable.Resource) StandardCharsets(java.nio.charset.StandardCharsets) Json(jakarta.json.Json) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Base64(java.util.Base64) List(java.util.List) ChronoUnit(java.time.temporal.ChronoUnit) CompletionStage(java.util.concurrent.CompletionStage) PrivateKey(java.security.PrivateKey) Version(io.helidon.common.Version) Optional(java.util.Optional) CertificateEncodingException(java.security.cert.CertificateEncodingException) PublicKey(java.security.PublicKey) JsonObject(jakarta.json.JsonObject) ByteArrayOutputStream(java.io.ByteArrayOutputStream)

Aggregations

Single (io.helidon.common.reactive.Single)39 Config (io.helidon.config.Config)23 Routing (io.helidon.webserver.Routing)18 WebServer (io.helidon.webserver.WebServer)18 LogConfig (io.helidon.common.LogConfig)16 JsonpSupport (io.helidon.media.jsonp.JsonpSupport)15 MetricsSupport (io.helidon.metrics.MetricsSupport)12 Optional (java.util.Optional)12 Logger (java.util.logging.Logger)12 Http (io.helidon.common.http.Http)11 MediaType (io.helidon.common.http.MediaType)9 DataChunk (io.helidon.common.http.DataChunk)8 HealthSupport (io.helidon.health.HealthSupport)8 HealthChecks (io.helidon.health.checks.HealthChecks)8 WebClient (io.helidon.webclient.WebClient)8 WebClientRequestBuilder (io.helidon.webclient.WebClientRequestBuilder)8 JsonBuilderFactory (jakarta.json.JsonBuilderFactory)8 JsonObject (jakarta.json.JsonObject)8 Supplier (java.util.function.Supplier)8 Contexts (io.helidon.common.context.Contexts)7