예제 #1
0
 def setUp(self):
     self.url = "http://localhost:8088"
     self.api_client = KSQLAPI(url=self.url, check_version=False)
     self.test_prefix = "ksql_python_test"
     self.exist_topic = 'exist_topic'
     self.bootstrap_servers = 'localhost:29092'
     if utils.check_kafka_available(self.bootstrap_servers):
         producer = Producer({'bootstrap.servers': self.bootstrap_servers})
         producer.produce(self.exist_topic, "test_message")
         producer.flush()
예제 #2
0
 def __init__(self):
     url = "http://localhost:8088"
     self.api_client = KSQLAPI(url)
     self.topic = "test08"
     self.bootstrap_servers = "localhost:9092"
     if utils.check_kafka_available(self.bootstrap_servers):
         value_schema_str = """ 
         { 
             "type": "record", 
             "namespace": "com.example", 
             "name": "value", 
             "fields": [ 
                 {"name":"LOCATION", "type":"string"}, 
                 {"name":"DATETIME", "type":"string"}, 
                 {"name":"SENTIMENT", "type":"string"}, 
                 {"name":"TEXT", "type":"string"} 
             ] 
         } 
         """
         key_schema_str = """ 
         { 
             "type": "record", 
             "namespace": "com.example", 
             "name": "key", 
             "fields": [ 
                 {"name":"LOCATION", "type":"string"}, 
                 {"name":"DATETIME", "type":"string"}, 
                 {"name":"SENTIMENT", "type":"string"}, 
                 {"name":"TEXT", "type":"string"} 
             ] 
         } 
         """
         value_schema = avro.loads(value_schema_str)
         key_schema = avro.loads(key_schema_str)
         self.key = {
             "LOCATION": "LOCATION",
             "DATETIME": "DATETIME",
             "SENTIMENT": "SENTIMENT",
             "TEXT": "TEXT"
         }
         self.producer = AvroProducer(
             {
                 'bootstrap.servers': self.bootstrap_servers,
                 'on_delivery': delivery_report,
                 'schema.registry.url': 'http://localhost:8081'
             },
             default_key_schema=None,
             default_value_schema=value_schema)
     else:
         print("Could not connect to Kafka")
         exit(-1)
예제 #3
0
 def tearDown(self):
     if utils.check_kafka_available(self.bootstrap_servers):
         utils.drop_all_streams(self.api_client, prefix=self.test_prefix)
예제 #4
0
class TestKSQLAPI(unittest.TestCase):
    """Test case for the client methods."""
    def setUp(self):
        self.url = "http://*****:*****@vcr.use_cassette('tests/vcr_cassettes/healthcheck.yml')
    def test_ksql_server_healthcheck(self):
        """ Test GET requests """
        res = requests.get(self.url + '/status')
        self.assertEqual(res.status_code, 200)

    @vcr.use_cassette('tests/vcr_cassettes/get_ksql_server.yml')
    def test_get_ksql_version_success(self):
        """ Test GET requests """
        version = self.api_client.get_ksql_version()
        self.assertEqual(version, ksql.__ksql_server_version__)

    @vcr.use_cassette('tests/vcr_cassettes/get_properties.yml')
    def test_get_properties(self):
        properties = self.api_client.get_properties()
        self.assertEqual(properties['ksql.schema.registry.url'],
                         "http://*****:*****@vcr.use_cassette('tests/vcr_cassettes/ksql_show_table.yml')
    def test_ksql_show_tables(self):
        """ Test GET requests """
        ksql_string = "show tables;"
        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r, [{
            '@type': 'tables',
            'statementText': 'show tables;',
            'tables': []
        }])

    @vcr.use_cassette('tests/vcr_cassettes/ksql_show_table.yml')
    def test_ksql_show_tables_with_no_semicolon(self):
        """ Test GET requests """
        ksql_string = "show tables"
        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r, [{
            '@type': 'tables',
            'statementText': 'show tables;',
            'tables': []
        }])

    @vcr.use_cassette('tests/vcr_cassettes/ksql_create_stream.yml')
    def test_ksql_create_stream(self):
        """ Test GET requests """
        topic = self.exist_topic
        stream_name = self.test_prefix + "test_ksql_create_stream"
        ksql_string = "CREATE STREAM {} (viewtime bigint, userid varchar, pageid varchar) \
                       WITH (kafka_topic='{}', value_format='DELIMITED');".format(
            stream_name, topic)
        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r[0]['commandStatus']['status'], 'SUCCESS')

    @unittest.skipIf(not utils.check_kafka_available('localhost:29092'),
                     "vcrpy does not support streams yet")
    def test_ksql_create_stream_w_properties(self):
        """ Test GET requests """
        topic = self.exist_topic
        stream_name = self.test_prefix + "test_ksql_create_stream"
        stream_name = "test_ksql_create_stream"
        ksql_string = "CREATE STREAM {} (ORDER_ID INT, TOTAL_AMOUNT DOUBLE, CUSTOMER_NAME VARCHAR) \
                       WITH (kafka_topic='{}', value_format='JSON');".format(
            stream_name, topic)
        streamProperties = {"ksql.streams.auto.offset.reset": "earliest"}
        if 'TEST_KSQL_CREATE_STREAM' not in utils.get_all_streams(
                self.api_client):
            r = self.api_client.ksql(ksql_string,
                                     stream_properties=streamProperties)
            self.assertEqual(r[0]['commandStatus']['status'], 'SUCCESS')
        producer = Producer({'bootstrap.servers': self.bootstrap_servers})
        producer.produce(
            self.exist_topic,
            '''{"order_id":3,"total_amount":43,"customer_name":"Palo Alto"}''')
        producer.flush()
        print()
        chunks = self.api_client.query("select * from {}".format(stream_name),
                                       stream_properties=streamProperties,
                                       idle_timeout=10)
        for chunk in chunks:
            pass
            assert json.loads(chunk)['row']['columns'][-1] == 'Palo Alto'

    @vcr.use_cassette('tests/vcr_cassettes/bad_requests.yml')
    def test_bad_requests(self):
        broken_ksql_string = "noi"
        with self.assertRaises(KSQLError) as e:
            r = self.api_client.ksql(broken_ksql_string)
        the_exception = e.exception
        self.assertEqual(the_exception.error_code, 40000)

    @vcr.use_cassette('tests/vcr_cassettes/ksql_create_stream_by_builder.yml')
    def test_ksql_create_stream_by_builder(self):
        sql_type = 'create'
        table_type = 'stream'
        table_name = 'test_table'
        columns_type = ['viewtime bigint', 'userid varchar', 'pageid varchar']
        topic = self.exist_topic
        value_format = 'DELIMITED'

        utils.drop_stream(self.api_client, table_name)

        ksql_string = SQLBuilder.build(sql_type=sql_type,
                                       table_type=table_type,
                                       table_name=table_name,
                                       columns_type=columns_type,
                                       topic=topic,
                                       value_format=value_format)

        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r[0]['commandStatus']['status'], 'SUCCESS')

    @vcr.use_cassette(
        'tests/vcr_cassettes/ksql_create_stream_by_builder_api.yml')
    def test_ksql_create_stream_by_builder_api(self):
        table_name = 'test_table'
        columns_type = ['viewtime bigint', 'userid varchar', 'pageid varchar']
        topic = self.exist_topic
        value_format = 'DELIMITED'

        utils.drop_stream(self.api_client, table_name)

        r = self.api_client.create_stream(table_name=table_name,
                                          columns_type=columns_type,
                                          topic=topic,
                                          value_format=value_format)

        self.assertTrue(r)

    @vcr.use_cassette('tests/vcr_cassettes/ksql_topic_already_registered.yml')
    def test_raise_create_error_topic_already_registered(self):
        table_name = 'foo_table'
        columns_type = ['name string', 'age bigint']
        topic = self.exist_topic
        value_format = 'DELIMITED'
        utils.drop_stream(self.api_client, table_name)
        r = self.api_client.create_stream(table_name=table_name,
                                          columns_type=columns_type,
                                          topic=topic,
                                          value_format=value_format)

        with self.assertRaises(KSQLError):
            r = self.api_client.create_stream(table_name=table_name,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)

    @vcr.use_cassette('tests/vcr_cassettes/raise_create_error_no_topic.yml')
    def test_raise_create_error_no_topic(self):
        table_name = 'foo_table'
        columns_type = ['name string', 'age bigint']
        topic = 'this_topic_is_not_exist'
        value_format = 'DELIMITED'

        with self.assertRaises(KSQLError):
            r = self.api_client.create_stream(table_name=table_name,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)

    @vcr.use_cassette(
        'tests/vcr_cassettes/ksql_create_stream_as_without_conditions.yml')
    def test_create_stream_as_without_conditions(self):

        src_table = 'pageviews_original'
        columns_type = [
            'name string', 'age bigint', 'userid string', 'pageid bigint'
        ]
        topic = self.exist_topic

        table_name = 'create_stream_as_without_conditions'
        kafka_topic = 'create_stream_as_without_conditions'
        value_format = 'DELIMITED'
        select_columns = ['rowtime as logtime', '*']

        try:
            r = self.api_client.create_stream(table_name=src_table,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)
        except KSQLError as e:
            pass

        r = self.api_client.create_stream_as(table_name=table_name,
                                             src_table=src_table,
                                             kafka_topic=kafka_topic,
                                             select_columns=select_columns,
                                             timestamp='logtime',
                                             value_format=value_format)
        self.assertTrue(r)

    @vcr.use_cassette(
        'tests/vcr_cassettes/ksql_create_stream_as_with_conditions_without_startwith.yml'
    )
    def test_create_stream_as_with_conditions_without_startwith(self):

        src_table = 'pageviews_original'
        columns_type = [
            'name string', 'age bigint', 'userid string', 'pageid bigint'
        ]
        topic = self.exist_topic

        table_name = 'create_stream_as_with_conditions_without_startwith'
        kafka_topic = 'create_stream_as_with_conditions_without_startwith'
        value_format = 'DELIMITED'
        select_columns = ['rowtime as logtime', '*']
        conditions = "userid = 'foo'"

        try:
            r = self.api_client.create_stream(table_name=src_table,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)
        except KSQLError as e:
            pass

        r = self.api_client.create_stream_as(table_name=table_name,
                                             src_table=src_table,
                                             kafka_topic=kafka_topic,
                                             select_columns=select_columns,
                                             timestamp='logtime',
                                             value_format=value_format,
                                             conditions=conditions)

        self.assertTrue(r)

    @vcr.use_cassette(
        'tests/vcr_cassettes/ksql_create_stream_as_with_conditions_with_startwith.yml'
    )
    def test_create_stream_as_with_conditions_with_startwith(self):

        src_table = 'pageviews_original'
        columns_type = [
            'name string', 'age bigint', 'userid string', 'pageid bigint'
        ]
        topic = self.exist_topic

        table_name = 'create_stream_as_with_conditions_with_startwith'
        kafka_topic = 'create_stream_as_with_conditions_with_startwith'
        value_format = 'DELIMITED'
        select_columns = ['rowtime as logtime', '*']
        conditions = "userid = 'foo_%'"
        utils.drop_stream(self.api_client, src_table)
        utils.drop_stream(self.api_client, table_name)

        try:
            r = self.api_client.create_stream(table_name=src_table,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)
        except KSQLError as e:
            pass

        r = self.api_client.create_stream_as(table_name=table_name,
                                             src_table=src_table,
                                             kafka_topic=kafka_topic,
                                             select_columns=select_columns,
                                             timestamp='logtime',
                                             value_format=value_format,
                                             conditions=conditions)

        self.assertTrue(r)

    @vcr.use_cassette(
        'tests/vcr_cassettes/ksql_create_stream_as_with_conditions_with_startwith_with_and.yml'
    )
    def test_create_stream_as_with_conditions_with_startwith_with_and(self):

        src_table = 'pageviews_original'
        columns_type = [
            'name string', 'age bigint', 'userid string', 'pageid bigint'
        ]
        topic = self.exist_topic

        table_name = 'create_stream_as_with_conditions_with_startwith_with_and'
        kafka_topic = 'create_stream_as_with_conditions_with_startwith_with_and'
        value_format = 'DELIMITED'
        select_columns = ['rowtime as logtime', '*']
        conditions = "userid = 'foo_%' and age > 10"

        try:
            r = self.api_client.create_stream(table_name=src_table,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)
        except KSQLError as e:
            pass

        r = self.api_client.create_stream_as(table_name=table_name,
                                             src_table=src_table,
                                             kafka_topic=kafka_topic,
                                             select_columns=select_columns,
                                             timestamp='logtime',
                                             value_format=value_format,
                                             conditions=conditions)

        self.assertTrue(r)

    @vcr.use_cassette(
        'tests/vcr_cassettes/ksql_create_stream_as_with_wrong_timestamp.yml')
    def test_ksql_create_stream_as_with_wrong_timestamp(self):
        src_table = 'prebid_traffic_log_total_stream'
        columns_type = [
            'name string', 'age bigint', 'userid string', 'pageid bigint'
        ]
        topic = self.exist_topic

        table_name = 'prebid_traffic_log_valid_stream'
        kafka_topic = 'prebid_traffic_log_valid_topic'
        value_format = 'DELIMITED'
        select_columns = ['*']
        timestamp = 'foo'
        utils.drop_stream(self.api_client, src_table)
        utils.drop_stream(self.api_client, table_name)
        try:
            r = self.api_client.create_stream(table_name=src_table,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)
        except KSQLError as e:
            raise

        with self.assertRaises(KSQLError):
            r = self.api_client.create_stream_as(table_name=table_name,
                                                 src_table=src_table,
                                                 kafka_topic=kafka_topic,
                                                 select_columns=select_columns,
                                                 timestamp=timestamp,
                                                 value_format=value_format)
예제 #5
0
class TestKSQLAPI(unittest.TestCase):
    """Test case for the client methods."""

    def setUp(self):
        self.url = "http://*****:*****@vcr.use_cassette("tests/vcr_cassettes/healthcheck.yml")
    def test_ksql_server_healthcheck(self):
        """ Test GET requests """
        res = requests.get(self.url + "/status")
        self.assertEqual(res.status_code, 200)

    @vcr.use_cassette("tests/vcr_cassettes/get_ksql_server.yml")
    def test_get_ksql_version_success(self):
        """ Test GET requests """
        version = self.api_client.get_ksql_version()
        self.assertEqual(version, ksql.__ksql_server_version__)

    @vcr.use_cassette("tests/vcr_cassettes/get_properties.yml")
    def test_get_properties(self):
        properties = self.api_client.get_properties()
        property = [i for i in properties if i["name"] == "ksql.schema.registry.url"][0]
        self.assertEqual(property.get("value"), "http://*****:*****@vcr.use_cassette("tests/vcr_cassettes/ksql_show_table_with_api_key.yml")
    def test_ksql_show_tables_with_api_key(self):
        api_client = KSQLAPI(url=self.url, check_version=False, api_key='foo', secret='bar')
        ksql_string = "show tables;"
        r = api_client.ksql(ksql_string)
        self.assertEqual(r, [{"@type": "tables", "statementText": "show tables;", "tables": [], "warnings": []}])

    @vcr.use_cassette("tests/vcr_cassettes/ksql_show_table.yml")
    def test_ksql_show_tables(self):
        """ Test GET requests """
        ksql_string = "show tables;"
        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r, [{"@type": "tables", "statementText": "show tables;", "tables": [], "warnings": []}])

    @vcr.use_cassette("tests/vcr_cassettes/ksql_show_table.yml")
    def test_ksql_show_tables_with_no_semicolon(self):
        """ Test GET requests """
        ksql_string = "show tables"
        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r, [{"@type": "tables", "statementText": "show tables;", "tables": [], "warnings": []}])

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream.yml")
    def test_ksql_create_stream(self):
        """ Test GET requests """
        topic = self.exist_topic
        stream_name = self.test_prefix + "test_ksql_create_stream"
        ksql_string = "CREATE STREAM {} (viewtime bigint, userid varchar, pageid varchar) \
                       WITH (kafka_topic='{}', value_format='DELIMITED');".format(
            stream_name, topic
        )
        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

    @unittest.skipIf(not utils.check_kafka_available("localhost:29092"), "vcrpy does not support streams yet")
    def test_ksql_create_stream_w_properties(self):
        """ Test GET requests """
        topic = self.exist_topic
        stream_name = "TEST_KSQL_CREATE_STREAM"
        ksql_string = "CREATE STREAM {} (ORDER_ID INT, TOTAL_AMOUNT DOUBLE, CUSTOMER_NAME VARCHAR) \
                       WITH (kafka_topic='{}', value_format='JSON');".format(
            stream_name, topic
        )
        streamProperties = {"ksql.streams.auto.offset.reset": "earliest"}

        if "TEST_KSQL_CREATE_STREAM" not in utils.get_all_streams(self.api_client):
            r = self.api_client.ksql(ksql_string, stream_properties=streamProperties)
            self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

        producer = Producer({"bootstrap.servers": self.bootstrap_servers})
        producer.produce(self.exist_topic, """{"order_id":3,"total_amount":43,"customer_name":"Palo Alto"}""")
        producer.flush()

        # test legacy HTTP/1.1 request
        chunks = self.api_client.query(
            "select * from {} EMIT CHANGES".format(stream_name), stream_properties=streamProperties
        )

        header = next(chunks)
        self.assertEqual(header, """[{"header":{"queryId":"none","schema":"`ORDER_ID` INTEGER, `TOTAL_AMOUNT` DOUBLE, `CUSTOMER_NAME` STRING"}},\n""")

        for chunk in chunks:
            self.assertEqual(chunk, """{"row":{"columns":[3,43.0,"Palo Alto"]}},\n""")
            break

        # test new HTTP/2 request
        chunks = self.api_client.query(
            "select * from {} EMIT CHANGES".format(stream_name), stream_properties=streamProperties, use_http2=True
        )

        header = next(chunks)
        header_obj = json.loads(header)
        self.assertEqual(header_obj["columnNames"], ['ORDER_ID', 'TOTAL_AMOUNT', 'CUSTOMER_NAME'])
        self.assertEqual(header_obj["columnTypes"], ['INTEGER', 'DOUBLE', 'STRING'])

        for chunk in chunks:
            chunk_obj = json.loads(chunk)
            self.assertEqual(chunk_obj, [3,43.0, "Palo Alto"])
            break

    @unittest.skipIf(not utils.check_kafka_available("localhost:29092"), "vcrpy does not support HTTP/2")
    def test_ksql_close_query(self):
        result = self.api_client.close_query("123")

        self.assertFalse(result)

    @unittest.skipIf(not utils.check_kafka_available("localhost:29092"), "vcrpy does not support streams yet")
    def test_inserts_stream(self):
        topic = self.exist_topic
        stream_name = "TEST_INSERTS_STREAM_STREAM"
        ksql_string = "CREATE STREAM {} (ORDER_ID INT, TOTAL_AMOUNT DOUBLE, CUSTOMER_NAME VARCHAR) \
        WITH (kafka_topic='{}', value_format='JSON');".format(
                    stream_name, topic
                )

        streamProperties = {"ksql.streams.auto.offset.reset": "earliest"}

        if "TEST_KSQL_CREATE_STREAM" not in utils.get_all_streams(self.api_client):
            r = self.api_client.ksql(ksql_string, stream_properties=streamProperties)
            self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

        rows = [
            {"ORDER_ID": 1, "TOTAL_AMOUNT": 23.5, "CUSTOMER_NAME": "abc"},
            {"ORDER_ID": 2, "TOTAL_AMOUNT": 3.7, "CUSTOMER_NAME": "xyz"}
        ]

        results = self.api_client.inserts_stream(stream_name, rows)

        for result in results:
            self.assertEqual(result["status"], "ok")

    @unittest.skipIf(not utils.check_kafka_available("localhost:29092"), "vcrpy does not support streams yet")
    def test_ksql_parse_query_result_with_utils(self):
        topic = "TEST_KSQL_PARSE_QUERY_RESULT_WITH_UTILS_TOPIC"
        stream_name = "TEST_KSQL_PARSE_QUERY_RESULT_WITH_UTILS_STREAM"

        producer = Producer({"bootstrap.servers": self.bootstrap_servers})
        producer.produce(topic, """{"order_id":3,"my_struct":{"a":1,"b":"bbb"}, "my_map":{"x":3, "y":4}, "my_array":[1,2,3], "total_amount":43,"customer_name":"Palo Alto"}""")
        producer.flush()

        ksql_string = "CREATE STREAM {} (ORDER_ID INT, MY_STRUCT STRUCT<A INT, B VARCHAR>, MY_MAP MAP<VARCHAR, INT>, MY_ARRAY ARRAY<INT>, TOTAL_AMOUNT DOUBLE, CUSTOMER_NAME VARCHAR) \
                       WITH (kafka_topic='{}', value_format='JSON');".format(
            stream_name, topic
        )
        streamProperties = {"ksql.streams.auto.offset.reset": "earliest"}

        if stream_name not in utils.get_all_streams(self.api_client):
            r = self.api_client.ksql(ksql_string, stream_properties=streamProperties)
            self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

        chunks = self.api_client.query(
            "select * from {} EMIT CHANGES".format(stream_name), stream_properties=streamProperties
        )
        header = next(chunks)
        columns = utils.parse_columns(header)

        for chunk in chunks:
            row_obj = utils.process_row(chunk, columns)
            self.assertEqual(row_obj["ORDER_ID"], 3)
            self.assertEqual(row_obj["MY_STRUCT"], {"A": 1, "B": "bbb"})
            self.assertEqual(row_obj["MY_MAP"], {"x": 3, "y": 4})
            self.assertEqual(row_obj["MY_ARRAY"], [1, 2, 3])
            self.assertEqual(row_obj["TOTAL_AMOUNT"], 43)
            self.assertEqual(row_obj["CUSTOMER_NAME"], "Palo Alto")
            break

    @unittest.skipIf(not utils.check_kafka_available("localhost:29092"), "vcrpy does not support streams yet")
    def test_ksql_parse_query_result(self):
        topic = "TEST_KSQL_PARSE_QUERY_RESULT_TOPIC"
        stream_name = "TEST_KSQL_PARSE_QUERY_RESULT_STREAM"

        producer = Producer({"bootstrap.servers": self.bootstrap_servers})
        producer.produce(topic, """{"order_id":3,"my_struct":{"a":1,"b":"bbb"}, "my_map":{"x":3, "y":4}, "my_array":[1,2,3], "total_amount":43,"customer_name":"Palo Alto"}""")
        producer.flush()

        ksql_string = "CREATE STREAM {} (ORDER_ID INT, MY_STRUCT STRUCT<A INT, B VARCHAR>, MY_MAP MAP<VARCHAR, INT>, MY_ARRAY ARRAY<INT>, TOTAL_AMOUNT DOUBLE, CUSTOMER_NAME VARCHAR) \
                       WITH (kafka_topic='{}', value_format='JSON');".format(
            stream_name, topic
        )
        streamProperties = {"ksql.streams.auto.offset.reset": "earliest"}

        if stream_name not in utils.get_all_streams(self.api_client):
            r = self.api_client.ksql(ksql_string, stream_properties=streamProperties)
            self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

        chunks = self.api_client.query(
            "select * from {} EMIT CHANGES".format(stream_name), stream_properties=streamProperties, return_objects=True
        )

        for chunk in chunks:
            self.assertEqual(chunk["ORDER_ID"], 3)
            self.assertEqual(chunk["MY_STRUCT"], {"A": 1, "B": "bbb"})
            self.assertEqual(chunk["MY_MAP"], {"x": 3, "y": 4})
            self.assertEqual(chunk["MY_ARRAY"], [1, 2, 3])
            self.assertEqual(chunk["TOTAL_AMOUNT"], 43)
            self.assertEqual(chunk["CUSTOMER_NAME"], "Palo Alto")
            break

    @unittest.skipIf(not utils.check_kafka_available("localhost:29092"), "vcrpy does not support streams yet")
    def test_ksql_parse_query_final_message(self):
        topic = "TEST_KSQL_PARSE_QUERY_FINAL_MESSAGE_TOPIC"
        stream_name = "TEST_KSQL_PARSE_QUERY_FINAL_MESSAGE_STREAM"

        producer = Producer({"bootstrap.servers": self.bootstrap_servers})
        producer.produce(topic, """{"order_id":3,"my_struct":{"a":1,"b":"bbb"}, "my_map":{"x":3, "y":4}, "my_array":[1,2,3], "total_amount":43,"customer_name":"Palo Alto"}""")
        producer.flush()

        ksql_string = "CREATE STREAM {} (ORDER_ID INT, MY_STRUCT STRUCT<A INT, B VARCHAR>, MY_MAP MAP<VARCHAR, INT>, MY_ARRAY ARRAY<INT>, TOTAL_AMOUNT DOUBLE, CUSTOMER_NAME VARCHAR) \
                       WITH (kafka_topic='{}', value_format='JSON');".format(
            stream_name, topic
        )
        streamProperties = {"ksql.streams.auto.offset.reset": "earliest"}

        if stream_name not in utils.get_all_streams(self.api_client):
            r = self.api_client.ksql(ksql_string, stream_properties=streamProperties)
            self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

        chunks = self.api_client.query(
            "select * from {} EMIT CHANGES LIMIT 1".format(stream_name), stream_properties=streamProperties, return_objects=True
        )

        for row_obj in chunks:
            self.assertEqual(row_obj["ORDER_ID"], 3)
            self.assertEqual(row_obj["MY_STRUCT"], {"A": 1, "B": "bbb"})
            self.assertEqual(row_obj["MY_MAP"], {"x": 3, "y": 4})
            self.assertEqual(row_obj["MY_ARRAY"], [1, 2, 3])
            self.assertEqual(row_obj["TOTAL_AMOUNT"], 43)
            self.assertEqual(row_obj["CUSTOMER_NAME"], "Palo Alto")

    @vcr.use_cassette("tests/vcr_cassettes/bad_requests.yml")
    def test_bad_requests(self):
        broken_ksql_string = "noi"
        with self.assertRaises(KSQLError) as e:
            self.api_client.ksql(broken_ksql_string)

        exception = e.exception
        self.assertEqual(exception.error_code, 40001)

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream_by_builder.yml")
    def test_ksql_create_stream_by_builder(self):
        sql_type = "create"
        table_type = "stream"
        table_name = "test_table"
        columns_type = ["viewtime bigint", "userid varchar", "pageid varchar"]
        topic = self.exist_topic
        value_format = "DELIMITED"

        utils.drop_stream(self.api_client, table_name)

        ksql_string = SQLBuilder.build(
            sql_type=sql_type,
            table_type=table_type,
            table_name=table_name,
            columns_type=columns_type,
            topic=topic,
            value_format=value_format,
        )

        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream_by_builder_api.yml")
    def test_ksql_create_stream_by_builder_api(self):
        table_name = "test_table"
        columns_type = ["viewtime bigint", "userid varchar", "pageid varchar"]
        topic = self.exist_topic
        value_format = "DELIMITED"

        utils.drop_stream(self.api_client, table_name)

        r = self.api_client.create_stream(
            table_name=table_name, columns_type=columns_type, topic=topic, value_format=value_format
        )

        self.assertTrue(r)

    @vcr.use_cassette("tests/vcr_cassettes/ksql_topic_already_registered.yml")
    def test_raise_create_error_topic_already_registered(self):
        table_name = "foo_table"
        columns_type = ["name string", "age bigint"]
        topic = self.exist_topic
        value_format = "DELIMITED"
        utils.drop_stream(self.api_client, table_name)
        self.api_client.create_stream(
            table_name=table_name, columns_type=columns_type, topic=topic, value_format=value_format
        )

        with self.assertRaises(KSQLError):
            self.api_client.create_stream(
                table_name=table_name, columns_type=columns_type, topic=topic, value_format=value_format
            )

    @vcr.use_cassette("tests/vcr_cassettes/raise_create_error_no_topic.yml")
    def test_raise_create_error_no_topic(self):
        table_name = "foo_table"
        columns_type = ["name string", "age bigint"]
        topic = "this_topic_is_not_exist"
        value_format = "DELIMITED"

        with self.assertRaises(KSQLError):
            self.api_client.create_stream(
                table_name=table_name, columns_type=columns_type, topic=topic, value_format=value_format
            )

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream_as_without_conditions.yml")
    def test_create_stream_as_without_conditions(self):

        src_table = "pageviews_original"
        columns_type = ["name string", "age bigint", "userid string", "pageid bigint"]
        topic = self.exist_topic

        table_name = "create_stream_as_without_conditions"
        kafka_topic = "create_stream_as_without_conditions"
        value_format = "DELIMITED"
        select_columns = ["rowtime as logtime", "*"]

        try:
            r = self.api_client.create_stream(
                table_name=src_table, columns_type=columns_type, topic=topic, value_format=value_format
            )
        except KSQLError:
            pass

        r = self.api_client.create_stream_as(
            table_name=table_name,
            src_table=src_table,
            kafka_topic=kafka_topic,
            select_columns=select_columns,
            timestamp="logtime",
            value_format=value_format,
        )
        self.assertTrue(r)

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream_as_with_conditions_without_startwith.yml")
    def test_create_stream_as_with_conditions_without_startwith(self):

        src_table = "pageviews_original"
        columns_type = ["name string", "age bigint", "userid string", "pageid bigint"]
        topic = self.exist_topic

        table_name = "create_stream_as_with_conditions_without_startwith"
        kafka_topic = "create_stream_as_with_conditions_without_startwith"
        value_format = "DELIMITED"
        select_columns = ["rowtime as logtime", "*"]
        conditions = "userid = 'foo'"

        try:
            r = self.api_client.create_stream(
                table_name=src_table, columns_type=columns_type, topic=topic, value_format=value_format
            )
        except KSQLError:
            pass

        r = self.api_client.create_stream_as(
            table_name=table_name,
            src_table=src_table,
            kafka_topic=kafka_topic,
            select_columns=select_columns,
            timestamp="logtime",
            value_format=value_format,
            conditions=conditions,
        )

        self.assertTrue(r)

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream_as_with_conditions_with_startwith.yml")
    def test_create_stream_as_with_conditions_with_startwith(self):

        src_table = "pageviews_original"
        columns_type = ["name string", "age bigint", "userid string", "pageid bigint"]
        topic = self.exist_topic

        table_name = "create_stream_as_with_conditions_with_startwith"
        kafka_topic = "create_stream_as_with_conditions_with_startwith"
        value_format = "DELIMITED"
        select_columns = ["rowtime as logtime", "*"]
        conditions = "userid = 'foo_%'"
        utils.drop_stream(self.api_client, src_table)
        utils.drop_stream(self.api_client, table_name)

        try:
            r = self.api_client.create_stream(
                table_name=src_table, columns_type=columns_type, topic=topic, value_format=value_format
            )
        except KSQLError:
            pass

        r = self.api_client.create_stream_as(
            table_name=table_name,
            src_table=src_table,
            kafka_topic=kafka_topic,
            select_columns=select_columns,
            timestamp="logtime",
            value_format=value_format,
            conditions=conditions,
        )

        self.assertTrue(r)

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream_as_with_conditions_with_startwith_with_and.yml")
    def test_create_stream_as_with_conditions_with_startwith_with_and(self):

        src_table = "pageviews_original"
        columns_type = ["name string", "age bigint", "userid string", "pageid bigint"]
        topic = self.exist_topic

        table_name = "create_stream_as_with_conditions_with_startwith_with_and"
        kafka_topic = "create_stream_as_with_conditions_with_startwith_with_and"
        value_format = "DELIMITED"
        select_columns = ["rowtime as logtime", "*"]
        conditions = "userid = 'foo_%' and age > 10"

        try:
            r = self.api_client.create_stream(
                table_name=src_table, columns_type=columns_type, topic=topic, value_format=value_format
            )
        except KSQLError:
            pass

        r = self.api_client.create_stream_as(
            table_name=table_name,
            src_table=src_table,
            kafka_topic=kafka_topic,
            select_columns=select_columns,
            timestamp="logtime",
            value_format=value_format,
            conditions=conditions,
        )

        self.assertTrue(r)

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream_as_with_wrong_timestamp.yml")
    def test_ksql_create_stream_as_with_wrong_timestamp(self):
        src_table = "prebid_traffic_log_total_stream"
        columns_type = ["name string", "age bigint", "userid string", "pageid bigint"]
        topic = self.exist_topic

        table_name = "prebid_traffic_log_valid_stream"
        kafka_topic = "prebid_traffic_log_valid_topic"
        value_format = "DELIMITED"
        select_columns = ["*"]
        timestamp = "foo"
        utils.drop_stream(self.api_client, src_table)
        utils.drop_stream(self.api_client, table_name)
        try:
            self.api_client.create_stream(
                table_name=src_table, columns_type=columns_type, topic=topic, value_format=value_format
            )
        except KSQLError:
            pass

        with self.assertRaises(KSQLError):
            self.api_client.create_stream_as(
                table_name=table_name,
                src_table=src_table,
                kafka_topic=kafka_topic,
                select_columns=select_columns,
                timestamp=timestamp,
                value_format=value_format,
            )
예제 #6
0
class TestKSQLAPI(unittest.TestCase):
    """Test case for the client methods."""
    def setUp(self):
        self.url = "http://*****:*****@vcr.use_cassette("tests/vcr_cassettes/healthcheck.yml")
    def test_ksql_server_healthcheck(self):
        """ Test GET requests """
        res = requests.get(self.url + "/status")
        self.assertEqual(res.status_code, 200)

    @vcr.use_cassette("tests/vcr_cassettes/get_ksql_server.yml")
    def test_get_ksql_version_success(self):
        """ Test GET requests """
        version = self.api_client.get_ksql_version()
        self.assertEqual(version, ksql.__ksql_server_version__)

    @vcr.use_cassette("tests/vcr_cassettes/get_properties.yml")
    def test_get_properties(self):
        properties = self.api_client.get_properties()
        property = [
            i for i in properties if i["name"] == "ksql.schema.registry.url"
        ][0]
        self.assertEqual(property.get("value"), "http://*****:*****@vcr.use_cassette("tests/vcr_cassettes/ksql_show_table_with_api_key.yml")
    def test_ksql_show_tables_with_api_key(self):
        api_client = KSQLAPI(url=self.url,
                             check_version=False,
                             api_key='foo',
                             secret='bar')
        ksql_string = "show tables;"
        r = api_client.ksql(ksql_string)
        self.assertEqual(r, [{
            "@type": "tables",
            "statementText": "show tables;",
            "tables": [],
            "warnings": []
        }])

    @vcr.use_cassette("tests/vcr_cassettes/ksql_show_table.yml")
    def test_ksql_show_tables(self):
        """ Test GET requests """
        ksql_string = "show tables;"
        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r, [{
            "@type": "tables",
            "statementText": "show tables;",
            "tables": [],
            "warnings": []
        }])

    @vcr.use_cassette("tests/vcr_cassettes/ksql_show_table.yml")
    def test_ksql_show_tables_with_no_semicolon(self):
        """ Test GET requests """
        ksql_string = "show tables"
        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r, [{
            "@type": "tables",
            "statementText": "show tables;",
            "tables": [],
            "warnings": []
        }])

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream.yml")
    def test_ksql_create_stream(self):
        """ Test GET requests """
        topic = self.exist_topic
        stream_name = self.test_prefix + "test_ksql_create_stream"
        ksql_string = "CREATE STREAM {} (viewtime bigint, userid varchar, pageid varchar) \
                       WITH (kafka_topic='{}', value_format='DELIMITED');".format(
            stream_name, topic)
        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

    @unittest.skipIf(not utils.check_kafka_available("localhost:29092"),
                     "vcrpy does not support streams yet")
    def test_ksql_create_stream_w_properties(self):
        """ Test GET requests """
        topic = self.exist_topic
        stream_name = "TEST_KSQL_CREATE_STREAM"
        ksql_string = "CREATE STREAM {} (ORDER_ID INT, TOTAL_AMOUNT DOUBLE, CUSTOMER_NAME VARCHAR) \
                       WITH (kafka_topic='{}', value_format='JSON');".format(
            stream_name, topic)
        streamProperties = {"ksql.streams.auto.offset.reset": "earliest"}

        if "TEST_KSQL_CREATE_STREAM" not in utils.get_all_streams(
                self.api_client):
            r = self.api_client.ksql(ksql_string,
                                     stream_properties=streamProperties)
            self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

        producer = Producer({"bootstrap.servers": self.bootstrap_servers})
        producer.produce(
            self.exist_topic,
            """{"order_id":3,"total_amount":43,"customer_name":"Palo Alto"}""")
        producer.flush()
        chunks = self.api_client.query(
            "select * from {} EMIT CHANGES".format(stream_name),
            stream_properties=streamProperties)

        for chunk in chunks:
            self.assertTrue(chunk)
            break

    @vcr.use_cassette("tests/vcr_cassettes/bad_requests.yml")
    def test_bad_requests(self):
        broken_ksql_string = "noi"
        with self.assertRaises(KSQLError) as e:
            self.api_client.ksql(broken_ksql_string)

        exception = e.exception
        self.assertEqual(exception.error_code, 40001)

    @vcr.use_cassette("tests/vcr_cassettes/ksql_create_stream_by_builder.yml")
    def test_ksql_create_stream_by_builder(self):
        sql_type = "create"
        table_type = "stream"
        table_name = "test_table"
        columns_type = ["viewtime bigint", "userid varchar", "pageid varchar"]
        topic = self.exist_topic
        value_format = "DELIMITED"

        utils.drop_stream(self.api_client, table_name)

        ksql_string = SQLBuilder.build(
            sql_type=sql_type,
            table_type=table_type,
            table_name=table_name,
            columns_type=columns_type,
            topic=topic,
            value_format=value_format,
        )

        r = self.api_client.ksql(ksql_string)
        self.assertEqual(r[0]["commandStatus"]["status"], "SUCCESS")

    @vcr.use_cassette(
        "tests/vcr_cassettes/ksql_create_stream_by_builder_api.yml")
    def test_ksql_create_stream_by_builder_api(self):
        table_name = "test_table"
        columns_type = ["viewtime bigint", "userid varchar", "pageid varchar"]
        topic = self.exist_topic
        value_format = "DELIMITED"

        utils.drop_stream(self.api_client, table_name)

        r = self.api_client.create_stream(table_name=table_name,
                                          columns_type=columns_type,
                                          topic=topic,
                                          value_format=value_format)

        self.assertTrue(r)

    @vcr.use_cassette("tests/vcr_cassettes/ksql_topic_already_registered.yml")
    def test_raise_create_error_topic_already_registered(self):
        table_name = "foo_table"
        columns_type = ["name string", "age bigint"]
        topic = self.exist_topic
        value_format = "DELIMITED"
        utils.drop_stream(self.api_client, table_name)
        self.api_client.create_stream(table_name=table_name,
                                      columns_type=columns_type,
                                      topic=topic,
                                      value_format=value_format)

        with self.assertRaises(KSQLError):
            self.api_client.create_stream(table_name=table_name,
                                          columns_type=columns_type,
                                          topic=topic,
                                          value_format=value_format)

    @vcr.use_cassette("tests/vcr_cassettes/raise_create_error_no_topic.yml")
    def test_raise_create_error_no_topic(self):
        table_name = "foo_table"
        columns_type = ["name string", "age bigint"]
        topic = "this_topic_is_not_exist"
        value_format = "DELIMITED"

        with self.assertRaises(KSQLError):
            self.api_client.create_stream(table_name=table_name,
                                          columns_type=columns_type,
                                          topic=topic,
                                          value_format=value_format)

    @vcr.use_cassette(
        "tests/vcr_cassettes/ksql_create_stream_as_without_conditions.yml")
    def test_create_stream_as_without_conditions(self):

        src_table = "pageviews_original"
        columns_type = [
            "name string", "age bigint", "userid string", "pageid bigint"
        ]
        topic = self.exist_topic

        table_name = "create_stream_as_without_conditions"
        kafka_topic = "create_stream_as_without_conditions"
        value_format = "DELIMITED"
        select_columns = ["rowtime as logtime", "*"]

        try:
            r = self.api_client.create_stream(table_name=src_table,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)
        except KSQLError:
            pass

        r = self.api_client.create_stream_as(
            table_name=table_name,
            src_table=src_table,
            kafka_topic=kafka_topic,
            select_columns=select_columns,
            timestamp="logtime",
            value_format=value_format,
        )
        self.assertTrue(r)

    @vcr.use_cassette(
        "tests/vcr_cassettes/ksql_create_stream_as_with_conditions_without_startwith.yml"
    )
    def test_create_stream_as_with_conditions_without_startwith(self):

        src_table = "pageviews_original"
        columns_type = [
            "name string", "age bigint", "userid string", "pageid bigint"
        ]
        topic = self.exist_topic

        table_name = "create_stream_as_with_conditions_without_startwith"
        kafka_topic = "create_stream_as_with_conditions_without_startwith"
        value_format = "DELIMITED"
        select_columns = ["rowtime as logtime", "*"]
        conditions = "userid = 'foo'"

        try:
            r = self.api_client.create_stream(table_name=src_table,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)
        except KSQLError:
            pass

        r = self.api_client.create_stream_as(
            table_name=table_name,
            src_table=src_table,
            kafka_topic=kafka_topic,
            select_columns=select_columns,
            timestamp="logtime",
            value_format=value_format,
            conditions=conditions,
        )

        self.assertTrue(r)

    @vcr.use_cassette(
        "tests/vcr_cassettes/ksql_create_stream_as_with_conditions_with_startwith.yml"
    )
    def test_create_stream_as_with_conditions_with_startwith(self):

        src_table = "pageviews_original"
        columns_type = [
            "name string", "age bigint", "userid string", "pageid bigint"
        ]
        topic = self.exist_topic

        table_name = "create_stream_as_with_conditions_with_startwith"
        kafka_topic = "create_stream_as_with_conditions_with_startwith"
        value_format = "DELIMITED"
        select_columns = ["rowtime as logtime", "*"]
        conditions = "userid = 'foo_%'"
        utils.drop_stream(self.api_client, src_table)
        utils.drop_stream(self.api_client, table_name)

        try:
            r = self.api_client.create_stream(table_name=src_table,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)
        except KSQLError:
            pass

        r = self.api_client.create_stream_as(
            table_name=table_name,
            src_table=src_table,
            kafka_topic=kafka_topic,
            select_columns=select_columns,
            timestamp="logtime",
            value_format=value_format,
            conditions=conditions,
        )

        self.assertTrue(r)

    @vcr.use_cassette(
        "tests/vcr_cassettes/ksql_create_stream_as_with_conditions_with_startwith_with_and.yml"
    )
    def test_create_stream_as_with_conditions_with_startwith_with_and(self):

        src_table = "pageviews_original"
        columns_type = [
            "name string", "age bigint", "userid string", "pageid bigint"
        ]
        topic = self.exist_topic

        table_name = "create_stream_as_with_conditions_with_startwith_with_and"
        kafka_topic = "create_stream_as_with_conditions_with_startwith_with_and"
        value_format = "DELIMITED"
        select_columns = ["rowtime as logtime", "*"]
        conditions = "userid = 'foo_%' and age > 10"

        try:
            r = self.api_client.create_stream(table_name=src_table,
                                              columns_type=columns_type,
                                              topic=topic,
                                              value_format=value_format)
        except KSQLError:
            pass

        r = self.api_client.create_stream_as(
            table_name=table_name,
            src_table=src_table,
            kafka_topic=kafka_topic,
            select_columns=select_columns,
            timestamp="logtime",
            value_format=value_format,
            conditions=conditions,
        )

        self.assertTrue(r)

    @vcr.use_cassette(
        "tests/vcr_cassettes/ksql_create_stream_as_with_wrong_timestamp.yml")
    def test_ksql_create_stream_as_with_wrong_timestamp(self):
        src_table = "prebid_traffic_log_total_stream"
        columns_type = [
            "name string", "age bigint", "userid string", "pageid bigint"
        ]
        topic = self.exist_topic

        table_name = "prebid_traffic_log_valid_stream"
        kafka_topic = "prebid_traffic_log_valid_topic"
        value_format = "DELIMITED"
        select_columns = ["*"]
        timestamp = "foo"
        utils.drop_stream(self.api_client, src_table)
        utils.drop_stream(self.api_client, table_name)
        try:
            self.api_client.create_stream(table_name=src_table,
                                          columns_type=columns_type,
                                          topic=topic,
                                          value_format=value_format)
        except KSQLError:
            pass

        with self.assertRaises(KSQLError):
            self.api_client.create_stream_as(
                table_name=table_name,
                src_table=src_table,
                kafka_topic=kafka_topic,
                select_columns=select_columns,
                timestamp=timestamp,
                value_format=value_format,
            )