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

io.github.sinri.keel.elasticsearch.ESApiMixin Maven / Gradle / Ivy

Go to download

A website framework with VERT.X for ex-PHP-ers, exactly Ark Framework Users.

The newest version!
package io.github.sinri.keel.elasticsearch;

import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.json.DecodeException;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.client.HttpRequest;
import io.vertx.ext.web.client.WebClient;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

import static io.github.sinri.keel.facade.KeelInstance.Keel;

/**
 * Developed with ES version 8.9.
 *
 * @since 3.0.7
 */
public interface ESApiMixin {
    ElasticSearchConfig getEsConfig();

    /**
     * @since 3.2.20
     * By default, For ES 8.9.
     */
    default void handleHeaders(HttpRequest bufferHttpRequest) {
        List version = getEsConfig().version();
        if (version != null && !version.isEmpty() && version.get(0) != null && version.get(0) < 8) {
            bufferHttpRequest.putHeader("Accept", "application/json");
            bufferHttpRequest.putHeader("Content-Type", "application/json");
        } else {
            bufferHttpRequest.putHeader("Accept", "application/vnd.elasticsearch+json");
            bufferHttpRequest.putHeader("Content-Type", "application/vnd.elasticsearch+json");
        }
    }

    /**
     * @since 3.1.10
     * For Bulk API, of which the body is not a json object.
     */
    default Future call(@Nonnull HttpMethod httpMethod, @Nonnull String endpoint, @Nullable ESApiQueries queries, @Nullable String requestBody) {
        WebClient webClient = WebClient.create(Keel.getVertx());
        String url = this.getEsConfig().clusterApiUrl(endpoint);
        HttpRequest bufferHttpRequest = webClient.requestAbs(httpMethod, url);

        bufferHttpRequest.basicAuthentication(getEsConfig().username(), getEsConfig().password());
        handleHeaders(bufferHttpRequest);

        String opaqueId = this.getEsConfig().opaqueId();
        if (opaqueId != null) {
            bufferHttpRequest.putHeader("X-Opaque-Id", opaqueId);
        }

        if (queries != null) {
            queries.forEach(bufferHttpRequest::addQueryParam);
        }

//        Handler logRequestEnricher = log -> log
//                .context(c -> c
//                        .put("request", new JsonObject()
//                                .put("method", httpMethod.name())
//                                .put("endpoint", endpoint)
//                                .put("queries", queriesForLog)
//                                .put("body", requestBody)
//                        )
//                );

        return Future.succeededFuture()
                .compose(v -> {
                    if (httpMethod == HttpMethod.GET || httpMethod == HttpMethod.DELETE) {
                        return bufferHttpRequest.send();
                    } else {
                        return bufferHttpRequest.sendBuffer(Buffer.buffer(Objects.requireNonNullElse(requestBody, "")));
                    }
                })
                .compose(bufferHttpResponse -> {
                    int statusCode = bufferHttpResponse.statusCode();
                    if ((statusCode >= 300 || statusCode < 200)) {
//                        this.getLogger().error(log -> {
//                            logRequestEnricher.handle(log);
//                            log.message("ES API Response Error")
//                                    .context(c -> c
//                                            .put("response", new JsonObject()
//                                                    .put("status_code", statusCode)
//                                                    .put("raw", bufferHttpResponse.bodyAsString()))
//                                    );
//                        });
//                        return Future.failedFuture("ES API: STATUS CODE IS " + statusCode + " | " + bufferHttpResponse.bodyAsString());

                        return Future.failedFuture(new ESApiException(
                                statusCode, bufferHttpResponse.bodyAsString(),
                                httpMethod,
                                endpoint,
                                queries,
                                requestBody
                        ));
                    }
                    JsonObject resp;
                    try {
                        resp = bufferHttpResponse.bodyAsJsonObject();
                    } catch (DecodeException decodeException) {
                        // There are situations that use Json Array as the response body!
                        resp = new JsonObject()
                                .put("array", new JsonArray(bufferHttpResponse.bodyAsString()));
                    }
//                    this.getLogger().info(log -> {
//                        logRequestEnricher.handle(log);
//                        log.message("ES API Response Error")
//                                .context(c -> c
//                                        .put("response", new JsonObject()
//                                                .put("status_code", statusCode)
//                                                .put("body", resp))
//                                );
//                    });
                    return Future.succeededFuture(resp);
                })
                .andThen(ar -> {
                    webClient.close();
                });
    }

    /**
     * @since 3.1.10 based on `io.github.sinri.keel.elasticsearch.ESApiMixin#call(io.vertx.core.http.HttpMethod, java.lang.String, io.github.sinri.keel.elasticsearch.ESApiMixin.ESApiQueries, java.lang.String)`
     */
    default Future callPost(@Nonnull String endpoint, @Nullable ESApiQueries queries, @Nonnull JsonObject requestBody) {
        return call(HttpMethod.POST, endpoint, queries, requestBody.toString());
    }

//    default Future call(HttpMethod httpMethod, String endpoint, ESApiQueries queries, @Nullable JsonObject requestBody) {
//        WebClient webClient = WebClient.create(Keel.getVertx());
//        String url = this.getEsConfig().clusterApiUrl(endpoint);
//        HttpRequest bufferHttpRequest = webClient.requestAbs(httpMethod, url);
//
//        bufferHttpRequest.basicAuthentication(getEsConfig().username(), getEsConfig().password());
//        bufferHttpRequest.putHeader("Accept", "application/vnd.elasticsearch+json");
//        bufferHttpRequest.putHeader("Content-Type", "application/vnd.elasticsearch+json");
//
//        String opaqueId = this.getEsConfig().opaqueId();
//        if (opaqueId != null) {
//            bufferHttpRequest.putHeader("X-Opaque-Id", opaqueId);
//        }
//
//        JsonObject queriesForLog = new JsonObject();
//        if (queries != null) {
//            queries.forEach((k, v) -> {
//                bufferHttpRequest.addQueryParam(k, v);
//                queriesForLog.put(k, v);
//            });
//        }
//
//        Handler logRequestEnricher = log -> log
//                .context(c -> c
//                        .put("request", new JsonObject()
//                                .put("method", httpMethod.name())
//                                .put("endpoint", endpoint)
//                                .put("queries", queriesForLog)
//                                .put("body", requestBody)
//                        )
//                );
//
//        return Future.succeededFuture()
//                .compose(v -> {
//                    if (httpMethod == HttpMethod.GET) {
//                        return bufferHttpRequest.send();
//                    } else {
//                        return bufferHttpRequest.sendJsonObject(requestBody);
//                    }
//                })
//                .compose(bufferHttpResponse -> {
//                    int statusCode = bufferHttpResponse.statusCode();
//                    JsonObject resp = bufferHttpResponse.bodyAsJsonObject();
//
//                    if ((statusCode >= 300 || statusCode < 200) || resp == null) {
//                        this.getLogger().error(log -> {
//                            logRequestEnricher.handle(log);
//                            log.message("ES API Response Error")
//                                    .context(c -> c
//                                            .put("response", new JsonObject()
//                                                    .put("status_code", statusCode)
//                                                    .put("raw", bufferHttpResponse.bodyAsString()))
//                                    );
//                        });
//                        return Future.failedFuture("ES API: STATUS CODE IS " + statusCode + " | " + bufferHttpResponse.bodyAsString());
//                    }
//                    this.getLogger().info(log -> {
//                        logRequestEnricher.handle(log);
//                        log.message("ES API Response Error")
//                                .context(c -> c
//                                        .put("response", new JsonObject()
//                                                .put("status_code", statusCode)
//                                                .put("body", resp))
//                                );
//                    });
//                    return Future.succeededFuture(resp);
//                });
//    }

    class ESApiQueries extends HashMap {
        public JsonObject toJsonObject() {
            JsonObject jsonObject = new JsonObject();
            this.forEach(jsonObject::put);
            return jsonObject;
        }
    }

    class ESApiException extends Exception {
        private final int statusCode;
        private final @Nullable String response;

        private final @Nonnull HttpMethod httpMethod;
        private final @Nonnull String endpoint;
        private final @Nullable ESApiQueries queries;
        private final @Nullable String requestBody;

        public ESApiException(
                int statusCode, @Nullable String response,
                @Nonnull HttpMethod httpMethod,
                @Nonnull String endpoint,
                @Nullable ESApiQueries queries,
                @Nullable String requestBody
        ) {
            this.statusCode = statusCode;
            this.response = response;

            this.httpMethod = httpMethod;
            this.endpoint = endpoint;
            this.queries = queries;
            this.requestBody = requestBody;
        }

        @Override
        public String toString() {
            return getClass().getName()
                    + "{status_code: " + statusCode
                    + ", response: " + response
                    + ", http_method: " + httpMethod.name()
                    + ", endpoint: " + endpoint
                    + ", queries: " + queries
                    + ", request_body: " + requestBody
                    + "}";
        }

        public int getStatusCode() {
            return statusCode;
        }

        @Nullable
        public String getResponse() {
            return response;
        }

        @Nonnull
        public String getEndpoint() {
            return endpoint;
        }

        @Nullable
        public ESApiQueries getQueries() {
            return queries;
        }

        @Nonnull
        public HttpMethod getHttpMethod() {
            return httpMethod;
        }

        @Nullable
        public String getRequestBody() {
            return requestBody;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy