Search in sources :

Example 1 with KeyValueMetadata

use of io.confluent.ksql.util.KeyValueMetadata 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 2 with KeyValueMetadata

use of io.confluent.ksql.util.KeyValueMetadata in project ksql by confluentinc.

the class EndToEndIntegrationTest method verifyAvailableRows.

private static List<GenericRow> verifyAvailableRows(final TransientQueryMetadata queryMetadata, final int expectedRows) {
    final BlockingRowQueue rowQueue = queryMetadata.getRowQueue();
    assertThatEventually(expectedRows + " rows were not available after 30 seconds", () -> rowQueue.size() >= expectedRows, is(true), 30, TimeUnit.SECONDS);
    final List<KeyValueMetadata<List<?>, GenericRow>> rows = new ArrayList<>();
    rowQueue.drainTo(rows);
    return rows.stream().map(kvm -> kvm.getKeyValue().value()).collect(Collectors.toList());
}
Also used : Arrays(java.util.Arrays) Matchers.either(org.hamcrest.Matchers.either) KeyValue(io.confluent.ksql.util.KeyValue) BlockingRowQueue(io.confluent.ksql.query.BlockingRowQueue) AssertEventually.assertThatEventually(io.confluent.ksql.test.util.AssertEventually.assertThatEventually) LoggerFactory(org.slf4j.LoggerFactory) ConsumerRecords(org.apache.kafka.clients.consumer.ConsumerRecords) TransientQueryMetadata(io.confluent.ksql.util.TransientQueryMetadata) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) After(org.junit.After) QueryId(io.confluent.ksql.query.QueryId) ClassRule(org.junit.ClassRule) PersistentQueryMetadata(io.confluent.ksql.util.PersistentQueryMetadata) Parameterized(org.junit.runners.Parameterized) ZooKeeperClientException(kafka.zookeeper.ZooKeeperClientException) QueryMetadata(io.confluent.ksql.util.QueryMetadata) Configurable(org.apache.kafka.common.Configurable) KSQL_FUNCTIONS_PROPERTY_PREFIX(io.confluent.ksql.util.KsqlConfig.KSQL_FUNCTIONS_PROPERTY_PREFIX) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) Set(java.util.Set) ConsumerConfig(org.apache.kafka.clients.consumer.ConsumerConfig) KsqlConfig(io.confluent.ksql.util.KsqlConfig) TopicListing(org.apache.kafka.clients.admin.TopicListing) RecordMetadata(org.apache.kafka.clients.producer.RecordMetadata) Category(org.junit.experimental.categories.Category) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) Matchers.startsWith(org.hamcrest.Matchers.startsWith) Objects(java.util.Objects) List(java.util.List) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) Matchers.is(org.hamcrest.Matchers.is) UserDataProvider(io.confluent.ksql.util.UserDataProvider) KsqlConstants(io.confluent.ksql.util.KsqlConstants) ConsumerInterceptor(org.apache.kafka.clients.consumer.ConsumerInterceptor) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) StreamsConfig(org.apache.kafka.streams.StreamsConfig) PageViewDataProvider(io.confluent.ksql.util.PageViewDataProvider) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) JSON(io.confluent.ksql.serde.FormatFactory.JSON) ProducerInterceptor(org.apache.kafka.clients.producer.ProducerInterceptor) RunWith(org.junit.runner.RunWith) IntegrationTest(org.apache.kafka.test.IntegrationTest) AvroSchema(io.confluent.kafka.schemaregistry.avro.AvroSchema) ArrayList(java.util.ArrayList) KeyValueMetadata(io.confluent.ksql.util.KeyValueMetadata) Timeout(org.junit.rules.Timeout) Matchers.hasSize(org.hamcrest.Matchers.hasSize) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) ProducerConfig(org.apache.kafka.clients.producer.ProducerConfig) Before(org.junit.Before) UdfDescription(io.confluent.ksql.function.udf.UdfDescription) Logger(org.slf4j.Logger) Udf(io.confluent.ksql.function.udf.Udf) KAFKA(io.confluent.ksql.serde.FormatFactory.KAFKA) Test(org.junit.Test) TimeUnit(java.util.concurrent.TimeUnit) RuleChain(org.junit.rules.RuleChain) Matchers.hasItem(org.hamcrest.Matchers.hasItem) Rule(org.junit.Rule) GenericRow(io.confluent.ksql.GenericRow) Format(io.confluent.ksql.serde.Format) ListTopicsResult(org.apache.kafka.clients.admin.ListTopicsResult) ArrayList(java.util.ArrayList) KeyValueMetadata(io.confluent.ksql.util.KeyValueMetadata) BlockingRowQueue(io.confluent.ksql.query.BlockingRowQueue)

Aggregations

ImmutableMap (com.google.common.collect.ImmutableMap)2 GenericRow (io.confluent.ksql.GenericRow)2 BlockingRowQueue (io.confluent.ksql.query.BlockingRowQueue)2 QueryId (io.confluent.ksql.query.QueryId)2 KeyValue (io.confluent.ksql.util.KeyValue)2 KeyValueMetadata (io.confluent.ksql.util.KeyValueMetadata)2 KsqlConfig (io.confluent.ksql.util.KsqlConfig)2 QueryMetadata (io.confluent.ksql.util.QueryMetadata)2 TransientQueryMetadata (io.confluent.ksql.util.TransientQueryMetadata)2 Collection (java.util.Collection)2 List (java.util.List)2 Map (java.util.Map)2 Objects (java.util.Objects)2 TimeUnit (java.util.concurrent.TimeUnit)2 StreamsConfig (org.apache.kafka.streams.StreamsConfig)2 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)2 Matchers.is (org.hamcrest.Matchers.is)2 Before (org.junit.Before)2 Test (org.junit.Test)2 RunWith (org.junit.runner.RunWith)2