Search in sources :

Example 1 with PinotException

use of io.trino.plugin.pinot.PinotException in project trino by trinodb.

the class PinotClient method doHttpActionWithHeadersJson.

protected <T> T doHttpActionWithHeadersJson(Request.Builder requestBuilder, Optional<String> requestBody, JsonCodec<T> codec, Multimap<String, String> additionalHeaders) {
    requestBuilder.addHeaders(additionalHeaders);
    requestBuilder.setHeader(ACCEPT, APPLICATION_JSON);
    if (requestBody.isPresent()) {
        requestBuilder.setHeader(CONTENT_TYPE, APPLICATION_JSON);
        requestBuilder.setBodyGenerator(StaticBodyGenerator.createStaticBodyGenerator(requestBody.get(), StandardCharsets.UTF_8));
    }
    Request request = requestBuilder.build();
    JsonResponseHandler<T> responseHandler = createJsonResponseHandler(codec);
    T response = null;
    try {
        response = httpClient.execute(request, responseHandler);
    } catch (UnexpectedResponseException e) {
        throw new PinotException(PinotErrorCode.PINOT_HTTP_ERROR, Optional.empty(), format("Unexpected response status: %d for request %s to url %s, with headers %s, full response %s", e.getStatusCode(), requestBody.orElse(""), request.getUri(), request.getHeaders(), response));
    }
    return response;
}
Also used : PinotException(io.trino.plugin.pinot.PinotException) ACCEPT(com.google.common.net.HttpHeaders.ACCEPT) Request(io.airlift.http.client.Request) UnexpectedResponseException(io.airlift.http.client.UnexpectedResponseException)

Example 2 with PinotException

use of io.trino.plugin.pinot.PinotException in project trino by trinodb.

the class PinotClient method submitBrokerQueryJson.

private BrokerResponseNative submitBrokerQueryJson(ConnectorSession session, PinotQueryInfo query) {
    String queryRequest = QUERY_REQUEST_JSON_CODEC.toJson(new QueryRequest(query.getQuery()));
    return doWithRetries(PinotSessionProperties.getPinotRetryCount(session), retryNumber -> {
        String queryHost = getBrokerHost(query.getTable());
        LOG.info("Query '%s' on broker host '%s'", queryHost, query.getQuery());
        Request.Builder builder = Request.Builder.preparePost().setUri(URI.create(format(QUERY_URL_TEMPLATE, queryHost)));
        ImmutableMultimap.Builder<String, String> additionalHeadersBuilder = ImmutableMultimap.builder();
        brokerAuthenticationProvider.getAuthenticationToken().ifPresent(token -> additionalHeadersBuilder.put(AUTHORIZATION, token));
        BrokerResponseNative response = doHttpActionWithHeadersJson(builder, Optional.of(queryRequest), brokerResponseCodec, additionalHeadersBuilder.build());
        if (response.getExceptionsSize() > 0 && response.getProcessingExceptions() != null && !response.getProcessingExceptions().isEmpty()) {
            // so we treat any exception as an error
            throw new PinotException(PINOT_EXCEPTION, Optional.of(query.getQuery()), format("Query %s encountered exception %s", query.getQuery(), response.getProcessingExceptions().get(0)));
        }
        if (response.getNumServersQueried() == 0 || response.getNumServersResponded() == 0 || response.getNumServersQueried() > response.getNumServersResponded()) {
            throw new PinotInsufficientServerResponseException(query, response.getNumServersResponded(), response.getNumServersQueried());
        }
        return response;
    });
}
Also used : PinotException(io.trino.plugin.pinot.PinotException) PinotInsufficientServerResponseException(io.trino.plugin.pinot.PinotInsufficientServerResponseException) BrokerResponseNative(org.apache.pinot.common.response.broker.BrokerResponseNative) Request(io.airlift.http.client.Request) ImmutableMultimap(com.google.common.collect.ImmutableMultimap)

Example 3 with PinotException

use of io.trino.plugin.pinot.PinotException in project trino by trinodb.

the class PinotQueryClient method queryPinotServerForDataTable.

public Map<ServerInstance, DataTable> queryPinotServerForDataTable(String query, String serverHost, List<String> segments, long connectionTimeoutInMillis, int pinotRetryCount) {
    // TODO: separate into offline and realtime methods
    BrokerRequest brokerRequest;
    try {
        brokerRequest = REQUEST_COMPILER.compileToBrokerRequest(query);
    } catch (SqlCompilationException e) {
        throw new PinotException(PINOT_INVALID_PQL_GENERATED, Optional.of(query), format("Parsing error with on %s, Error = %s", serverHost, e.getMessage()), e);
    }
    ServerInstance serverInstance = pinotHostMapper.getServerInstance(serverHost);
    Map<ServerInstance, List<String>> routingTable = new HashMap<>();
    routingTable.put(serverInstance, new ArrayList<>(segments));
    String tableName = brokerRequest.getQuerySource().getTableName();
    String rawTableName = TableNameBuilder.extractRawTableName(tableName);
    Map<ServerInstance, List<String>> offlineRoutingTable = TableNameBuilder.isOfflineTableResource(tableName) ? routingTable : null;
    Map<ServerInstance, List<String>> realtimeRoutingTable = TableNameBuilder.isRealtimeTableResource(tableName) ? routingTable : null;
    BrokerRequest offlineBrokerRequest = TableNameBuilder.isOfflineTableResource(tableName) ? brokerRequest : null;
    BrokerRequest realtimeBrokerRequest = TableNameBuilder.isRealtimeTableResource(tableName) ? brokerRequest : null;
    AsyncQueryResponse asyncQueryResponse = doWithRetries(pinotRetryCount, requestId -> queryRouter.submitQuery(requestId, rawTableName, offlineBrokerRequest, offlineRoutingTable, realtimeBrokerRequest, realtimeRoutingTable, connectionTimeoutInMillis));
    try {
        Map<ServerRoutingInstance, ServerResponse> response = asyncQueryResponse.getResponse();
        Map<ServerInstance, DataTable> dataTableMap = new HashMap<>();
        for (Map.Entry<ServerRoutingInstance, ServerResponse> entry : response.entrySet()) {
            ServerResponse serverResponse = entry.getValue();
            DataTable dataTable = serverResponse.getDataTable();
            dataTableMap.put(toServerInstance(entry.getKey()), dataTable);
        }
        return dataTableMap;
    } catch (InterruptedException e) {
        throw new PinotException(PINOT_EXCEPTION, Optional.of(query), "Pinot query execution was interrupted", e);
    }
}
Also used : ServerResponse(org.apache.pinot.core.transport.ServerResponse) PinotException(io.trino.plugin.pinot.PinotException) DataTable(org.apache.pinot.common.utils.DataTable) HashMap(java.util.HashMap) ServerRoutingInstance(org.apache.pinot.core.transport.ServerRoutingInstance) SqlCompilationException(org.apache.pinot.sql.parsers.SqlCompilationException) BrokerRequest(org.apache.pinot.common.request.BrokerRequest) ArrayList(java.util.ArrayList) List(java.util.List) AsyncQueryResponse(org.apache.pinot.core.transport.AsyncQueryResponse) ServerInstance(org.apache.pinot.core.transport.ServerInstance) HashMap(java.util.HashMap) Map(java.util.Map)

Example 4 with PinotException

use of io.trino.plugin.pinot.PinotException in project trino by trinodb.

the class PinotClient method getAllBrokersForTable.

@VisibleForTesting
public List<String> getAllBrokersForTable(String table) {
    ArrayList<String> brokers = sendHttpGetToControllerJson(format(TABLE_INSTANCES_API_TEMPLATE, table), brokersForTableJsonCodec).getBrokers().stream().flatMap(broker -> broker.getInstances().stream()).distinct().map(brokerToParse -> {
        Matcher matcher = BROKER_PATTERN.matcher(brokerToParse);
        if (matcher.matches() && matcher.groupCount() == 2) {
            return pinotHostMapper.getBrokerHost(matcher.group(1), matcher.group(2));
        } else {
            throw new PinotException(PINOT_UNABLE_TO_FIND_BROKER, Optional.empty(), format("Cannot parse %s in the broker instance", brokerToParse));
        }
    }).collect(Collectors.toCollection(ArrayList::new));
    Collections.shuffle(brokers);
    return ImmutableList.copyOf(brokers);
}
Also used : JsonProperty(com.fasterxml.jackson.annotation.JsonProperty) PinotConfig(io.trino.plugin.pinot.PinotConfig) JsonResponseHandler(io.airlift.http.client.JsonResponseHandler) UnaryOperator.identity(java.util.function.UnaryOperator.identity) AUTHORIZATION(com.google.common.net.HttpHeaders.AUTHORIZATION) ACCEPT(com.google.common.net.HttpHeaders.ACCEPT) DeserializationFeature(com.fasterxml.jackson.databind.DeserializationFeature) NonEvictableLoadingCache(io.trino.collect.cache.NonEvictableLoadingCache) UnexpectedResponseException(io.airlift.http.client.UnexpectedResponseException) Matcher(java.util.regex.Matcher) JsonCodecBinder(io.airlift.json.JsonCodecBinder) Schema(org.apache.pinot.spi.data.Schema) PINOT_UNABLE_TO_FIND_BROKER(io.trino.plugin.pinot.PinotErrorCode.PINOT_UNABLE_TO_FIND_BROKER) PinotSessionProperties(io.trino.plugin.pinot.PinotSessionProperties) Map(java.util.Map) URI(java.net.URI) ENGLISH(java.util.Locale.ENGLISH) ForPinot(io.trino.plugin.pinot.ForPinot) ImmutableMap(com.google.common.collect.ImmutableMap) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) String.format(java.lang.String.format) Preconditions.checkState(com.google.common.base.Preconditions.checkState) CacheLoader(com.google.common.cache.CacheLoader) SafeCaches.buildNonEvictableCache(io.trino.collect.cache.SafeCaches.buildNonEvictableCache) List(java.util.List) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) JsonCodec.listJsonCodec(io.airlift.json.JsonCodec.listJsonCodec) JsonCodecFactory(io.airlift.json.JsonCodecFactory) HttpUriBuilder.uriBuilderFrom(io.airlift.http.client.HttpUriBuilder.uriBuilderFrom) Optional(java.util.Optional) JsonResponseHandler.createJsonResponseHandler(io.airlift.http.client.JsonResponseHandler.createJsonResponseHandler) PinotBrokerAuthenticationProvider(io.trino.plugin.pinot.auth.PinotBrokerAuthenticationProvider) CacheBuilder(com.google.common.cache.CacheBuilder) Pattern(java.util.regex.Pattern) JsonCodec(io.airlift.json.JsonCodec) PINOT_INVALID_CONFIGURATION(io.trino.plugin.pinot.PinotErrorCode.PINOT_INVALID_CONFIGURATION) HttpClient(io.airlift.http.client.HttpClient) IntStream(java.util.stream.IntStream) Logger(io.airlift.log.Logger) BrokerResponseNative(org.apache.pinot.common.response.broker.BrokerResponseNative) PinotInsufficientServerResponseException(io.trino.plugin.pinot.PinotInsufficientServerResponseException) PINOT_EXCEPTION(io.trino.plugin.pinot.PinotErrorCode.PINOT_EXCEPTION) Multimap(com.google.common.collect.Multimap) Function(java.util.function.Function) CONTENT_TYPE(com.google.common.net.HttpHeaders.CONTENT_TYPE) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) PinotQueryInfo(io.trino.plugin.pinot.query.PinotQueryInfo) ImmutableList(com.google.common.collect.ImmutableList) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Objects.requireNonNull(java.util.Objects.requireNonNull) Request(io.airlift.http.client.Request) PinotException(io.trino.plugin.pinot.PinotException) ResultTable(org.apache.pinot.common.response.broker.ResultTable) TableNameBuilder.extractRawTableName(org.apache.pinot.spi.utils.builder.TableNameBuilder.extractRawTableName) ImmutableMultimap(com.google.common.collect.ImmutableMultimap) Iterator(java.util.Iterator) JsonCodec.mapJsonCodec(io.airlift.json.JsonCodec.mapJsonCodec) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) AbstractIterator(com.google.common.collect.AbstractIterator) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) ConnectorSession(io.trino.spi.connector.ConnectorSession) PinotErrorCode(io.trino.plugin.pinot.PinotErrorCode) PinotControllerAuthenticationProvider(io.trino.plugin.pinot.auth.PinotControllerAuthenticationProvider) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) JsonCodec.jsonCodec(io.airlift.json.JsonCodec.jsonCodec) StaticBodyGenerator(io.airlift.http.client.StaticBodyGenerator) JsonCreator(com.fasterxml.jackson.annotation.JsonCreator) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) PinotColumnHandle(io.trino.plugin.pinot.PinotColumnHandle) PinotException(io.trino.plugin.pinot.PinotException) Matcher(java.util.regex.Matcher) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 5 with PinotException

use of io.trino.plugin.pinot.PinotException in project trino by trinodb.

the class PinotClient method doWithRetries.

public static <T> T doWithRetries(int retries, Function<Integer, T> caller) {
    PinotException firstError = null;
    checkState(retries > 0, "Invalid num of retries %s", retries);
    for (int i = 0; i < retries; ++i) {
        try {
            return caller.apply(i);
        } catch (PinotException e) {
            if (firstError == null) {
                firstError = e;
            }
            if (!e.isRetryable()) {
                throw e;
            }
        }
    }
    throw firstError;
}
Also used : PinotException(io.trino.plugin.pinot.PinotException)

Aggregations

PinotException (io.trino.plugin.pinot.PinotException)5 Request (io.airlift.http.client.Request)3 ImmutableMultimap (com.google.common.collect.ImmutableMultimap)2 ACCEPT (com.google.common.net.HttpHeaders.ACCEPT)2 UnexpectedResponseException (io.airlift.http.client.UnexpectedResponseException)2 JsonCreator (com.fasterxml.jackson.annotation.JsonCreator)1 JsonProperty (com.fasterxml.jackson.annotation.JsonProperty)1 DeserializationFeature (com.fasterxml.jackson.databind.DeserializationFeature)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 CacheBuilder (com.google.common.cache.CacheBuilder)1 CacheLoader (com.google.common.cache.CacheLoader)1 AbstractIterator (com.google.common.collect.AbstractIterator)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)1 Iterables.getOnlyElement (com.google.common.collect.Iterables.getOnlyElement)1 Multimap (com.google.common.collect.Multimap)1 AUTHORIZATION (com.google.common.net.HttpHeaders.AUTHORIZATION)1