All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.helidon.webclient.api.WebClientServiceResponse Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2024 Oracle and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.helidon.webclient.api;

import java.io.InputStream;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

import io.helidon.builder.api.Prototype;
import io.helidon.common.Errors;
import io.helidon.common.Generated;
import io.helidon.http.ClientResponseHeaders;
import io.helidon.http.ClientResponseTrailers;
import io.helidon.http.Status;

/**
 * Response which is created upon receiving of server response.
 *
 * @see #builder()
 * @see #create()
 */
@Generated(value = "io.helidon.builder.codegen.BuilderCodegen", trigger = "io.helidon.webclient.api.WebClientServiceResponseBlueprint")
public interface WebClientServiceResponse extends WebClientServiceResponseBlueprint, Prototype.Api {

    /**
     * Create a new fluent API builder to customize configuration.
     *
     * @return a new builder
     */
    static WebClientServiceResponse.Builder builder() {
        return new WebClientServiceResponse.Builder();
    }

    /**
     * Create a new fluent API builder from an existing instance.
     *
     * @param instance an existing instance used as a base for the builder
     * @return a builder based on an instance
     */
    static WebClientServiceResponse.Builder builder(WebClientServiceResponse instance) {
        return WebClientServiceResponse.builder().from(instance);
    }

    /**
     * Create a new instance with default values.
     *
     * @return a new instance
     */
    static WebClientServiceResponse create() {
        return WebClientServiceResponse.builder().buildPrototype();
    }

    /**
     * Fluent API builder base for {@link WebClientServiceResponse}.
     *
     * @param  type of the builder extending this abstract builder
     * @param  type of the prototype interface that would be built by {@link #buildPrototype()}
     */
    abstract class BuilderBase, PROTOTYPE extends WebClientServiceResponse> implements Prototype.Builder {

        private ClientResponseHeaders headers;
        private CompletableFuture whenComplete;
        private CompletableFuture trailers;
        private InputStream inputStream;
        private ReleasableResource connection;
        private Status status;
        private WebClientServiceRequest serviceRequest;

        /**
         * Protected to support extensibility.
         */
        protected BuilderBase() {
        }

        /**
         * Update this builder from an existing prototype instance. This method disables automatic service discovery.
         *
         * @param prototype existing prototype to update this builder from
         * @return updated builder instance
         */
        public BUILDER from(WebClientServiceResponse prototype) {
            headers(prototype.headers());
            trailers(prototype.trailers());
            status(prototype.status());
            inputStream(prototype.inputStream());
            connection(prototype.connection());
            whenComplete(prototype.whenComplete());
            serviceRequest(prototype.serviceRequest());
            return self();
        }

        /**
         * Update this builder from an existing prototype builder instance.
         *
         * @param builder existing builder prototype to update this builder from
         * @return updated builder instance
         */
        public BUILDER from(WebClientServiceResponse.BuilderBase builder) {
            builder.headers().ifPresent(this::headers);
            builder.trailers().ifPresent(this::trailers);
            builder.status().ifPresent(this::status);
            builder.inputStream().ifPresent(this::inputStream);
            builder.connection().ifPresent(this::connection);
            builder.whenComplete().ifPresent(this::whenComplete);
            builder.serviceRequest().ifPresent(this::serviceRequest);
            return self();
        }

        /**
         * Received response headers.
         *
         * @param headers immutable response headers
         * @return updated builder instance
         * @see #headers()
         */
        public BUILDER headers(ClientResponseHeaders headers) {
            Objects.requireNonNull(headers);
            this.headers = headers;
            return self();
        }

        /**
         * Received response trailer headers.
         *
         * @param trailers immutable response trailer headers
         * @return updated builder instance
         * @see #trailers()
         */
        public BUILDER trailers(CompletableFuture trailers) {
            Objects.requireNonNull(trailers);
            this.trailers = trailers;
            return self();
        }

        /**
         * Status of the response.
         *
         * @param status response status
         * @return updated builder instance
         * @see #status()
         */
        public BUILDER status(Status status) {
            Objects.requireNonNull(status);
            this.status = status;
            return self();
        }

        /**
         * Clear existing value of this property.
         *
         * @return updated builder instance
         * @see #inputStream()
         */
        public BUILDER clearInputStream() {
            this.inputStream = null;
            return self();
        }

        /**
         * Input stream to get data of the entity. This allows decorating the entity (such as decryption).
         * The status, headers are always already read, and the input stream will not provide transfer encoded bytes
         * (e.g. the bytes in the input stream are the entity bytes, regardless of how it is encoded over HTTP).
         *
         * @param inputStream entity input stream, or empty, if there is no entity
         * @return updated builder instance
         * @see #inputStream()
         */
        public BUILDER inputStream(InputStream inputStream) {
            Objects.requireNonNull(inputStream);
            this.inputStream = inputStream;
            return self();
        }

        /**
         * Client connection/stream that was used to handle this request.
         * This resource will be closed/released once the entity is fully read, depending on keep alive configuration.
         *
         * @param connection connection resource
         * @return updated builder instance
         * @see #connection()
         */
        public BUILDER connection(ReleasableResource connection) {
            Objects.requireNonNull(connection);
            this.connection = connection;
            return self();
        }

        /**
         * Completable future to be completed by the client response when the entity is fully read.
         *
         * @param whenComplete completable future to be finished by the client response
         * @return updated builder instance
         * @see #whenComplete()
         */
        public BUILDER whenComplete(CompletableFuture whenComplete) {
            Objects.requireNonNull(whenComplete);
            this.whenComplete = whenComplete;
            return self();
        }

        /**
         * The service request used to invoke the final call.
         *
         * @param serviceRequest service request
         * @return updated builder instance
         * @see #serviceRequest()
         */
        public BUILDER serviceRequest(WebClientServiceRequest serviceRequest) {
            Objects.requireNonNull(serviceRequest);
            this.serviceRequest = serviceRequest;
            return self();
        }

        /**
         * Received response headers.
         *
         * @return the headers
         */
        public Optional headers() {
            return Optional.ofNullable(headers);
        }

        /**
         * Received response trailer headers.
         *
         * @return the trailers
         */
        public Optional> trailers() {
            return Optional.ofNullable(trailers);
        }

        /**
         * Status of the response.
         *
         * @return the status
         */
        public Optional status() {
            return Optional.ofNullable(status);
        }

        /**
         * Input stream to get data of the entity. This allows decorating the entity (such as decryption).
         * The status, headers are always already read, and the input stream will not provide transfer encoded bytes
         * (e.g. the bytes in the input stream are the entity bytes, regardless of how it is encoded over HTTP).
         *
         * @return the input stream
         */
        public Optional inputStream() {
            return Optional.ofNullable(inputStream);
        }

        /**
         * Client connection/stream that was used to handle this request.
         * This resource will be closed/released once the entity is fully read, depending on keep alive configuration.
         *
         * @return the connection
         */
        public Optional connection() {
            return Optional.ofNullable(connection);
        }

        /**
         * Completable future to be completed by the client response when the entity is fully read.
         *
         * @return the when complete
         */
        public Optional> whenComplete() {
            return Optional.ofNullable(whenComplete);
        }

        /**
         * The service request used to invoke the final call.
         *
         * @return the service request
         */
        public Optional serviceRequest() {
            return Optional.ofNullable(serviceRequest);
        }

        @Override
        public String toString() {
            return "WebClientServiceResponseBuilder{"
                    + "headers=" + headers + ","
                    + "trailers=" + trailers + ","
                    + "status=" + status + ","
                    + "inputStream=" + inputStream + ","
                    + "connection=" + connection + ","
                    + "whenComplete=" + whenComplete + ","
                    + "serviceRequest=" + serviceRequest
                    + "}";
        }

        /**
         * Handles providers and decorators.
         */
        protected void preBuildPrototype() {
            new WebClientServiceResponseDecorator().decorate(this);
        }

        /**
         * Validates required properties.
         */
        protected void validatePrototype() {
            Errors.Collector collector = Errors.collector();
            if (headers == null) {
                collector.fatal(getClass(), "Property \"headers\" must not be null, but not set");
            }
            if (trailers == null) {
                collector.fatal(getClass(), "Property \"trailers\" must not be null, but not set");
            }
            if (status == null) {
                collector.fatal(getClass(), "Property \"status\" must not be null, but not set");
            }
            if (connection == null) {
                collector.fatal(getClass(), "Property \"connection\" must not be null, but not set");
            }
            if (whenComplete == null) {
                collector.fatal(getClass(), "Property \"whenComplete\" must not be null, but not set");
            }
            if (serviceRequest == null) {
                collector.fatal(getClass(), "Property \"serviceRequest\" must not be null, but not set");
            }
            collector.collect().checkValid();
        }

        /**
         * Input stream to get data of the entity. This allows decorating the entity (such as decryption).
         * The status, headers are always already read, and the input stream will not provide transfer encoded bytes
         * (e.g. the bytes in the input stream are the entity bytes, regardless of how it is encoded over HTTP).
         *
         * @param inputStream entity input stream, or empty, if there is no entity
         * @return updated builder instance
         * @see #inputStream()
         */
        BUILDER inputStream(Optional inputStream) {
            Objects.requireNonNull(inputStream);
            this.inputStream = inputStream.map(java.io.InputStream.class::cast).orElse(this.inputStream);
            return self();
        }

        /**
         * Generated implementation of the prototype, can be extended by descendant prototype implementations.
         */
        protected static class WebClientServiceResponseImpl implements WebClientServiceResponse {

            private final ClientResponseHeaders headers;
            private final CompletableFuture whenComplete;
            private final CompletableFuture trailers;
            private final Optional inputStream;
            private final ReleasableResource connection;
            private final Status status;
            private final WebClientServiceRequest serviceRequest;

            /**
             * Create an instance providing a builder.
             *
             * @param builder extending builder base of this prototype
             */
            protected WebClientServiceResponseImpl(WebClientServiceResponse.BuilderBase builder) {
                this.headers = builder.headers().get();
                this.trailers = builder.trailers().get();
                this.status = builder.status().get();
                this.inputStream = builder.inputStream();
                this.connection = builder.connection().get();
                this.whenComplete = builder.whenComplete().get();
                this.serviceRequest = builder.serviceRequest().get();
            }

            @Override
            public ClientResponseHeaders headers() {
                return headers;
            }

            @Override
            public CompletableFuture trailers() {
                return trailers;
            }

            @Override
            public Status status() {
                return status;
            }

            @Override
            public Optional inputStream() {
                return inputStream;
            }

            @Override
            public ReleasableResource connection() {
                return connection;
            }

            @Override
            public CompletableFuture whenComplete() {
                return whenComplete;
            }

            @Override
            public WebClientServiceRequest serviceRequest() {
                return serviceRequest;
            }

            @Override
            public String toString() {
                return "WebClientServiceResponse{"
                        + "headers=" + headers + ","
                        + "trailers=" + trailers + ","
                        + "status=" + status + ","
                        + "inputStream=" + inputStream + ","
                        + "connection=" + connection + ","
                        + "whenComplete=" + whenComplete + ","
                        + "serviceRequest=" + serviceRequest
                        + "}";
            }

            @Override
            public boolean equals(Object o) {
                if (o == this) {
                    return true;
                }
                if (!(o instanceof WebClientServiceResponse other)) {
                    return false;
                }
                return Objects.equals(headers, other.headers())
                    && Objects.equals(trailers, other.trailers())
                    && Objects.equals(status, other.status())
                    && Objects.equals(inputStream, other.inputStream())
                    && Objects.equals(connection, other.connection())
                    && Objects.equals(whenComplete, other.whenComplete())
                    && Objects.equals(serviceRequest, other.serviceRequest());
            }

            @Override
            public int hashCode() {
                return Objects.hash(headers, trailers, status, inputStream, connection, whenComplete, serviceRequest);
            }

        }

    }

    /**
     * Fluent API builder for {@link WebClientServiceResponse}.
     */
    class Builder extends WebClientServiceResponse.BuilderBase implements io.helidon.common.Builder {

        private Builder() {
        }

        @Override
        public WebClientServiceResponse buildPrototype() {
            preBuildPrototype();
            validatePrototype();
            return new WebClientServiceResponseImpl(this);
        }

        @Override
        public WebClientServiceResponse build() {
            return buildPrototype();
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy