Search in sources :

Example 1 with MetricsCallbackHolder

use of io.confluent.ksql.api.server.MetricsCallbackHolder in project ksql by confluentinc.

the class StreamedQueryResourceTest method shouldNotCreateExternalClientsForPullQuery.

@Test
public void shouldNotCreateExternalClientsForPullQuery() {
    // Given:
    testResource.configure(new KsqlConfig(ImmutableMap.of(StreamsConfig.APPLICATION_SERVER_CONFIG, "something:1")));
    when(queryMetadataHolder.getPullQueryResult()).thenReturn(Optional.of(pullQueryResult));
    // When:
    testResource.streamQuery(securityContext, new KsqlRequest(PULL_QUERY_STRING, Collections.emptyMap(), Collections.emptyMap(), null), new CompletableFuture<>(), Optional.empty(), new MetricsCallbackHolder(), context);
    // Then:
    verify(serviceContext, never()).getAdminClient();
    verify(serviceContext, never()).getConnectClient();
    verify(serviceContext, never()).getSchemaRegistryClient();
    verify(serviceContext, never()).getTopicClient();
}
Also used : MetricsCallbackHolder(io.confluent.ksql.api.server.MetricsCallbackHolder) KsqlRequest(io.confluent.ksql.rest.entity.KsqlRequest) KsqlConfig(io.confluent.ksql.util.KsqlConfig) Test(org.junit.Test)

Example 2 with MetricsCallbackHolder

use of io.confluent.ksql.api.server.MetricsCallbackHolder in project ksql by confluentinc.

the class StreamedQueryResourceTest method shouldReturn400OnBadStatement.

@Test
public void shouldReturn400OnBadStatement() {
    // Given:
    when(mockStatementParser.parseSingleStatement(any())).thenThrow(new IllegalArgumentException("some error message"));
    // When:
    final KsqlRestException e = assertThrows(KsqlRestException.class, () -> testResource.streamQuery(securityContext, new KsqlRequest("query", Collections.emptyMap(), Collections.emptyMap(), null), new CompletableFuture<>(), Optional.empty(), new MetricsCallbackHolder(), context));
    // Then:
    assertThat(e, exceptionStatusCode(is(BAD_REQUEST.code())));
    assertThat(e, exceptionErrorMessage(errorMessage(is("some error message"))));
    assertThat(e, exceptionErrorMessage(errorCode(is(ERROR_CODE_BAD_STATEMENT))));
}
Also used : KsqlRestException(io.confluent.ksql.rest.server.resources.KsqlRestException) CompletableFuture(java.util.concurrent.CompletableFuture) MetricsCallbackHolder(io.confluent.ksql.api.server.MetricsCallbackHolder) KsqlRequest(io.confluent.ksql.rest.entity.KsqlRequest) Test(org.junit.Test)

Example 3 with MetricsCallbackHolder

use of io.confluent.ksql.api.server.MetricsCallbackHolder in project ksql by confluentinc.

the class StreamedQueryResourceTest method shouldStreamRowsCorrectly.

@Test
public void shouldStreamRowsCorrectly() throws Throwable {
    final int NUM_ROWS = 5;
    final AtomicReference<Throwable> threadException = new AtomicReference<>(null);
    final Thread.UncaughtExceptionHandler threadExceptionHandler = (thread, exception) -> threadException.compareAndSet(null, exception);
    final String queryString = "SELECT * FROM test_stream;";
    final SynchronousQueue<KeyValueMetadata<List<?>, GenericRow>> rowQueue = new SynchronousQueue<>();
    final LinkedList<GenericRow> writtenRows = new LinkedList<>();
    final Thread rowQueuePopulatorThread = new Thread(() -> {
        try {
            for (int i = 0; i != NUM_ROWS; i++) {
                final GenericRow value = genericRow(i);
                synchronized (writtenRows) {
                    writtenRows.add(value);
                }
                rowQueue.put(new KeyValueMetadata<>(KeyValue.keyValue(null, value)));
            }
        } catch (final InterruptedException exception) {
        // This should happen during the test, so it's fine
        }
    }, "Row Queue Populator");
    rowQueuePopulatorThread.setUncaughtExceptionHandler(threadExceptionHandler);
    rowQueuePopulatorThread.start();
    final KafkaStreams mockKafkaStreams = mock(KafkaStreams.class);
    when(mockStatementParser.<Query>parseSingleStatement(queryString)).thenReturn(query);
    final Map<String, Object> requestStreamsProperties = Collections.emptyMap();
    final KafkaStreamsBuilder kafkaStreamsBuilder = mock(KafkaStreamsBuilder.class);
    when(kafkaStreamsBuilder.build(any(), any())).thenReturn(mockKafkaStreams);
    MutableBoolean closed = new MutableBoolean(false);
    when(mockKafkaStreams.close(any())).thenAnswer(i -> {
        closed.setValue(true);
        return true;
    });
    when(mockKafkaStreams.state()).thenAnswer(i -> closed.getValue() ? State.NOT_RUNNING : State.RUNNING);
    final TransientQueryMetadata transientQueryMetadata = new TransientQueryMetadata(queryString, SOME_SCHEMA, Collections.emptySet(), "", new TestRowQueue(rowQueue), queryId, "appId", mock(Topology.class), kafkaStreamsBuilder, Collections.emptyMap(), Collections.emptyMap(), closeTimeout, 10, ResultType.STREAM, 0L, 0L, listener);
    transientQueryMetadata.initialize();
    when(queryMetadataHolder.getPushQueryMetadata()).thenReturn(Optional.of(transientQueryMetadata));
    final EndpointResponse response = testResource.streamQuery(securityContext, new KsqlRequest(queryString, requestStreamsProperties, Collections.emptyMap(), null), new CompletableFuture<>(), Optional.empty(), new MetricsCallbackHolder(), context);
    final PipedOutputStream responseOutputStream = new EOFPipedOutputStream();
    final PipedInputStream responseInputStream = new PipedInputStream(responseOutputStream, 1);
    final StreamingOutput responseStream = (StreamingOutput) response.getEntity();
    final Thread queryWriterThread = new Thread(() -> {
        try {
            responseStream.write(responseOutputStream);
        } catch (final EOFException exception) {
        // It's fine
        } catch (final IOException exception) {
            throw new RuntimeException(exception);
        }
    }, "Query Writer");
    queryWriterThread.setUncaughtExceptionHandler(threadExceptionHandler);
    queryWriterThread.start();
    final Scanner responseScanner = new Scanner(responseInputStream, "UTF-8");
    final ObjectMapper objectMapper = ApiJsonMapper.INSTANCE.get();
    for (int i = 0; i != NUM_ROWS; i++) {
        if (!responseScanner.hasNextLine()) {
            throw new Exception("Response input stream failed to have expected line available");
        }
        final String responseLine = responseScanner.nextLine();
        String jsonLine = StringUtils.stripStart(responseLine, "[");
        jsonLine = StringUtils.stripEnd(jsonLine, ",");
        jsonLine = StringUtils.stripEnd(jsonLine, "]");
        if (jsonLine.isEmpty()) {
            i--;
            continue;
        }
        if (i == 0) {
            // Header:
            assertThat(jsonLine, is("{\"header\":{\"queryId\":\"queryId\",\"schema\":\"`f1` INTEGER\"}}"));
            continue;
        }
        final GenericRow expectedRow;
        synchronized (writtenRows) {
            expectedRow = writtenRows.poll();
        }
        final DataRow testRow = objectMapper.readValue(jsonLine, StreamedRow.class).getRow().get();
        assertThat(testRow.getColumns(), is(expectedRow.values()));
    }
    responseOutputStream.close();
    queryWriterThread.join();
    rowQueuePopulatorThread.interrupt();
    rowQueuePopulatorThread.join();
    // Definitely want to make sure that the Kafka Streams instance has been closed and cleaned up
    verify(mockKafkaStreams).start();
    // called on init and when setting uncaught exception handler manually
    verify(mockKafkaStreams, times(2)).setUncaughtExceptionHandler(any(StreamsUncaughtExceptionHandler.class));
    verify(mockKafkaStreams).cleanUp();
    verify(mockKafkaStreams).close(Duration.ofMillis(closeTimeout));
    // If one of the other threads has somehow managed to throw an exception without breaking things up until this
    // point, we throw that exception now in the main thread and cause the test to fail
    final Throwable exception = threadException.get();
    if (exception != null) {
        throw exception;
    }
}
Also used : ERROR_CODE_BAD_STATEMENT(io.confluent.ksql.rest.Errors.ERROR_CODE_BAD_STATEMENT) ColumnName(io.confluent.ksql.name.ColumnName) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) KsqlTopicAuthorizationException(io.confluent.ksql.exception.KsqlTopicAuthorizationException) KsqlErrorMessage(io.confluent.ksql.rest.entity.KsqlErrorMessage) KsqlRestExceptionMatchers.exceptionStatementErrorMessage(io.confluent.ksql.rest.server.resources.KsqlRestExceptionMatchers.exceptionStatementErrorMessage) Mockito.doThrow(org.mockito.Mockito.doThrow) TransientQueryMetadata(io.confluent.ksql.util.TransientQueryMetadata) PipedInputStream(java.io.PipedInputStream) Duration(java.time.Duration) Map(java.util.Map) QueryId(io.confluent.ksql.query.QueryId) QueryMetadata(io.confluent.ksql.util.QueryMetadata) CommonClientConfigs(org.apache.kafka.clients.CommonClientConfigs) ConfiguredStatement(io.confluent.ksql.statement.ConfiguredStatement) State(org.apache.kafka.streams.KafkaStreams.State) ApiJsonMapper(io.confluent.ksql.rest.ApiJsonMapper) ActivenessRegistrar(io.confluent.ksql.version.metrics.ActivenessRegistrar) KsqlRestConfig(io.confluent.ksql.rest.server.KsqlRestConfig) SERVICE_UNAVAILABLE(io.netty.handler.codec.http.HttpResponseStatus.SERVICE_UNAVAILABLE) KsqlRestException(io.confluent.ksql.rest.server.resources.KsqlRestException) KsqlException(io.confluent.ksql.util.KsqlException) Matchers.is(org.hamcrest.Matchers.is) KsqlRequest(io.confluent.ksql.rest.entity.KsqlRequest) Matchers.containsString(org.hamcrest.Matchers.containsString) MockitoJUnitRunner(org.mockito.junit.MockitoJUnitRunner) PullQueryResult(io.confluent.ksql.physical.pull.PullQueryResult) Topology(org.apache.kafka.streams.Topology) Mockito.mock(org.mockito.Mockito.mock) StreamedRow(io.confluent.ksql.rest.entity.StreamedRow) Mock(org.mockito.Mock) RunWith(org.junit.runner.RunWith) KsqlRestExceptionMatchers.exceptionErrorMessage(io.confluent.ksql.rest.server.resources.KsqlRestExceptionMatchers.exceptionErrorMessage) ArgumentMatchers.anyBoolean(org.mockito.ArgumentMatchers.anyBoolean) KsqlSecurityContext(io.confluent.ksql.security.KsqlSecurityContext) SessionConfig(io.confluent.ksql.config.SessionConfig) KeyValueMetadata(io.confluent.ksql.util.KeyValueMetadata) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Before(org.junit.Before) CommandQueue(io.confluent.ksql.rest.server.computation.CommandQueue) KsqlEngine(io.confluent.ksql.engine.KsqlEngine) Mockito.times(org.mockito.Mockito.times) IOException(java.io.IOException) Test(org.junit.Test) PipedOutputStream(java.io.PipedOutputStream) AclOperation(org.apache.kafka.common.acl.AclOperation) StreamingOutput(io.confluent.ksql.api.server.StreamingOutput) Mockito.never(org.mockito.Mockito.never) GenericRow(io.confluent.ksql.GenericRow) QueryExecutor(io.confluent.ksql.rest.server.query.QueryExecutor) ERROR_CODE_FORBIDDEN_KAFKA_ACCESS(io.confluent.ksql.rest.Errors.ERROR_CODE_FORBIDDEN_KAFKA_ACCESS) KafkaStreams(org.apache.kafka.streams.KafkaStreams) SqlTypes(io.confluent.ksql.schema.ksql.types.SqlTypes) Assert.assertEquals(org.junit.Assert.assertEquals) PreparedStatement(io.confluent.ksql.parser.KsqlParser.PreparedStatement) Query(io.confluent.ksql.parser.tree.Query) KsqlStatementErrorMessageMatchers.statement(io.confluent.ksql.rest.entity.KsqlStatementErrorMessageMatchers.statement) CoreMatchers(org.hamcrest.CoreMatchers) SessionProperties(io.confluent.ksql.rest.SessionProperties) KeyValue(io.confluent.ksql.util.KeyValue) BlockingRowQueue(io.confluent.ksql.query.BlockingRowQueue) ServiceContext(io.confluent.ksql.services.ServiceContext) Scanner(java.util.Scanner) TimeoutException(java.util.concurrent.TimeoutException) DataRow(io.confluent.ksql.rest.entity.StreamedRow.DataRow) Context(io.vertx.core.Context) GenericRow.genericRow(io.confluent.ksql.GenericRow.genericRow) DenyListPropertyValidator(io.confluent.ksql.properties.DenyListPropertyValidator) KsqlAuthorizationValidator(io.confluent.ksql.security.KsqlAuthorizationValidator) LimitHandler(io.confluent.ksql.query.LimitHandler) ImmutableSet(com.google.common.collect.ImmutableSet) StringUtils(org.codehaus.plexus.util.StringUtils) ImmutableMap(com.google.common.collect.ImmutableMap) Errors(io.confluent.ksql.rest.Errors) SynchronousQueue(java.util.concurrent.SynchronousQueue) StatementParser(io.confluent.ksql.rest.server.StatementParser) Collection(java.util.Collection) KsqlConfig(io.confluent.ksql.util.KsqlConfig) LogicalSchema(io.confluent.ksql.schema.ksql.LogicalSchema) EOFException(java.io.EOFException) Objects(java.util.Objects) List(java.util.List) CompletionHandler(io.confluent.ksql.query.CompletionHandler) PrintTopic(io.confluent.ksql.parser.tree.PrintTopic) KsqlErrorMessageMatchers.errorCode(io.confluent.ksql.rest.entity.KsqlErrorMessageMatchers.errorCode) Optional(java.util.Optional) Statement(io.confluent.ksql.parser.tree.Statement) MutableBoolean(org.apache.commons.lang3.mutable.MutableBoolean) PullQueryQueue(io.confluent.ksql.query.PullQueryQueue) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) StreamsConfig(org.apache.kafka.streams.StreamsConfig) QueryMetadataHolder(io.confluent.ksql.rest.server.query.QueryMetadataHolder) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) FORBIDDEN(io.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN) Assert.assertThrows(org.junit.Assert.assertThrows) KafkaStreamsBuilder(io.confluent.ksql.query.KafkaStreamsBuilder) ResultType(io.confluent.ksql.util.PushQueryMetadata.ResultType) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) KafkaTopicClient(io.confluent.ksql.services.KafkaTopicClient) AtomicReference(java.util.concurrent.atomic.AtomicReference) Captor(org.mockito.Captor) BAD_REQUEST(io.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST) ArgumentCaptor(org.mockito.ArgumentCaptor) KsqlErrorMessageMatchers.errorMessage(io.confluent.ksql.rest.entity.KsqlErrorMessageMatchers.errorMessage) CustomValidators(io.confluent.ksql.rest.server.validation.CustomValidators) LinkedList(java.util.LinkedList) StreamsUncaughtExceptionHandler(org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) EndpointResponse(io.confluent.ksql.rest.EndpointResponse) Matchers(org.hamcrest.Matchers) Mockito.when(org.mockito.Mockito.when) MetricsCallbackHolder(io.confluent.ksql.api.server.MetricsCallbackHolder) KsqlRestExceptionMatchers.exceptionStatusCode(io.confluent.ksql.rest.server.resources.KsqlRestExceptionMatchers.exceptionStatusCode) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Errors.badRequest(io.confluent.ksql.rest.Errors.badRequest) Collections(java.util.Collections) Scanner(java.util.Scanner) Query(io.confluent.ksql.parser.tree.Query) MetricsCallbackHolder(io.confluent.ksql.api.server.MetricsCallbackHolder) KeyValueMetadata(io.confluent.ksql.util.KeyValueMetadata) PipedOutputStream(java.io.PipedOutputStream) StreamingOutput(io.confluent.ksql.api.server.StreamingOutput) Matchers.containsString(org.hamcrest.Matchers.containsString) DataRow(io.confluent.ksql.rest.entity.StreamedRow.DataRow) TransientQueryMetadata(io.confluent.ksql.util.TransientQueryMetadata) GenericRow(io.confluent.ksql.GenericRow) EndpointResponse(io.confluent.ksql.rest.EndpointResponse) KsqlRequest(io.confluent.ksql.rest.entity.KsqlRequest) SynchronousQueue(java.util.concurrent.SynchronousQueue) EOFException(java.io.EOFException) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) KafkaStreams(org.apache.kafka.streams.KafkaStreams) StreamsUncaughtExceptionHandler(org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler) MutableBoolean(org.apache.commons.lang3.mutable.MutableBoolean) AtomicReference(java.util.concurrent.atomic.AtomicReference) Topology(org.apache.kafka.streams.Topology) PipedInputStream(java.io.PipedInputStream) IOException(java.io.IOException) LinkedList(java.util.LinkedList) KsqlTopicAuthorizationException(io.confluent.ksql.exception.KsqlTopicAuthorizationException) KsqlRestException(io.confluent.ksql.rest.server.resources.KsqlRestException) KsqlException(io.confluent.ksql.util.KsqlException) IOException(java.io.IOException) TimeoutException(java.util.concurrent.TimeoutException) EOFException(java.io.EOFException) KafkaStreamsBuilder(io.confluent.ksql.query.KafkaStreamsBuilder) Test(org.junit.Test)

Example 4 with MetricsCallbackHolder

use of io.confluent.ksql.api.server.MetricsCallbackHolder in project ksql by confluentinc.

the class StreamedQueryResourceTest method shouldNotWaitIfCommandSequenceNumberSpecified.

@Test
public void shouldNotWaitIfCommandSequenceNumberSpecified() throws Exception {
    // When:
    testResource.streamQuery(securityContext, new KsqlRequest(PUSH_QUERY_STRING, Collections.emptyMap(), Collections.emptyMap(), null), new CompletableFuture<>(), Optional.empty(), new MetricsCallbackHolder(), context);
    // Then:
    verify(commandQueue, never()).ensureConsumedPast(anyLong(), any());
}
Also used : MetricsCallbackHolder(io.confluent.ksql.api.server.MetricsCallbackHolder) KsqlRequest(io.confluent.ksql.rest.entity.KsqlRequest) Test(org.junit.Test)

Example 5 with MetricsCallbackHolder

use of io.confluent.ksql.api.server.MetricsCallbackHolder in project ksql by confluentinc.

the class StreamedQueryResourceTest method shouldSuggestAlternativesIfPrintTopicDoesNotExist.

@Test
public void shouldSuggestAlternativesIfPrintTopicDoesNotExist() {
    // Given:
    final PrintTopic cmd = mock(PrintTopic.class);
    when(cmd.getTopic()).thenReturn("TEST_TOPIC");
    print = PreparedStatement.of("print", cmd);
    when(mockStatementParser.<PrintTopic>parseSingleStatement(any())).thenReturn(print);
    when(mockKafkaTopicClient.isTopicExists(any())).thenReturn(false);
    when(mockKafkaTopicClient.listTopicNames()).thenReturn(ImmutableSet.of("aTopic", "test_topic", "Test_Topic"));
    // When:
    final KsqlRestException e = assertThrows(KsqlRestException.class, () -> testResource.streamQuery(securityContext, new KsqlRequest(PRINT_TOPIC, Collections.emptyMap(), Collections.emptyMap(), null), new CompletableFuture<>(), Optional.empty(), new MetricsCallbackHolder(), context));
    // Then:
    assertThat(e, exceptionStatusCode(is(BAD_REQUEST.code())));
    assertThat(e, exceptionErrorMessage(errorMessage(containsString("Could not find topic 'TEST_TOPIC', " + "or the KSQL user does not have permissions to list the topic. " + "Topic names are case-sensitive." + System.lineSeparator() + "Did you mean:"))));
    assertThat(e, exceptionErrorMessage(errorMessage(containsString("\tprint test_topic;"))));
    assertThat(e, exceptionErrorMessage(errorMessage(containsString("\tprint Test_Topic;"))));
}
Also used : KsqlRestException(io.confluent.ksql.rest.server.resources.KsqlRestException) CompletableFuture(java.util.concurrent.CompletableFuture) MetricsCallbackHolder(io.confluent.ksql.api.server.MetricsCallbackHolder) KsqlRequest(io.confluent.ksql.rest.entity.KsqlRequest) PrintTopic(io.confluent.ksql.parser.tree.PrintTopic) Test(org.junit.Test)

Aggregations

MetricsCallbackHolder (io.confluent.ksql.api.server.MetricsCallbackHolder)14 KsqlRequest (io.confluent.ksql.rest.entity.KsqlRequest)13 Test (org.junit.Test)13 Query (io.confluent.ksql.parser.tree.Query)5 EndpointResponse (io.confluent.ksql.rest.EndpointResponse)5 KsqlRestException (io.confluent.ksql.rest.server.resources.KsqlRestException)5 CompletableFuture (java.util.concurrent.CompletableFuture)5 KsqlTopicAuthorizationException (io.confluent.ksql.exception.KsqlTopicAuthorizationException)4 PrintTopic (io.confluent.ksql.parser.tree.PrintTopic)3 KsqlErrorMessage (io.confluent.ksql.rest.entity.KsqlErrorMessage)3 KsqlConfig (io.confluent.ksql.util.KsqlConfig)3 StreamedRow (io.confluent.ksql.rest.entity.StreamedRow)2 QueryMetadataHolder (io.confluent.ksql.rest.server.query.QueryMetadataHolder)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 GenericRow (io.confluent.ksql.GenericRow)1 GenericRow.genericRow (io.confluent.ksql.GenericRow.genericRow)1 StreamingOutput (io.confluent.ksql.api.server.StreamingOutput)1 SessionConfig (io.confluent.ksql.config.SessionConfig)1