コード例 #1
0
        internal StringContent CreateContent(KSqlDbStatement ksqlDbStatement)
        {
            var json = JsonSerializer.Serialize(ksqlDbStatement);

            var data = new StringContent(json, ksqlDbStatement.ContentEncoding, MediaType);

            return(data);
        }
コード例 #2
0
    public void StatementText_WasSet()
    {
        //Arrange
        var ksqlDbStatement = new KSqlDbStatement(Statement);

        //Act
        var statementText = ksqlDbStatement.Sql;

        //Assert
        statementText.Should().Be(Statement);
    }
コード例 #3
0
    public void ContentEncoding_DefaultIsUTF8()
    {
        //Arrange
        var ksqlDbStatement = new KSqlDbStatement(Statement);

        //Act
        var defaultEncoding = ksqlDbStatement.ContentEncoding;

        //Assert
        defaultEncoding.Should().Be(Encoding.UTF8);
    }
コード例 #4
0
    public void GetEndpoint_DefaultIs_KSql()
    {
        //Arrange
        var ksqlDbStatement = new KSqlDbStatement(createOrReplaceTableStatement);

        //Act
        var endpoint = KSqlDbRestApiClient.GetEndpoint(ksqlDbStatement);

        //Assert
        endpoint.Should().Be("/ksql");
    }
コード例 #5
0
    public void EndpointType_DefaultIsKSql()
    {
        //Arrange
        var ksqlDbStatement = new KSqlDbStatement(Statement);

        //Act
        var endpointType = ksqlDbStatement.EndpointType;

        //Assert
        endpointType.Should().Be(EndpointType.KSql);
    }
コード例 #6
0
    public void CreateContent_MediaTypeAndCharsetWereApplied()
    {
        //Arrange
        var ksqlDbStatement = new KSqlDbStatement(createOrReplaceTableStatement);

        //Act
        var stringContent = ClassUnderTest.CreateContent(ksqlDbStatement);

        //Assert
        stringContent.Headers.ContentType.MediaType.Should().Be(KSqlDbRestApiClient.MediaType);
        stringContent.Headers.ContentType.CharSet.Should().Be(Encoding.UTF8.WebName);
    }
コード例 #7
0
        internal static string GetEndpoint(KSqlDbStatement ksqlDbStatement)
        {
            var endpoint = ksqlDbStatement.EndpointType switch
            {
                EndpointType.KSql => "/ksql",
                EndpointType.Query => "/query",
                _ => throw new ArgumentOutOfRangeException()
            };

            return(endpoint);
        }
    }
コード例 #8
0
    public async Task CreateContent_KSqlContentWasSet()
    {
        //Arrange
        var ksqlDbStatement = new KSqlDbStatement(createOrReplaceTableStatement);

        //Act
        var stringContent = ClassUnderTest.CreateContent(ksqlDbStatement);

        //Assert
        var content = await GetContent(stringContent);

        content.Should().Be(@$ "{{" "ksql" ":" "{createOrReplaceTableStatement}" "," "streamsProperties" ":{{}}}}");
    }
コード例 #9
0
        internal HttpRequestMessage CreateHttpRequestMessage(KSqlDbStatement ksqlDbStatement)
        {
            var data = CreateContent(ksqlDbStatement);

            var endpoint = GetEndpoint(ksqlDbStatement);

            var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, endpoint)
            {
                Content = data
            };

            return(httpRequestMessage);
        }
コード例 #10
0
        public async Task ExecuteStatementAsync_HttpClientWasCalled_OkResult()
        {
            //Arrange
            var ksqlDbStatement = new KSqlDbStatement(statement);

            //Act
            var httpResponseMessage = await ClassUnderTest.ExecuteStatementAsync(ksqlDbStatement);

            //Assert
            httpResponseMessage.Should().NotBeNull();

            Mock.Get(HttpClientFactory).Verify(c => c.CreateClient(), Times.Once);
        }
コード例 #11
0
    public void CreateHttpRequestMessage_HttpRequestMessage_WasConfigured()
    {
        //Arrange
        var ksqlDbStatement = new KSqlDbStatement(createOrReplaceTableStatement);

        //Act
        var httpRequestMessage = ClassUnderTest.CreateHttpRequestMessage(ksqlDbStatement);

        //Assert
        httpRequestMessage.Method.Should().Be(HttpMethod.Post);
        httpRequestMessage.RequestUri.Should().Be("/ksql");
        httpRequestMessage.Content.Headers.ContentType.MediaType.Should().Be(KSqlDbRestApiClient.MediaType);
    }
コード例 #12
0
        private Task <HttpResponseMessage> ExecuteStatementAsync(KSqlDbStatement ksqlDbStatement, CancellationToken cancellationToken = default)
        {
            var httpClient = new HttpClient()
            {
                BaseAddress = ksqlDbUrl
            };

            var httpClientFactory = new HttpClientFactory(httpClient);

            var restApiClient = new KSqlDbRestApiClient(httpClientFactory);

            return(restApiClient.ExecuteStatementAsync(ksqlDbStatement, cancellationToken));
        }
コード例 #13
0
    public async Task CreateHttpRequestMessage_HttpRequestMessage_ContentWasSet()
    {
        //Arrange
        var ksqlDbStatement = new KSqlDbStatement(createOrReplaceTableStatement);

        //Act
        var httpRequestMessage = ClassUnderTest.CreateHttpRequestMessage(ksqlDbStatement);

        //Assert
        var content = await httpRequestMessage.Content.ReadAsStringAsync();

        content.Should().Be(@$ "{{" "ksql" ":" "{createOrReplaceTableStatement}" "," "streamsProperties" ":{{}}}}");
    }
コード例 #14
0
        public async Task <HttpResponseMessage> ExecuteStatementAsync(KSqlDbStatement ksqlDbStatement, CancellationToken cancellationToken = default)
        {
            using var httpClient = httpClientFactory.CreateClient();

            var httpRequestMessage = CreateHttpRequestMessage(ksqlDbStatement);

            httpClient.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue(MediaType));

            var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage, cancellationToken)
                                      .ConfigureAwait(false);

            return(httpResponseMessage);
        }
コード例 #15
0
    public void GetEndpoint_OverridenToQueryEndpoint()
    {
        //Arrange
        var ksqlDbStatement = new KSqlDbStatement(createOrReplaceTableStatement)
        {
            EndpointType = EndpointType.Query
        };

        //Act
        var endpoint = KSqlDbRestApiClient.GetEndpoint(ksqlDbStatement);

        //Assert
        endpoint.Should().Be("/query");
    }
コード例 #16
0
    public async Task CreateOrReplaceStreamStatement_ToStatementString_ComplexQueryWasGenerated()
    {
        //Arrange
        var restApiClient = KSqlDbRestApiProvider.Create();

        var statement = new KSqlDbStatement(StatementTemplates.DropStream(StreamName));
        var response  = await restApiClient.ExecuteStatementAsync(statement);

        EntityCreationMetadata metadata = new()
        {
            EntityName = StreamEntityName,
            KafkaTopic = nameof(Movie) + "Test2",
            Partitions = 1,
            Replicas   = 1
        };

        var httpResponseMessage =
            await restApiClient.CreateStreamAsync <Movie>(metadata, ifNotExists : false);

        var creationMetadata = new CreationMetadata
        {
            KafkaTopic  = "moviesByTitle",
            KeyFormat   = SerializationFormats.Json,
            ValueFormat = SerializationFormats.Json,
            Replicas    = 1,
            Partitions  = 1
        };

        var createStatement = Context.CreateOrReplaceStreamStatement(StreamName)
                              .With(creationMetadata)
                              .As <Movie>(StreamEntityName)
                              .Where(c => c.Id < 3)
                              .Select(c => new { c.Id, c.Title, ReleaseYear = c.Release_Year })
                              .PartitionBy(c => c.Id);

        //Act
        var ksql = createStatement.ToStatementString();

        httpResponseMessage = await createStatement.ExecuteStatementAsync();

        //Assert
        ksql.Should().BeEquivalentTo(@$ "CREATE OR REPLACE STREAM {StreamName}
 WITH ( KAFKA_TOPIC='moviesByTitle', KEY_FORMAT='Json', VALUE_FORMAT='Json', PARTITIONS='1', REPLICAS='1' )
AS SELECT Id, Title, Release_Year AS ReleaseYear FROM {StreamEntityName}
WHERE Id < 3 PARTITION BY Id EMIT CHANGES;");

        var responses = await httpResponseMessage.ToStatementResponsesAsync();

        responses[0].CommandStatus.Status.Should().BeOneOf("SUCCESS", "EXECUTING");
    }
コード例 #17
0
        public Task <HttpResponseMessage> ExecuteStatementAsync(CancellationToken cancellationToken = default)
        {
            serviceScope = serviceScopeFactory.CreateScope();

            cancellationToken.Register(() => serviceScope?.Dispose());

            var restApiClient = serviceScope.ServiceProvider.GetService <IKSqlDbRestApiClient>();

            serviceScope.Dispose();

            var ksqlQuery = BuildKsql();

            var dBStatement = new KSqlDbStatement(ksqlQuery);

            return(restApiClient?.ExecuteStatementAsync(dBStatement, cancellationToken));
        }
コード例 #18
0
    public void CreateContent_Encoding_OverridenCharsetWasApplied()
    {
        //Arrange
        var encoding = Encoding.Unicode;

        var ksqlDbStatement = new KSqlDbStatement(createOrReplaceTableStatement)
        {
            ContentEncoding = encoding
        };

        //Act
        var stringContent = ClassUnderTest.CreateContent(ksqlDbStatement);

        //Assert
        stringContent.Headers.ContentType.CharSet.Should().Be(encoding.WebName);
    }
コード例 #19
0
    public async Task ExecuteStatementAsync_LogInformation()
    {
        //Arrange
        CreateHttpMocks(StatementResponse);

        var ksqlDbStatement = new KSqlDbStatement(createOrReplaceTableStatement);

        //Act
        var httpResponseMessage = await ClassUnderTest.ExecuteStatementAsync(ksqlDbStatement);

        //Assert
        httpResponseMessage.Should().NotBeNull();

        LoggerMock.VerifyLog(LogLevel.Debug, Times.Once);
        LoggerMock.VerifyLog(LogLevel.Information, Times.Once);
    }
コード例 #20
0
    public async Task CreateContent_CommandSequenceNumber()
    {
        //Arrange
        long commandSequenceNumber = 1000;
        var  ksqlDbStatement       = new KSqlDbStatement(createOrReplaceTableStatement)
        {
            CommandSequenceNumber = commandSequenceNumber
        };

        //Act
        var stringContent = ClassUnderTest.CreateContent(ksqlDbStatement);

        //Assert
        var content = await GetContent(stringContent);

        content.Should().Be(@$ "{{" "commandSequenceNumber" ":{commandSequenceNumber}," "ksql" ":" "{createOrReplaceTableStatement}" "," "streamsProperties" ":{{}}}}");
    }
コード例 #21
0
        public async Task ExecuteStatementAsync_HttpClientWasCalled_OkResult()
        {
            //Arrange
            var ksqlDbStatement = new KSqlDbStatement(statement);
            var restApiClient   = new KSqlDbRestApiClient(HttpClientFactory);

            var httpResponseMessage = await restApiClient.ExecuteStatementAsync(ksqlDbStatement);

            //Act
            var responses = httpResponseMessage.ToStatementResponses();

            //Assert
            responses[0].CommandStatus.Message.Should().Be("Table created");
            responses[0].CommandStatus.Status.Should().Be("SUCCESS");
            responses[0].CommandId.Should().Be("table/`MOVIES`/create");
            responses[0].CommandSequenceNumber.Should().Be(328);
        }
コード例 #22
0
    public async Task CreateOrReplaceTableStatement_ExecuteStatementAsync_ResponseWasReceived()
    {
        //Arrange
        var restApiClient = KSqlDbRestApiProvider.Create();

        await restApiClient.CreateStreamAsync <Movie>(new EntityCreationMetadata(EntityName, 1) { EntityName = EntityName, ShouldPluralizeEntityName = false });

        var statement = new KSqlDbStatement(StatementTemplates.DropTable(TableName));
        var response  = await restApiClient.ExecuteStatementAsync(statement);

        int retryCount = 0;

        while ((await KSqlDbRestApiProvider.Create().GetTablesAsync()).SelectMany(c => c.Tables).Any(c => c.Name == TableName.ToUpper()))
        {
            if (retryCount++ > 5)
            {
                return;
            }

            await Task.Delay(TimeSpan.FromSeconds(1));
        }

        var createStatement = Context.CreateTableStatement(TableName)
                              .As <Movie>(EntityName)
                              .GroupBy(c => c.Title)
                              .Select(c => new { Title = c.Key, Count = c.Count() });

        //Act
        var httpResponseMessage = await createStatement.ExecuteStatementAsync();

        //Assert
        string responseContent = await httpResponseMessage.Content.ReadAsStringAsync();

        responseContent.Should().NotBeNull();

        var responses = await httpResponseMessage.ToStatementResponsesAsync();

        responses[0].CommandStatus.Status.Should().Be("SUCCESS");
    }
コード例 #23
0
    public async Task <bool> CreateTablesAsync()
    {
        var createMoviesTable = $@"CREATE OR REPLACE TABLE {MoviesTableName} (
        title VARCHAR PRIMARY KEY,
        id INT,
        release_year INT
      ) WITH (
        KAFKA_TOPIC='{MoviesTableName}',
        PARTITIONS=1,
        VALUE_FORMAT = 'JSON'
      );";

        KSqlDbStatement ksqlDbStatement = new(createMoviesTable);

        var result = await restApiProvider.ExecuteStatementAsync(ksqlDbStatement);

        var isSuccess = result.IsSuccess();

        isSuccess.Should().BeTrue();

        var createActorsTable = $@"CREATE OR REPLACE TABLE {ActorsTableName} (
        title VARCHAR PRIMARY KEY,
        actor_name VARCHAR
      ) WITH (
        KAFKA_TOPIC='{ActorsTableName}',
        PARTITIONS=1,
        VALUE_FORMAT='JSON'
      );";

        ksqlDbStatement = new KSqlDbStatement(createActorsTable);

        result = await restApiProvider.ExecuteStatementAsync(ksqlDbStatement);

        isSuccess = result.IsSuccess();

        isSuccess.Should().BeTrue();

        return(true);
    }
コード例 #24
0
    public static async Task ClassInitialize(TestContext context)
    {
        RestApiProvider = KSqlDbRestApiProvider.Create();

        var statement =
            new KSqlDbStatement(
                @"CREATE STREAM stream2 (id INT, lambda_arr ARRAY<INTEGER>) WITH (kafka_topic = 'stream2', partitions = 1, value_format = 'json');");

        var response = await RestApiProvider.ExecuteStatementAsync(statement);

        var statement2 =
            new KSqlDbStatement(
                @"CREATE OR REPLACE STREAM stream4 (id INT, lambda_map MAP<STRING,ARRAY<INTEGER>>) WITH (kafka_topic = 'stream4', partitions = 1, value_format = 'json');");

        response = await RestApiProvider.ExecuteStatementAsync(statement2);

        string insertIntoStream3 = "insert into stream4 (id, lambda_map) values (1, MAP('hello':= ARRAY [1,2,3], 'goodbye':= ARRAY [-1,-2,-3]) );";

        response = await RestApiProvider.ExecuteStatementAsync(
            new KSqlDbStatement("insert into stream2 (id, lambda_arr) values (1, ARRAY [1,2,3]);"));

        response = await RestApiProvider.ExecuteStatementAsync(
            new KSqlDbStatement(insertIntoStream3));
    }
コード例 #25
0
 internal HttpRequestMessage CreateHttpRequestMessage(KSqlDbStatement ksqlDbStatement)
 {
     return(CreateHttpRequestMessage(ksqlDbStatement, ksqlDbStatement.EndpointType, ksqlDbStatement.ContentEncoding));
 }
コード例 #26
0
 internal static string GetEndpoint(KSqlDbStatement ksqlDbStatement)
 {
     return(GetEndpoint(ksqlDbStatement.EndpointType));
 }
コード例 #27
0
    private Task <HttpResponseMessage> ExecuteAsync <T>(string ksql, CancellationToken cancellationToken = default)
    {
        var ksqlStatement = new KSqlDbStatement(ksql);

        return(ExecuteStatementAsync(ksqlStatement, cancellationToken));
    }
コード例 #28
0
    /// <summary>
    /// Run a sequence of SQL statements.
    /// </summary>
    /// <param name="ksqlDbStatement">The text of the SQL statements.</param>
    /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
    /// <returns></returns>
    public Task <HttpResponseMessage> ExecuteStatementAsync(KSqlDbStatement ksqlDbStatement, CancellationToken cancellationToken = default)
    {
        logger?.LogInformation($"Executing command: {ksqlDbStatement.Sql}");

        return(ExecuteStatementAsync(ksqlDbStatement, ksqlDbStatement.EndpointType, ksqlDbStatement.ContentEncoding, cancellationToken));
    }
コード例 #29
0
 internal StringContent CreateContent(KSqlDbStatement ksqlDbStatement)
 {
     return(CreateContent(ksqlDbStatement, ksqlDbStatement.ContentEncoding));
 }