{"id":740,"date":"2020-04-21T17:37:14","date_gmt":"2020-04-21T16:37:14","guid":{"rendered":"http:\/\/www.igfasouza.com\/blog\/?p=740"},"modified":"2021-05-20T14:22:07","modified_gmt":"2021-05-20T13:22:07","slug":"kafka-connect","status":"publish","type":"post","link":"http:\/\/www.igfasouza.com\/blog\/kafka-connect\/","title":{"rendered":"Kafka Connect"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/Screenshot-78.png\" alt=\"\" width=\"1920\" height=\"1080\" class=\"alignnone size-full wp-image-741\" srcset=\"http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/Screenshot-78.png 1920w, http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/Screenshot-78-300x169.png 300w, http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/Screenshot-78-768x432.png 768w, http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/Screenshot-78-1024x576.png 1024w, http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/Screenshot-78-624x351.png 624w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/p>\n<p><b>How are you?<\/b><\/p>\n<p>This blog post is part of my series of posts regarding Kafka Connect.<br \/>\nIf you&#8217;re not familiar with Kafka, I suggest you have a look at some of my previous post;<\/p>\n<p><a href=\"http:\/\/www.igfasouza.com\/blog\/what-is-kafka\/\" rel=\"noopener\" target=\"_blank\">What is Kafka?<\/a><br \/>\n<a href=\"http:\/\/www.igfasouza.com\/blog\/kafka-connect-overview\/\" rel=\"noopener\" target=\"_blank\">Kafka Connect Overview<\/a><br \/>\n<a href=\"http:\/\/www.igfasouza.com\/blog\/kafka-connector-architecture\/\" rel=\"noopener\" target=\"_blank\">Kafka Connector Architecture<\/a><\/p>\n<p>This post is a collection of links, videos, tutorials, blogs and books that I found mixed with my opinion. <\/p>\n<h2>Table of contents<\/h2>\n<p>1. Source Standalone mode<br \/>\n2. Source Distributed mode<br \/>\n3. Sink<br \/>\n4. Don\u2019t use Docker composer<br \/>\n5. Lensesio<br \/>\n6. Strimzi<br \/>\n7. Debezium<br \/>\n8. JDBC<br \/>\n9. Link<\/p>\n<h2>1. Source Standalone mode<\/h2>\n<p>Standalone mode is the best way to get started with minimum config and infrastructure setup. In this section, we will see how to configure a connector in Standalone mode and transfer file content to Kafka topic.<\/p>\n<p>Here I\u2019m going to show how to use the <a href=\"https:\/\/docs.confluent.io\/current\/connect\/filestream_connector.html\" rel=\"noopener\" target=\"_blank\">FileSource Connector<\/a><\/p>\n<p>Let\u2019s create a Docker compose file. \u201cdocker-compose.yml\u201d<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/>32<br \/>33<br \/>34<br \/>35<br \/>36<br \/>37<br \/>38<br \/>39<br \/>40<br \/>41<br \/>42<br \/>43<br \/>44<br \/>45<br \/>46<br \/>47<br \/>48<br \/>49<br \/>50<br \/>51<br \/><\/div><\/td><td><div class=\"python codecolorer\">zookeeper:<br \/>\n&nbsp; &nbsp; image: zookeeper:3.4.9<br \/>\n&nbsp; &nbsp; restart: unless-stopped<br \/>\n&nbsp; &nbsp; hostname: zookeeper<br \/>\n&nbsp; &nbsp; container_name: zookeeper<br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"st0\">&quot;2181:2181&quot;<\/span><br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; ZOO_MY_ID: <span class=\"nu0\">1<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; ZOO_PORT: <span class=\"nu0\">2181<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; ZOO_SERVERS: server.1<span class=\"sy0\">=<\/span>zookeeper:<span class=\"nu0\">2888<\/span>:<span class=\"nu0\">3888<\/span><br \/>\n&nbsp; kafka:<br \/>\n&nbsp; &nbsp; image: confluentinc\/cp-kafka:5.1.0<br \/>\n&nbsp; &nbsp; hostname: kafka<br \/>\n&nbsp; &nbsp; container_name: kafka<br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"st0\">&quot;9092:9092&quot;<\/span><br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp; KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT<span class=\"sy0\">,<\/span>PLAINTEXT_HOST:PLAINTEXT<br \/>\n&nbsp; &nbsp; &nbsp; KAFKA_ADVERTISED_LISTENERS: PLAINTEXT:\/\/kafka:<span class=\"nu0\">9092<\/span><span class=\"sy0\">,<\/span>PLAINTEXT_HOST:\/\/localhost:<span class=\"nu0\">29092<\/span><br \/>\n&nbsp; &nbsp; &nbsp; KAFKA_ZOOKEEPER_CONNECT: <span class=\"st0\">&quot;zookeeper:2181&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; KAFKA_BROKER_ID: <span class=\"nu0\">1<\/span><br \/>\n&nbsp; &nbsp; &nbsp; KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: <span class=\"nu0\">1<\/span><br \/>\n&nbsp; &nbsp; depends_on:<br \/>\n&nbsp; &nbsp; &nbsp; - zookeeper<br \/>\n&nbsp; kafka-connect:<br \/>\n&nbsp; &nbsp; image: confluentinc\/cp-kafka-connect:5.1.0<br \/>\n&nbsp; &nbsp; hostname: kafka-connect<br \/>\n&nbsp; &nbsp; container_name: kafka-connect<br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"st0\">&quot;8083:8083&quot;<\/span><br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_BOOTSTRAP_SERVERS: <span class=\"st0\">&quot;kafka:9092&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_REST_ADVERTISED_HOST_NAME: connect<br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_REST_PORT: <span class=\"nu0\">8083<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_GROUP_ID: compose-connect-group<br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_CONFIG_STORAGE_TOPIC: docker-connect-configs<br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_OFFSET_STORAGE_TOPIC: docker-connect-offsets<br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_STATUS_STORAGE_TOPIC: docker-connect-status<br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_KEY_CONVERTER: org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_VALUE_CONVERTER: org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_INTERNAL_KEY_CONVERTER: <span class=\"st0\">&quot;org.apache.kafka.connect.json.JsonConverter&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_INTERNAL_VALUE_CONVERTER: <span class=\"st0\">&quot;org.apache.kafka.connect.json.JsonConverter&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_CONFIG_STORAGE_REPLICATION_FACTOR: <span class=\"st0\">&quot;1&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_OFFSET_STORAGE_REPLICATION_FACTOR: <span class=\"st0\">&quot;1&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_STATUS_STORAGE_REPLICATION_FACTOR: <span class=\"st0\">&quot;1&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_PLUGIN_PATH: <span class=\"st0\">'\/usr\/share\/java,\/etc\/kafka-connect\/jars'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; CONNECT_CONFLUENT_TOPIC_REPLICATION_FACTOR: <span class=\"nu0\">1<\/span><br \/>\n&nbsp; &nbsp; depends_on:<br \/>\n&nbsp; &nbsp; &nbsp; - zookeeper<br \/>\n&nbsp; &nbsp; &nbsp; - kafka<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>In the same directory where we have created the yaml file execute the following command to start Kafka cluster. When the below command runs for the very first time it downloads the image. Once the image is downloaded it creates a Kafka cluster.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"python codecolorer\">docker-compose up<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>For starting any Kafka connect cluster we require &#8211; workers config and connector (file-stream) config.<br \/>\nCreate two files: workers-config.properties  and file-stream-connector-properties.<\/p>\n<p><strong>Workers-config.properties:<\/strong><\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/><\/div><\/td><td><div class=\"python codecolorer\">bootstrap.<span class=\"me1\">servers<\/span><span class=\"sy0\">=<\/span>127.0.0.1:<span class=\"nu0\">9092<\/span><br \/>\nkey.<span class=\"me1\">converter<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\nkey.<span class=\"me1\">converter<\/span>.<span class=\"me1\">schemas<\/span>.<span class=\"me1\">enable<\/span><span class=\"sy0\">=<\/span>false<br \/>\nvalue.<span class=\"me1\">converter<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\nvalue.<span class=\"me1\">converter<\/span>.<span class=\"me1\">schemas<\/span>.<span class=\"me1\">enable<\/span><span class=\"sy0\">=<\/span>false<br \/>\n<span class=\"co1\"># we always leave the internal key to JsonConverter<\/span><br \/>\ninternal.<span class=\"me1\">key<\/span>.<span class=\"me1\">converter<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\ninternal.<span class=\"me1\">key<\/span>.<span class=\"me1\">converter<\/span>.<span class=\"me1\">schemas<\/span>.<span class=\"me1\">enable<\/span><span class=\"sy0\">=<\/span>false<br \/>\ninternal.<span class=\"me1\">value<\/span>.<span class=\"me1\">converter<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\ninternal.<span class=\"me1\">value<\/span>.<span class=\"me1\">converter<\/span>.<span class=\"me1\">schemas<\/span>.<span class=\"me1\">enable<\/span><span class=\"sy0\">=<\/span>false<br \/>\n<span class=\"co1\"># Rest API<\/span><br \/>\nrest.<span class=\"me1\">port<\/span><span class=\"sy0\">=<\/span><span class=\"nu0\">8086<\/span><br \/>\nrest.<span class=\"me1\">host<\/span>.<span class=\"me1\">name<\/span><span class=\"sy0\">=<\/span>127.0.0.1<br \/>\n<span class=\"co1\"># this config is only for standalone workers<\/span><br \/>\noffset.<span class=\"me1\">storage<\/span>.<span class=\"kw2\">file<\/span>.<span class=\"me1\">filename<\/span><span class=\"sy0\">=<\/span>standalone.<span class=\"me1\">offsets<\/span><br \/>\noffset.<span class=\"me1\">flush<\/span>.<span class=\"me1\">interval<\/span>.<span class=\"me1\">ms<\/span><span class=\"sy0\">=<\/span><span class=\"nu0\">10000<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p><strong>File-stream-connector-properties:<\/strong><\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/><\/div><\/td><td><div class=\"python codecolorer\"><span class=\"co1\"># These are standard kafka connect parameters, need for ALL connectors<\/span><br \/>\nname<span class=\"sy0\">=<\/span>file-stream-kafka-connect-standalone<br \/>\nconnector.<span class=\"kw1\">class<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"kw2\">file<\/span>.<span class=\"me1\">FileStreamSourceConnector<\/span><br \/>\ntasks.<span class=\"kw2\">max<\/span><span class=\"sy0\">=<\/span><span class=\"nu0\">1<\/span><br \/>\n<span class=\"kw2\">file<\/span>\/FileStreamSourceConnector.<span class=\"me1\">java<\/span><br \/>\n<span class=\"kw2\">file<\/span><span class=\"sy0\">=<\/span>source-<span class=\"kw2\">input<\/span>.<span class=\"me1\">txt<\/span><br \/>\ntopic<span class=\"sy0\">=<\/span>kafka-connect-standalone<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>You should see three files in the folder; docker-compose.yml, file-stream-connector-properties and workers-config.properties<\/p>\n<p>Create an input file source-input.txt, the content of the file is transferred to Kafka topic.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"python codecolorer\">touch source-<span class=\"kw2\">input<\/span>.<span class=\"me1\">txt<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Mount a host directory in a docker container: Make sure we are in the directory where we have created the files. After mount, we automatically switch to cp-kafka-connect.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"python codecolorer\">docker run --rm -it -v <span class=\"st0\">&quot;$(pwd)&quot;<\/span>:\/kafka-connect\/ --net<span class=\"sy0\">=<\/span>host confluentinc\/cp-kafka-connect<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>This docker image expect the connector in this folder;<br \/>\n\/etc\/kafka-connect\/jars<\/p>\n<p>Create Kafka topic &#8220;kafka-connect-standalone&#8221; with 3 partitions and replication factor 1.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"python codecolorer\">kafka-topics --create --topic kafka-connect-standalone --partitions <span class=\"nu0\">3<\/span> --replication-factor <span class=\"nu0\">1<\/span> --zookeeper 127.0.0.1:<span class=\"nu0\">2181<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Create standalone connector using workers-config.properties and file-stream-connector-properties.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"python codecolorer\">connect-standalone workers-config.<span class=\"me1\">properties<\/span> file-stream-connector-properties<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Now you can test: Open file source-input.txt and type some message to it &#038; save it. The message should have been transferred to Kafka topic. <\/p>\n<p>What happened in the background: We wrote data to the source file and Kafka connect standalone pushed the data to topic. No programming, just configs.<\/p>\n<p>Now stop Kafka Connect (press Ctrl\/Command + C). Once Kafka connect gracefully stopped, list all files in the given directory. We have a new guest in the form of a file &#8220;standalone.offsets&#8221;.<br \/>\nThis file is created by Kafka connect to keep track of from where it should resume reading messages from the source file on re-starts.<br \/>\nWhen Kafka connect starts again it should resume reading without publishing duplicate messages to the topic.<\/p>\n<p>Try to execute the above command (connect-standalone workers-config.properties file-stream-connector-properties) again and validate if you do not have a duplicate message.<\/p>\n<h2>2. Source Distributed mode<\/h2>\n<p>Now let\u2019s configure a connector in distributed mode.<\/p>\n<p>Create Kafka topic &#8220;kafka-connect-distibuted&#8221; with 3 partitions and replication factor 1.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"python codecolorer\">kafka-topics --create --topic kafka-connect-distributed --partitions <span class=\"nu0\">3<\/span> --replication-factor <span class=\"nu0\">1<\/span> --zookeeper 127.0.0.1:<span class=\"nu0\">2181<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Create a config file \u201cconnect-source.json\u201d.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/><\/div><\/td><td><div class=\"python codecolorer\">name<span class=\"sy0\">=<\/span>file-stream-kafka-connect-distributed<br \/>\nconnector.<span class=\"kw1\">class<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"kw2\">file<\/span>.<span class=\"me1\">FileStreamSourceConnector<\/span><br \/>\ntasks.<span class=\"kw2\">max<\/span><span class=\"sy0\">=<\/span><span class=\"nu0\">1<\/span><br \/>\n<span class=\"kw2\">file<\/span><span class=\"sy0\">=<\/span>source-<span class=\"kw2\">input<\/span>.<span class=\"me1\">txt<\/span><br \/>\ntopic<span class=\"sy0\">=<\/span>kafka-connect-distributed<br \/>\nkey.<span class=\"me1\">converter<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\nkey.<span class=\"me1\">converter<\/span>.<span class=\"me1\">schemas<\/span>.<span class=\"me1\">enable<\/span><span class=\"sy0\">=<\/span>true<br \/>\nvalue.<span class=\"me1\">converter<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\nvalue.<span class=\"me1\">converter<\/span>.<span class=\"me1\">schemas<\/span>.<span class=\"me1\">enable<\/span><span class=\"sy0\">=<\/span>true<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>and run;<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"python codecolorer\">curl -d <span class=\"sy0\">@&lt;<\/span>path-to-config-file<span class=\"sy0\">&gt;<\/span>\/connect-source.<span class=\"me1\">json<\/span> -H <span class=\"st0\">&quot;Content-Type: application\/json&quot;<\/span> -X POST http:\/\/localhost:<span class=\"nu0\">8083<\/span>\/connectors<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Now write some message in the source file and once the file is saved, all messages are posted in topic &#8220;kafka-connect-distributed&#8221;. <\/p>\n<p>check for the message copied from file to topic by FileSourceConnector. Note that messages are stored in JSON format as the connector topic created earlier with config value.converter.schemas.enable=true.<\/p>\n<p>We can run the command to check the topic;<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"python codecolorer\">kafka-console-consumer --topic kafka-connect-distributed --from-beginning --bootstrap-server 127.0.0.1:<span class=\"nu0\">9092<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<h2>3. Sink<\/h2>\n<p>Now we need a sink example; Let\u2019s look at a JDBC one. MondoBD.<br \/>\nWe can add this to the docker composer file.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/><\/div><\/td><td><div class=\"python codecolorer\">&nbsp;mongo-db:<br \/>\n&nbsp; &nbsp; image: mongo:4.0.5<br \/>\n&nbsp; &nbsp; hostname: mongo-db<br \/>\n&nbsp; &nbsp; container_name: mongo-db<br \/>\n&nbsp; &nbsp; expose:<br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"st0\">&quot;27017&quot;<\/span><br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"st0\">&quot;27017:27017&quot;<\/span><br \/>\n&nbsp; &nbsp; command: --bind_ip_all --smallfiles<br \/>\n&nbsp; &nbsp; volumes:<br \/>\n&nbsp; &nbsp; &nbsp; - .\/mongo-db:\/data<br \/>\n&nbsp; mongoclient:<br \/>\n&nbsp; &nbsp; image: mongoclient\/mongoclient:2.2.0<br \/>\n&nbsp; &nbsp; container_name: mongoclient<br \/>\n&nbsp; &nbsp; hostname: mongoclient<br \/>\n&nbsp; &nbsp; depends_on:<br \/>\n&nbsp; &nbsp; &nbsp; - mongo-db<br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"nu0\">3000<\/span>:<span class=\"nu0\">3000<\/span><br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp; MONGO_URL: <span class=\"st0\">&quot;mongodb:\/\/mongo-db:27017&quot;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; PORT: <span class=\"nu0\">3000<\/span><br \/>\n&nbsp; &nbsp; expose:<br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"st0\">&quot;3000&quot;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>and run;<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"python codecolorer\">curl -d <span class=\"sy0\">@&lt;<\/span>path-to-config file<span class=\"sy0\">&gt;<\/span>\/connect-mongodb-sink.<span class=\"me1\">json<\/span> -H <span class=\"st0\">&quot;Content-Type: application\/json&quot;<\/span> -X POST http:\/\/localhost:<span class=\"nu0\">8083<\/span>\/connectors<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Create a connect-mongodb-sink.json<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/><\/div><\/td><td><div class=\"python codecolorer\"><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"st0\">&quot;name&quot;<\/span>: <span class=\"st0\">&quot;mongodb-sink&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; <span class=\"st0\">&quot;config&quot;<\/span>: <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st0\">&quot;connector.class&quot;<\/span>: <span class=\"st0\">&quot;at.grahsl.kafka.connect.mongodb.MongoDbSinkConnector&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st0\">&quot;tasks.max&quot;<\/span>: <span class=\"nu0\">1<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st0\">&quot;topics&quot;<\/span>: <span class=\"st0\">&quot;connect-custom&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st0\">&quot;mongodb.connection.uri&quot;<\/span>: <span class=\"st0\">&quot;mongodb:\/\/mongo-db\/test?retryWrites=true&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st0\">&quot;mongodb.collection&quot;<\/span>: <span class=\"st0\">&quot;MyCollection&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st0\">&quot;key.converter&quot;<\/span>: <span class=\"st0\">&quot;org.apache.kafka.connect.json.JsonConverter&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st0\">&quot;key.converter.schemas.enable&quot;<\/span>: false<span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st0\">&quot;value.converter&quot;<\/span>: <span class=\"st0\">&quot;org.apache.kafka.connect.json.JsonConverter&quot;<\/span><span class=\"sy0\">,<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st0\">&quot;value.converter.schemas.enable&quot;<\/span>: false<br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>We have the following MongoDB-specific properties here:<\/p>\n<ul>\n<li>\nmongodb.connection.uri contains the connection string for our MongoDB instance\n<\/li>\n<li>\nmongodb.collection defines the collection\n<\/li>\n<p>Since the MongoDB connector is expecting JSON, we have to set JsonConverter for key.converter and value.converter\n<\/li>\n<li>\nAnd we also need schemaless JSON for MongoDB, so we have to set key.converter.schemas.enable and value.converter.schemas.enable to false\n<\/li>\n<\/ul>\n<p><strong>Elasticsearch<\/strong><\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/><\/div><\/td><td><div class=\"python codecolorer\">elasticsearch:<br \/>\n&nbsp; &nbsp; image: itzg\/elasticsearch:2.4.3<br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp; PLUGINS: appbaseio\/dejavu<br \/>\n&nbsp; &nbsp; &nbsp; OPTS: -Dindex.<span class=\"me1\">number_of_shards<\/span><span class=\"sy0\">=<\/span><span class=\"nu0\">1<\/span> -Dindex.<span class=\"me1\">number_of_replicas<\/span><span class=\"sy0\">=<\/span><span class=\"nu0\">0<\/span><br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"st0\">&quot;9200:9200&quot;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Create a config file \u201cconnect-elasticsearch-sink.json\u201d.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/><\/div><\/td><td><div class=\"python codecolorer\">name<span class=\"sy0\">=<\/span>sink-elastic-twitter-distributed<br \/>\nconnector.<span class=\"kw1\">class<\/span><span class=\"sy0\">=<\/span>io.<span class=\"me1\">confluent<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">elasticsearch<\/span>.<span class=\"me1\">ElasticsearchSinkConnector<\/span><br \/>\ntasks.<span class=\"kw2\">max<\/span><span class=\"sy0\">=<\/span><span class=\"nu0\">2<\/span><br \/>\ntopics<span class=\"sy0\">=<\/span>kafka-connect-distributed-twitter<br \/>\nkey.<span class=\"me1\">converter<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\nkey.<span class=\"me1\">converter<\/span>.<span class=\"me1\">schemas<\/span>.<span class=\"me1\">enable<\/span><span class=\"sy0\">=<\/span>true<br \/>\nvalue.<span class=\"me1\">converter<\/span><span class=\"sy0\">=<\/span>org.<span class=\"me1\">apache<\/span>.<span class=\"me1\">kafka<\/span>.<span class=\"me1\">connect<\/span>.<span class=\"me1\">json<\/span>.<span class=\"me1\">JsonConverter<\/span><br \/>\nvalue.<span class=\"me1\">converter<\/span>.<span class=\"me1\">schemas<\/span>.<span class=\"me1\">enable<\/span><span class=\"sy0\">=<\/span>true<br \/>\nconnection.<span class=\"me1\">url<\/span><span class=\"sy0\">=<\/span>http:\/\/elasticsearch:<span class=\"nu0\">9200<\/span><br \/>\n<span class=\"kw2\">type<\/span>.<span class=\"me1\">name<\/span><span class=\"sy0\">=<\/span>kafka-connect<br \/>\nkey.<span class=\"me1\">ignore<\/span><span class=\"sy0\">=<\/span>true<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p><a href=\"https:\/\/docs.confluent.io\/5.0.0\/installation\/docker\/docs\/installation\/connect-avro-jdbc.html\" rel=\"noopener\" target=\"_blank\">Here<\/a> is a nice link to check about Docker options and images.<\/p>\n<p>I found this with a nice and simple docker composer for single or multiple<br \/>\nnodes <a href=\"https:\/\/github.com\/simplesteph\/kafka-stack-docker-compose\" rel=\"noopener\" target=\"_blank\">here<\/a>.<\/p>\n<h2>4. Don\u2019t use Docker composer<\/h2>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/><\/div><\/td><td><div class=\"python codecolorer\"><span class=\"co1\">#Start Zookeeper<\/span><br \/>\ndocker run -it --rm --name zookeeper -p <span class=\"nu0\">2181<\/span>:<span class=\"nu0\">2181<\/span> -p <span class=\"nu0\">2888<\/span>:<span class=\"nu0\">2888<\/span> -p <span class=\"nu0\">3888<\/span>:<span class=\"nu0\">3888<\/span> zookeeper:3.5.5<br \/>\n<br \/>\n<span class=\"co1\">#Start Kafka Broker<\/span><br \/>\ndocker run -it --rm --name kafka -p <span class=\"nu0\">9092<\/span>:<span class=\"nu0\">9092<\/span> --link zookeeper:zookeeper debezium\/kafka:<span class=\"nu0\">1.0<\/span><br \/>\n<br \/>\n<span class=\"co1\">#Start Kafka Connect<\/span><br \/>\ndocker run -it --rm --name connect -p <span class=\"nu0\">8083<\/span>:<span class=\"nu0\">8083<\/span> \\<br \/>\n-e GROUP_ID<span class=\"sy0\">=<\/span><span class=\"nu0\">1<\/span> \\<br \/>\n-e CONFIG_STORAGE_TOPIC<span class=\"sy0\">=<\/span>kafka_connect_configs \\<br \/>\n-e OFFSET_STORAGE_TOPIC<span class=\"sy0\">=<\/span>kafka_connect_offsets \\<br \/>\n-e STATUS_STORAGE_TOPIC<span class=\"sy0\">=<\/span>kafka_connect_statuses \\<br \/>\n--link zookeeper:zookeeper \\<br \/>\n--link kafka:kafka \\<br \/>\ndebezium\/connect:<span class=\"nu0\">1.0<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<h2>5. Lensesio<\/h2>\n<p>Another option is to use the lenses.io image that already contains several kafka connectors pre installed and a nice user interface.<\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/><\/div><\/td><td><div class=\"python codecolorer\">services:<br \/>\n&nbsp; <span class=\"co1\"># this is our kafka cluster.<\/span><br \/>\n&nbsp; kafka-cluster:<br \/>\n&nbsp; &nbsp; image: landoop\/fast-data-dev:cp3.3.0<br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp; ADV_HOST: 127.0.0.1 &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\"># Change to 192.168.99.100 if using Docker Toolbox<\/span><br \/>\n&nbsp; &nbsp; &nbsp; RUNTESTS: <span class=\"nu0\">0<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\"># Disable Running tests so the cluster starts faster<\/span><br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"nu0\">2181<\/span>:<span class=\"nu0\">2181<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\"># Zookeeper<\/span><br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"nu0\">3030<\/span>:<span class=\"nu0\">3030<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\"># Landoop UI<\/span><br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"nu0\">8081<\/span>-<span class=\"nu0\">8083<\/span>:<span class=\"nu0\">8081<\/span>-<span class=\"nu0\">8083<\/span> &nbsp; &nbsp; &nbsp; <span class=\"co1\"># REST Proxy, Schema Registry, Kafka Connect ports<\/span><br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"nu0\">9581<\/span>-<span class=\"nu0\">9585<\/span>:<span class=\"nu0\">9581<\/span>-<span class=\"nu0\">9585<\/span> &nbsp; &nbsp; &nbsp; <span class=\"co1\"># JMX Ports<\/span><br \/>\n&nbsp; &nbsp; &nbsp; - <span class=\"nu0\">9092<\/span>:<span class=\"nu0\">9092<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\"># Kafka Broker<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p><a href=\"https:\/\/lenses.io\/\" rel=\"noopener\" target=\"_blank\">https:\/\/lenses.io\/<\/a><br \/>\n<a href=\"https:\/\/github.com\/lensesio\/fast-data-dev\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/lensesio\/fast-data-dev<\/a><\/p>\n<h2>6. Strimzi<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/0-9gFlyQBLppFWo-Q4.png\" alt=\"\" width=\"601\" height=\"157\" class=\"alignnone size-full wp-image-742\" srcset=\"http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/0-9gFlyQBLppFWo-Q4.png 601w, http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/0-9gFlyQBLppFWo-Q4-300x78.png 300w\" sizes=\"auto, (max-width: 601px) 100vw, 601px\" \/><\/p>\n<p>Strimzi simplifies the process of running Apache Kafka in a Kubernetes cluster. It provides container images and Operators for running Kafka on Kubernetes.<\/p>\n<p><a href=\"https:\/\/strimzi.io\/\" rel=\"noopener\" target=\"_blank\">https:\/\/strimzi.io\/<\/a><\/p>\n<p><a href=\"https:\/\/medium.com\/@sincysebastian\/setup-kafka-with-debezium-using-strimzi-in-kubernetes-efd494642585\" rel=\"noopener\" target=\"_blank\">https:\/\/medium.com\/@sincysebastian\/setup-kafka-with-debezium-using-strimzi-in-kubernetes-efd494642585<\/a><\/p>\n<p><a href=\"https:\/\/medium.com\/@vamsiramakrishnan\/strimzi-on-oracle-kubernetes-engine-oke-kafka-connect-on-oracle-streaming-service-oss-a-c73cc9714e90\" rel=\"noopener\" target=\"_blank\">https:\/\/medium.com\/@vamsiramakrishnan\/strimzi-on-oracle-kubernetes-engine-oke-kafka-connect-on-oracle-streaming-service-oss-a-c73cc9714e90<\/a><\/p>\n<p><a href=\"https:\/\/itnext.io\/kafka-connect-on-kubernetes-the-easy-way-b5b617b7d5e9\" rel=\"noopener\" target=\"_blank\">https:\/\/itnext.io\/kafka-connect-on-kubernetes-the-easy-way-b5b617b7d5e9<\/a><\/p>\n<h2>7. Debezium<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/debezium.png\" alt=\"\" width=\"659\" height=\"194\" class=\"alignnone size-full wp-image-744\" srcset=\"http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/debezium.png 659w, http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/debezium-300x88.png 300w, http:\/\/www.igfasouza.com\/blog\/wp-content\/uploads\/2020\/04\/debezium-624x184.png 624w\" sizes=\"auto, (max-width: 659px) 100vw, 659px\" \/><\/p>\n<p>Debezium before, it is an open source project for applying the Change Data Capture (CDC) pattern to your applications using Kafka.<\/p>\n<p><a href=\"https:\/\/debezium.io\/\" rel=\"noopener\" target=\"_blank\">https:\/\/debezium.io\/<\/a><\/p>\n<div class=\"codecolorer-container python blackboard\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/>32<br \/>33<br \/>34<br \/>35<br \/>36<br \/>37<br \/>38<br \/>39<br \/>40<br \/>41<br \/>42<br \/>43<br \/>44<br \/>45<br \/>46<br \/>47<br \/>48<br \/>49<br \/>50<br \/>51<br \/>52<br \/>53<br \/>54<br \/>55<br \/>56<br \/>57<br \/>58<br \/><\/div><\/td><td><div class=\"python codecolorer\">version: <span class=\"st0\">'2'<\/span><br \/>\nservices:<br \/>\n&nbsp; zookeeper:<br \/>\n&nbsp; &nbsp; image: debezium\/zookeeper:$<span class=\"br0\">&#123;<\/span>DEBEZIUM_VERSION<span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp;- <span class=\"nu0\">2181<\/span>:<span class=\"nu0\">2181<\/span><br \/>\n&nbsp; &nbsp; &nbsp;- <span class=\"nu0\">2888<\/span>:<span class=\"nu0\">2888<\/span><br \/>\n&nbsp; &nbsp; &nbsp;- <span class=\"nu0\">3888<\/span>:<span class=\"nu0\">3888<\/span><br \/>\n&nbsp; kafka:<br \/>\n&nbsp; &nbsp; image: debezium\/kafka:$<span class=\"br0\">&#123;<\/span>DEBEZIUM_VERSION<span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp;- <span class=\"nu0\">9092<\/span>:<span class=\"nu0\">9092<\/span><br \/>\n&nbsp; &nbsp; links:<br \/>\n&nbsp; &nbsp; &nbsp;- zookeeper<br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp;- ZOOKEEPER_CONNECT<span class=\"sy0\">=<\/span>zookeeper:<span class=\"nu0\">2181<\/span><br \/>\n&nbsp; mysql:<br \/>\n&nbsp; &nbsp; image: debezium\/example-mysql:$<span class=\"br0\">&#123;<\/span>DEBEZIUM_VERSION<span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp;- <span class=\"nu0\">3306<\/span>:<span class=\"nu0\">3306<\/span><br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp;- MYSQL_ROOT_PASSWORD<span class=\"sy0\">=<\/span>debezium<br \/>\n&nbsp; &nbsp; &nbsp;- MYSQL_USER<span class=\"sy0\">=<\/span>mysqluser<br \/>\n&nbsp; &nbsp; &nbsp;- MYSQL_PASSWORD<span class=\"sy0\">=<\/span>mysqlpw<br \/>\n&nbsp; postgres:<br \/>\n&nbsp; &nbsp; image: debezium\/postgres:<span class=\"nu0\">9.6<\/span><br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp;- <span class=\"st0\">&quot;5432:5432&quot;<\/span><br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp;- POSTGRES_USER<span class=\"sy0\">=<\/span>postgresuser<br \/>\n&nbsp; &nbsp; &nbsp;- POSTGRES_PASSWORD<span class=\"sy0\">=<\/span>postgrespw<br \/>\n&nbsp; &nbsp; &nbsp;- POSTGRES_DB<span class=\"sy0\">=<\/span>inventory<br \/>\n&nbsp; elastic:<br \/>\n&nbsp; &nbsp; image: docker.<span class=\"me1\">elastic<\/span>.<span class=\"me1\">co<\/span>\/elasticsearch\/elasticsearch:5.5.2<br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp;- <span class=\"st0\">&quot;9200:9200&quot;<\/span><br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp;- http.<span class=\"me1\">host<\/span><span class=\"sy0\">=<\/span>0.0.0.0<br \/>\n&nbsp; &nbsp; &nbsp;- transport.<span class=\"me1\">host<\/span><span class=\"sy0\">=<\/span>127.0.0.1<br \/>\n&nbsp; &nbsp; &nbsp;- xpack.<span class=\"me1\">security<\/span>.<span class=\"me1\">enabled<\/span><span class=\"sy0\">=<\/span>false<br \/>\n&nbsp; connect:<br \/>\n&nbsp; &nbsp; image: debezium\/connect-jdbc-es:$<span class=\"br0\">&#123;<\/span>DEBEZIUM_VERSION<span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; build:<br \/>\n&nbsp; &nbsp; &nbsp; context: debezium-jdbc-es<br \/>\n&nbsp; &nbsp; ports:<br \/>\n&nbsp; &nbsp; &nbsp;- <span class=\"nu0\">8083<\/span>:<span class=\"nu0\">8083<\/span><br \/>\n&nbsp; &nbsp; &nbsp;- <span class=\"nu0\">5005<\/span>:<span class=\"nu0\">5005<\/span><br \/>\n&nbsp; &nbsp; links:<br \/>\n&nbsp; &nbsp; &nbsp;- kafka<br \/>\n&nbsp; &nbsp; &nbsp;- mysql<br \/>\n&nbsp; &nbsp; &nbsp;- postgres<br \/>\n&nbsp; &nbsp; &nbsp;- elastic<br \/>\n&nbsp; &nbsp; environment:<br \/>\n&nbsp; &nbsp; &nbsp;- BOOTSTRAP_SERVERS<span class=\"sy0\">=<\/span>kafka:<span class=\"nu0\">9092<\/span><br \/>\n&nbsp; &nbsp; &nbsp;- GROUP_ID<span class=\"sy0\">=<\/span><span class=\"nu0\">1<\/span><br \/>\n&nbsp; &nbsp; &nbsp;- CONFIG_STORAGE_TOPIC<span class=\"sy0\">=<\/span>my_connect_configs<br \/>\n&nbsp; &nbsp; &nbsp;- OFFSET_STORAGE_TOPIC<span class=\"sy0\">=<\/span>my_connect_offsets<br \/>\n&nbsp; &nbsp; &nbsp;- STATUS_STORAGE_TOPIC<span class=\"sy0\">=<\/span>my_source_connect_statuses<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>And of course, you can use Strimzi and Debezium together <a href=\"https:\/\/strimzi.io\/blog\/2020\/01\/27\/deploying-debezium-with-kafkaconnector-resource\/\" rel=\"noopener\" target=\"_blank\">here<\/a>. <\/p>\n<h2>8. JDBC<\/h2>\n<p>One of the most common integrations that people want to do with Kafka is getting data in or from a database.<\/p>\n<p><a href=\"https:\/\/www.confluent.io\/blog\/kafka-connect-deep-dive-jdbc-source-connector\/\" rel=\"noopener\" target=\"_blank\">https:\/\/www.confluent.io\/blog\/kafka-connect-deep-dive-jdbc-source-connector\/<\/a><\/p>\n<p><a href=\"https:\/\/dev.to\/rmoff\/streaming-data-from-kafka-to-s3-video-walkthrough-2elh\" rel=\"noopener\" target=\"_blank\">https:\/\/dev.to\/rmoff\/streaming-data-from-kafka-to-s3-video-walkthrough-2elh<\/a><\/p>\n<p><iframe loading=\"lazy\" width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/b-3qN_tlYR4\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe><\/p>\n<h2>9. Link<\/h2>\n<p><a href=\"https:\/\/docs.confluent.io\/current\/connect\/kafka-connect-jdbc\/index.html\" rel=\"noopener\" target=\"_blank\">https:\/\/docs.confluent.io\/current\/connect\/kafka-connect-jdbc\/index.html<\/a><\/p>\n<p><a href=\"https:\/\/docs.confluent.io\/3.1.2\/cp-docker-images\/docs\/quickstart.html\" rel=\"noopener\" target=\"_blank\">https:\/\/docs.confluent.io\/3.1.2\/cp-docker-images\/docs\/quickstart.html<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/confluentinc\/cp-docker-images\/tree\/5.3.1-post\/examples\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/confluentinc\/cp-docker-images\/tree\/5.3.1-post\/examples<\/a><\/p>\n<p><a href=\"https:\/\/www.baeldung.com\/kafka-connectors-guide\" rel=\"noopener\" target=\"_blank\">https:\/\/www.baeldung.com\/kafka-connectors-guide<\/a><\/p>\n<p><a href=\"https:\/\/blog.softwaremill.com\/do-not-reinvent-the-wheel-use-kafka-connect-4bcabb143292\" rel=\"noopener\" target=\"_blank\">https:\/\/blog.softwaremill.com\/do-not-reinvent-the-wheel-use-kafka-connect-4bcabb143292<\/a><\/p>\n<p><a href=\"https:\/\/www.confluent.io\/blog\/webify-event-streams-using-kafka-connect-http-sink\/\" rel=\"noopener\" target=\"_blank\">https:\/\/www.confluent.io\/blog\/webify-event-streams-using-kafka-connect-http-sink\/<\/a><\/p>\n<p><strong>Stay tuned!<\/strong> Next blog post I\u2019ll show how to code your own Kafka connector.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How are you? This blog post is part of my series of posts regarding Kafka Connect. If you&#8217;re not familiar with Kafka, I suggest you have a look at some of my previous post; What is Kafka? Kafka Connect Overview&hellip; <a href=\"http:\/\/www.igfasouza.com\/blog\/kafka-connect\/\" class=\"more-link\">Continue Reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":741,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[25],"tags":[7,11],"class_list":["post-740","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kafka","tag-kafka","tag-kafka-connect"],"_links":{"self":[{"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/posts\/740","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/comments?post=740"}],"version-history":[{"count":4,"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/posts\/740\/revisions"}],"predecessor-version":[{"id":1249,"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/posts\/740\/revisions\/1249"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/media\/741"}],"wp:attachment":[{"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/media?parent=740"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/categories?post=740"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.igfasouza.com\/blog\/wp-json\/wp\/v2\/tags?post=740"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}