Search in sources :

Example 6 with QueryException

use of org.apache.druid.query.QueryException in project druid by druid-io.

the class SqlResourceTest method testCannotParse.

@Test
public void testCannotParse() throws Exception {
    final QueryException exception = doPost(createSimpleQueryWithId("id", "FROM druid.foo")).lhs;
    Assert.assertNotNull(exception);
    Assert.assertEquals(PlanningError.SQL_PARSE_ERROR.getErrorCode(), exception.getErrorCode());
    Assert.assertEquals(PlanningError.SQL_PARSE_ERROR.getErrorClass(), exception.getErrorClass());
    Assert.assertTrue(exception.getMessage().contains("Encountered \"FROM\" at line 1, column 1."));
    checkSqlRequestLog(false);
    Assert.assertTrue(lifecycleManager.getAll("id").isEmpty());
}
Also used : UnsupportedSQLQueryException(org.apache.druid.sql.calcite.planner.UnsupportedSQLQueryException) QueryException(org.apache.druid.query.QueryException) Test(org.junit.Test)

Example 7 with QueryException

use of org.apache.druid.query.QueryException in project druid by druid-io.

the class SqlResourceTest method testUnsupportedQueryThrowsExceptionWithFilterResponse.

@Test
public void testUnsupportedQueryThrowsExceptionWithFilterResponse() throws Exception {
    resource = new SqlResource(JSON_MAPPER, CalciteTests.TEST_AUTHORIZER_MAPPER, sqlLifecycleFactory, lifecycleManager, new ServerConfig() {

        @Override
        public boolean isShowDetailedJettyErrors() {
            return true;
        }

        @Override
        public ErrorResponseTransformStrategy getErrorResponseTransformStrategy() {
            return new AllowedRegexErrorResponseTransformStrategy(ImmutableList.of());
        }
    });
    String errorMessage = "This will be support in Druid 9999";
    SqlQuery badQuery = EasyMock.createMock(SqlQuery.class);
    EasyMock.expect(badQuery.getQuery()).andReturn("SELECT ANSWER TO LIFE");
    EasyMock.expect(badQuery.getContext()).andReturn(ImmutableMap.of("sqlQueryId", "id"));
    EasyMock.expect(badQuery.getParameterList()).andThrow(new QueryUnsupportedException(errorMessage));
    EasyMock.replay(badQuery);
    final QueryException exception = doPost(badQuery).lhs;
    Assert.assertNotNull(exception);
    Assert.assertNull(exception.getMessage());
    Assert.assertNull(exception.getHost());
    Assert.assertEquals(exception.getErrorCode(), QueryUnsupportedException.ERROR_CODE);
    Assert.assertNull(exception.getErrorClass());
    Assert.assertTrue(lifecycleManager.getAll("id").isEmpty());
}
Also used : ServerConfig(org.apache.druid.server.initialization.ServerConfig) UnsupportedSQLQueryException(org.apache.druid.sql.calcite.planner.UnsupportedSQLQueryException) QueryException(org.apache.druid.query.QueryException) QueryUnsupportedException(org.apache.druid.query.QueryUnsupportedException) AllowedRegexErrorResponseTransformStrategy(org.apache.druid.common.exception.AllowedRegexErrorResponseTransformStrategy) Test(org.junit.Test)

Example 8 with QueryException

use of org.apache.druid.query.QueryException in project druid by druid-io.

the class QueryResourceTest method testBadQuery.

@Test
public void testBadQuery() throws IOException {
    EasyMock.replay(testServletRequest);
    Response response = queryResource.doPost(new ByteArrayInputStream("Meka Leka Hi Meka Hiney Ho".getBytes(StandardCharsets.UTF_8)), null, /*pretty*/
    testServletRequest);
    Assert.assertNotNull(response);
    Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
    QueryException e = jsonMapper.readValue((byte[]) response.getEntity(), QueryException.class);
    Assert.assertEquals(BadJsonQueryException.ERROR_CODE, e.getErrorCode());
    Assert.assertEquals(BadJsonQueryException.ERROR_CLASS, e.getErrorClass());
}
Also used : Response(javax.ws.rs.core.Response) BadJsonQueryException(org.apache.druid.query.BadJsonQueryException) QueryException(org.apache.druid.query.QueryException) ByteArrayInputStream(java.io.ByteArrayInputStream) Test(org.junit.Test)

Example 9 with QueryException

use of org.apache.druid.query.QueryException in project druid by druid-io.

the class QueryResource method doPost.

@POST
@Produces({ MediaType.APPLICATION_JSON, SmileMediaTypes.APPLICATION_JACKSON_SMILE })
@Consumes({ MediaType.APPLICATION_JSON, SmileMediaTypes.APPLICATION_JACKSON_SMILE, APPLICATION_SMILE })
public Response doPost(final InputStream in, @QueryParam("pretty") final String pretty, // used to get request content-type,Accept header, remote address and auth-related headers
@Context final HttpServletRequest req) throws IOException {
    final QueryLifecycle queryLifecycle = queryLifecycleFactory.factorize();
    Query<?> query = null;
    final ResourceIOReaderWriter ioReaderWriter = createResourceIOReaderWriter(req, pretty != null);
    final String currThreadName = Thread.currentThread().getName();
    try {
        queryLifecycle.initialize(readQuery(req, in, ioReaderWriter));
        query = queryLifecycle.getQuery();
        final String queryId = query.getId();
        final String queryThreadName = StringUtils.format("%s[%s_%s_%s]", currThreadName, query.getType(), query.getDataSource().getTableNames(), queryId);
        Thread.currentThread().setName(queryThreadName);
        if (log.isDebugEnabled()) {
            log.debug("Got query [%s]", query);
        }
        final Access authResult = queryLifecycle.authorize(req);
        if (!authResult.isAllowed()) {
            throw new ForbiddenException(authResult.toString());
        }
        final QueryLifecycle.QueryResponse queryResponse = queryLifecycle.execute();
        final Sequence<?> results = queryResponse.getResults();
        final ResponseContext responseContext = queryResponse.getResponseContext();
        final String prevEtag = getPreviousEtag(req);
        if (prevEtag != null && prevEtag.equals(responseContext.getEntityTag())) {
            queryLifecycle.emitLogsAndMetrics(null, req.getRemoteAddr(), -1);
            successfulQueryCount.incrementAndGet();
            return Response.notModified().build();
        }
        final Yielder<?> yielder = Yielders.each(results);
        try {
            boolean shouldFinalize = QueryContexts.isFinalize(query, true);
            boolean serializeDateTimeAsLong = QueryContexts.isSerializeDateTimeAsLong(query, false) || (!shouldFinalize && QueryContexts.isSerializeDateTimeAsLongInner(query, false));
            final ObjectWriter jsonWriter = ioReaderWriter.getResponseWriter().newOutputWriter(queryLifecycle.getToolChest(), queryLifecycle.getQuery(), serializeDateTimeAsLong);
            Response.ResponseBuilder responseBuilder = Response.ok(new StreamingOutput() {

                @Override
                public void write(OutputStream outputStream) throws WebApplicationException {
                    Exception e = null;
                    CountingOutputStream os = new CountingOutputStream(outputStream);
                    try {
                        // json serializer will always close the yielder
                        jsonWriter.writeValue(os, yielder);
                        // Some types of OutputStream suppress flush errors in the .close() method.
                        os.flush();
                        os.close();
                    } catch (Exception ex) {
                        e = ex;
                        log.noStackTrace().error(ex, "Unable to send query response.");
                        throw new RuntimeException(ex);
                    } finally {
                        Thread.currentThread().setName(currThreadName);
                        queryLifecycle.emitLogsAndMetrics(e, req.getRemoteAddr(), os.getCount());
                        if (e == null) {
                            successfulQueryCount.incrementAndGet();
                        } else {
                            failedQueryCount.incrementAndGet();
                        }
                    }
                }
            }, ioReaderWriter.getResponseWriter().getResponseType()).header("X-Druid-Query-Id", queryId);
            transferEntityTag(responseContext, responseBuilder);
            DirectDruidClient.removeMagicResponseContextFields(responseContext);
            // Limit the response-context header, see https://github.com/apache/druid/issues/2331
            // Note that Response.ResponseBuilder.header(String key,Object value).build() calls value.toString()
            // and encodes the string using ASCII, so 1 char is = 1 byte
            final ResponseContext.SerializationResult serializationResult = responseContext.serializeWith(jsonMapper, responseContextConfig.getMaxResponseContextHeaderSize());
            if (serializationResult.isTruncated()) {
                final String logToPrint = StringUtils.format("Response Context truncated for id [%s]. Full context is [%s].", queryId, serializationResult.getFullResult());
                if (responseContextConfig.shouldFailOnTruncatedResponseContext()) {
                    log.error(logToPrint);
                    throw new QueryInterruptedException(new TruncatedResponseContextException("Serialized response context exceeds the max size[%s]", responseContextConfig.getMaxResponseContextHeaderSize()), selfNode.getHostAndPortToUse());
                } else {
                    log.warn(logToPrint);
                }
            }
            return responseBuilder.header(HEADER_RESPONSE_CONTEXT, serializationResult.getResult()).build();
        } catch (QueryException e) {
            // make sure to close yielder if anything happened before starting to serialize the response.
            yielder.close();
            throw e;
        } catch (Exception e) {
            // make sure to close yielder if anything happened before starting to serialize the response.
            yielder.close();
            throw new RuntimeException(e);
        } finally {
        // do not close yielder here, since we do not want to close the yielder prior to
        // StreamingOutput having iterated over all the results
        }
    } catch (QueryInterruptedException e) {
        interruptedQueryCount.incrementAndGet();
        queryLifecycle.emitLogsAndMetrics(e, req.getRemoteAddr(), -1);
        return ioReaderWriter.getResponseWriter().gotError(e);
    } catch (QueryTimeoutException timeout) {
        timedOutQueryCount.incrementAndGet();
        queryLifecycle.emitLogsAndMetrics(timeout, req.getRemoteAddr(), -1);
        return ioReaderWriter.getResponseWriter().gotTimeout(timeout);
    } catch (QueryCapacityExceededException cap) {
        failedQueryCount.incrementAndGet();
        queryLifecycle.emitLogsAndMetrics(cap, req.getRemoteAddr(), -1);
        return ioReaderWriter.getResponseWriter().gotLimited(cap);
    } catch (QueryUnsupportedException unsupported) {
        failedQueryCount.incrementAndGet();
        queryLifecycle.emitLogsAndMetrics(unsupported, req.getRemoteAddr(), -1);
        return ioReaderWriter.getResponseWriter().gotUnsupported(unsupported);
    } catch (BadJsonQueryException | ResourceLimitExceededException e) {
        interruptedQueryCount.incrementAndGet();
        queryLifecycle.emitLogsAndMetrics(e, req.getRemoteAddr(), -1);
        return ioReaderWriter.getResponseWriter().gotBadQuery(e);
    } catch (ForbiddenException e) {
        // send an error response if this is thrown.
        throw e;
    } catch (Exception e) {
        failedQueryCount.incrementAndGet();
        queryLifecycle.emitLogsAndMetrics(e, req.getRemoteAddr(), -1);
        log.noStackTrace().makeAlert(e, "Exception handling request").addData("query", query != null ? jsonMapper.writeValueAsString(query) : "unparseable query").addData("peer", req.getRemoteAddr()).emit();
        return ioReaderWriter.getResponseWriter().gotError(e);
    } finally {
        Thread.currentThread().setName(currThreadName);
    }
}
Also used : CountingOutputStream(com.google.common.io.CountingOutputStream) OutputStream(java.io.OutputStream) Access(org.apache.druid.server.security.Access) StreamingOutput(javax.ws.rs.core.StreamingOutput) QueryTimeoutException(org.apache.druid.query.QueryTimeoutException) CountingOutputStream(com.google.common.io.CountingOutputStream) ResponseContext(org.apache.druid.query.context.ResponseContext) QueryInterruptedException(org.apache.druid.query.QueryInterruptedException) ForbiddenException(org.apache.druid.server.security.ForbiddenException) QueryCapacityExceededException(org.apache.druid.query.QueryCapacityExceededException) TruncatedResponseContextException(org.apache.druid.query.TruncatedResponseContextException) QueryUnsupportedException(org.apache.druid.query.QueryUnsupportedException) ObjectWriter(com.fasterxml.jackson.databind.ObjectWriter) BadJsonQueryException(org.apache.druid.query.BadJsonQueryException) ForbiddenException(org.apache.druid.server.security.ForbiddenException) JsonParseException(com.fasterxml.jackson.core.JsonParseException) QueryTimeoutException(org.apache.druid.query.QueryTimeoutException) WebApplicationException(javax.ws.rs.WebApplicationException) QueryException(org.apache.druid.query.QueryException) BadQueryException(org.apache.druid.query.BadQueryException) QueryCapacityExceededException(org.apache.druid.query.QueryCapacityExceededException) QueryInterruptedException(org.apache.druid.query.QueryInterruptedException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException) TruncatedResponseContextException(org.apache.druid.query.TruncatedResponseContextException) ResourceLimitExceededException(org.apache.druid.query.ResourceLimitExceededException) QueryUnsupportedException(org.apache.druid.query.QueryUnsupportedException) Response(javax.ws.rs.core.Response) BadJsonQueryException(org.apache.druid.query.BadJsonQueryException) BadJsonQueryException(org.apache.druid.query.BadJsonQueryException) QueryException(org.apache.druid.query.QueryException) BadQueryException(org.apache.druid.query.BadQueryException) ResourceLimitExceededException(org.apache.druid.query.ResourceLimitExceededException) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) Consumes(javax.ws.rs.Consumes)

Example 10 with QueryException

use of org.apache.druid.query.QueryException in project druid by druid-io.

the class AsyncQueryForwardingServletTest method testHandleExceptionWithFilterDisabled.

@Test
public void testHandleExceptionWithFilterDisabled() throws Exception {
    String errorMessage = "test exception message";
    ObjectMapper mockMapper = Mockito.mock(ObjectMapper.class);
    HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
    ServletOutputStream outputStream = Mockito.mock(ServletOutputStream.class);
    Mockito.when(response.getOutputStream()).thenReturn(outputStream);
    final AsyncQueryForwardingServlet servlet = new AsyncQueryForwardingServlet(new MapQueryToolChestWarehouse(ImmutableMap.of()), mockMapper, TestHelper.makeSmileMapper(), null, null, null, new NoopServiceEmitter(), new NoopRequestLogger(), new DefaultGenericQueryMetricsFactory(), new AuthenticatorMapper(ImmutableMap.of()), new Properties(), new ServerConfig());
    Exception testException = new IllegalStateException(errorMessage);
    servlet.handleException(response, mockMapper, testException);
    ArgumentCaptor<Exception> captor = ArgumentCaptor.forClass(Exception.class);
    Mockito.verify(mockMapper).writeValue(ArgumentMatchers.eq(outputStream), captor.capture());
    Assert.assertTrue(captor.getValue() instanceof QueryException);
    Assert.assertEquals(QueryInterruptedException.UNKNOWN_EXCEPTION, ((QueryException) captor.getValue()).getErrorCode());
    Assert.assertEquals(errorMessage, captor.getValue().getMessage());
    Assert.assertEquals(IllegalStateException.class.getName(), ((QueryException) captor.getValue()).getErrorClass());
}
Also used : ServletOutputStream(javax.servlet.ServletOutputStream) HttpServletResponse(javax.servlet.http.HttpServletResponse) NoopRequestLogger(org.apache.druid.server.log.NoopRequestLogger) NoopServiceEmitter(org.apache.druid.server.metrics.NoopServiceEmitter) Properties(java.util.Properties) QueryException(org.apache.druid.query.QueryException) QueryInterruptedException(org.apache.druid.query.QueryInterruptedException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) IOException(java.io.IOException) AuthenticatorMapper(org.apache.druid.server.security.AuthenticatorMapper) ServerConfig(org.apache.druid.server.initialization.ServerConfig) QueryException(org.apache.druid.query.QueryException) MapQueryToolChestWarehouse(org.apache.druid.query.MapQueryToolChestWarehouse) DefaultGenericQueryMetricsFactory(org.apache.druid.query.DefaultGenericQueryMetricsFactory) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) BaseJettyTest(org.apache.druid.server.initialization.BaseJettyTest) Test(org.junit.Test)

Aggregations

QueryException (org.apache.druid.query.QueryException)25 Test (org.junit.Test)22 UnsupportedSQLQueryException (org.apache.druid.sql.calcite.planner.UnsupportedSQLQueryException)13 IOException (java.io.IOException)9 QueryInterruptedException (org.apache.druid.query.QueryInterruptedException)9 ServerConfig (org.apache.druid.server.initialization.ServerConfig)9 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)7 Response (javax.ws.rs.core.Response)7 AllowedRegexErrorResponseTransformStrategy (org.apache.druid.common.exception.AllowedRegexErrorResponseTransformStrategy)7 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)6 Properties (java.util.Properties)6 ServletOutputStream (javax.servlet.ServletOutputStream)6 HttpServletResponse (javax.servlet.http.HttpServletResponse)6 DefaultGenericQueryMetricsFactory (org.apache.druid.query.DefaultGenericQueryMetricsFactory)6 MapQueryToolChestWarehouse (org.apache.druid.query.MapQueryToolChestWarehouse)6 QueryUnsupportedException (org.apache.druid.query.QueryUnsupportedException)6 BaseJettyTest (org.apache.druid.server.initialization.BaseJettyTest)6 NoopRequestLogger (org.apache.druid.server.log.NoopRequestLogger)6 NoopServiceEmitter (org.apache.druid.server.metrics.NoopServiceEmitter)6 AuthenticatorMapper (org.apache.druid.server.security.AuthenticatorMapper)6