From 92499fe2bea660cb10fedfb03bf012ca56ddd31c Mon Sep 17 00:00:00 2001 From: Konstantine Karantasis Date: Wed, 16 Mar 2022 12:05:55 -0700 Subject: [PATCH 1/9] KAFKA-13748: Do not include file stream connectors in Connect's CLASSPATH and plugin.path by default --- bin/kafka-run-class.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/kafka-run-class.sh b/bin/kafka-run-class.sh index 6167583780bd5..490f930b8cc4d 100755 --- a/bin/kafka-run-class.sh +++ b/bin/kafka-run-class.sh @@ -32,7 +32,7 @@ if [ -z "$INCLUDE_TEST_JARS" ]; then fi # Exclude jars not necessary for running commands. -regex="(-(test|test-sources|src|scaladoc|javadoc)\.jar|jar.asc)$" +regex="(-(test|test-sources|src|scaladoc|javadoc)\.jar|jar.asc|connect-file.*\.jar)$" should_include_file() { if [ "$INCLUDE_TEST_JARS" = true ]; then return 0 @@ -171,7 +171,7 @@ do CLASSPATH="$CLASSPATH:$dir/*" done -for cc_pkg in "api" "transforms" "runtime" "file" "mirror" "mirror-client" "json" "tools" "basic-auth-extension" +for cc_pkg in "api" "transforms" "runtime" "mirror" "mirror-client" "json" "tools" "basic-auth-extension" do for file in "$base_dir"/connect/${cc_pkg}/build/libs/connect-${cc_pkg}*.jar; do From 3ed3fd9973362f655dd05931d3d38dd1511dae9d Mon Sep 17 00:00:00 2001 From: Konstantine Karantasis Date: Thu, 17 Mar 2022 16:38:06 -0700 Subject: [PATCH 2/9] KAFKA-13748: Adapt system tests to the absence of file stream connectors by default --- tests/kafkatest/services/connect.py | 38 ++++++++++++++++--- .../tests/connect/connect_distributed_test.py | 9 +++-- .../tests/connect/connect_rest_test.py | 3 +- tests/kafkatest/tests/connect/connect_test.py | 12 ++++-- 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/tests/kafkatest/services/connect.py b/tests/kafkatest/services/connect.py index 26c0d927dccd5..58da840f4e929 100644 --- a/tests/kafkatest/services/connect.py +++ b/tests/kafkatest/services/connect.py @@ -69,7 +69,8 @@ class ConnectServiceBase(KafkaPathResolverMixin, Service): "collect_default": True} } - def __init__(self, context, num_nodes, kafka, files, startup_timeout_sec = 60): + def __init__(self, context, num_nodes, kafka, files, startup_timeout_sec=60, + include_filestream_connectors=False): super(ConnectServiceBase, self).__init__(context, num_nodes) self.kafka = kafka self.security_config = kafka.security_config.client_config() @@ -78,6 +79,8 @@ def __init__(self, context, num_nodes, kafka, files, startup_timeout_sec = 60): self.startup_timeout_sec = startup_timeout_sec self.environment = {} self.external_config_template_func = None + self.include_filestream_connectors = include_filestream_connectors + self.logger.debug("include_filestream_connectors % s", include_filestream_connectors) def pids(self, node): """Return process ids for Kafka Connect processes.""" @@ -279,12 +282,30 @@ def append_to_environment_variable(self, envvar, value): env_opts = "\"%s %s\"" % (env_opts.strip('\"'), value) self.environment[envvar] = env_opts + def append_filestream_connectors_to_classpath(self): + if self.include_filestream_connectors: + cwd = os.getcwd() + self.logger.info("Including filestream connectors when starting Connect from: %s", cwd) + lib_dir = cwd + "/connect/file/build/libs/" + for pwd, dirs, files in os.walk(lib_dir): + for file in files: + if file.startswith("connect-file") and file.endswith(".jar"): + file_path = os.path.abspath(os.path.join(pwd, file)) + self.logger.debug("Appending %s to Connect worker's CLASSPATH" % file_path) + return "export CLASSPATH=${CLASSPATH}:%s; " % file_path + self.logger.info("Jar with filestream connectors was not found under %s" % lib_dir) + else: + self.logger.info("Starting Connect without filestream connectors in the CLASSPATH") + + return None + class ConnectStandaloneService(ConnectServiceBase): """Runs Kafka Connect in standalone mode.""" - def __init__(self, context, kafka, files, startup_timeout_sec = 60): - super(ConnectStandaloneService, self).__init__(context, 1, kafka, files, startup_timeout_sec) + def __init__(self, context, kafka, files, startup_timeout_sec=60, include_filestream_connectors=False): + super(ConnectStandaloneService, self).__init__(context, 1, kafka, files, startup_timeout_sec, + include_filestream_connectors) # For convenience since this service only makes sense with a single node @property @@ -299,6 +320,9 @@ def start_cmd(self, node, connector_configs): cmd += fix_opts_for_new_jvm(node) cmd += "export KAFKA_OPTS=\"%s %s\"; " % (heap_kafka_opts, other_kafka_opts) + classpath = self.append_filestream_connectors_to_classpath() + cmd += classpath if classpath else "" + for envvar in self.environment: cmd += "export %s=%s; " % (envvar, str(self.environment[envvar])) cmd += "%s %s " % (self.path.script("connect-standalone.sh", node), self.CONFIG_FILE) @@ -339,8 +363,9 @@ class ConnectDistributedService(ConnectServiceBase): """Runs Kafka Connect in distributed mode.""" def __init__(self, context, num_nodes, kafka, files, offsets_topic="connect-offsets", - configs_topic="connect-configs", status_topic="connect-status", startup_timeout_sec = 60): - super(ConnectDistributedService, self).__init__(context, num_nodes, kafka, files, startup_timeout_sec) + configs_topic="connect-configs", status_topic="connect-status", startup_timeout_sec=60, + include_filestream_connectors=False): + super(ConnectDistributedService, self).__init__(context, num_nodes, kafka, files, startup_timeout_sec, include_filestream_connectors) self.startup_mode = self.STARTUP_MODE_JOIN self.offsets_topic = offsets_topic self.configs_topic = configs_topic @@ -353,6 +378,9 @@ def start_cmd(self, node, connector_configs): self.logs["connect_heap_dump_file"]["path"] other_kafka_opts = self.security_config.kafka_opts.strip('\"') cmd += "export KAFKA_OPTS=\"%s %s\"; " % (heap_kafka_opts, other_kafka_opts) + classpath = self.append_filestream_connectors_to_classpath() + cmd += classpath if classpath else "" + for envvar in self.environment: cmd += "export %s=%s; " % (envvar, str(self.environment[envvar])) cmd += "%s %s " % (self.path.script("connect-distributed.sh", node), self.CONFIG_FILE) diff --git a/tests/kafkatest/tests/connect/connect_distributed_test.py b/tests/kafkatest/tests/connect/connect_distributed_test.py index 6bc52b0d35f49..d1b0285293c48 100644 --- a/tests/kafkatest/tests/connect/connect_distributed_test.py +++ b/tests/kafkatest/tests/connect/connect_distributed_test.py @@ -80,7 +80,7 @@ def __init__(self, test_context): self.value_converter = "org.apache.kafka.connect.json.JsonConverter" self.schemas = True - def setup_services(self, security_protocol=SecurityConfig.PLAINTEXT, timestamp_type=None, broker_version=DEV_BRANCH, auto_create_topics=False): + def setup_services(self, security_protocol=SecurityConfig.PLAINTEXT, timestamp_type=None, broker_version=DEV_BRANCH, auto_create_topics=False, include_filestream_connectors=False): self.kafka = KafkaService(self.test_context, self.num_brokers, self.zk, security_protocol=security_protocol, interbroker_security_protocol=security_protocol, topics=self.topics, version=broker_version, @@ -89,7 +89,7 @@ def setup_services(self, security_protocol=SecurityConfig.PLAINTEXT, timestamp_t for node in self.kafka.nodes: node.config[config_property.MESSAGE_TIMESTAMP_TYPE] = timestamp_type - self.cc = ConnectDistributedService(self.test_context, 3, self.kafka, [self.INPUT_FILE, self.OUTPUT_FILE]) + self.cc = ConnectDistributedService(self.test_context, 3, self.kafka, [self.INPUT_FILE, self.OUTPUT_FILE], include_filestream_connectors) self.cc.log_level = "DEBUG" self.zk.start() @@ -370,7 +370,7 @@ def test_file_source_and_sink(self, security_protocol, connect_protocol): """ self.CONNECT_PROTOCOL = connect_protocol - self.setup_services(security_protocol=security_protocol) + self.setup_services(security_protocol=security_protocol, include_filestream_connectors=True) self.cc.set_configs(lambda node: self.render("connect-distributed.properties", node=node)) self.cc.start() @@ -610,7 +610,8 @@ def test_broker_compatibility(self, broker_version, auto_create_topics, security or relies upon the broker to auto-create the topics (v0.10.0.x and before). """ self.CONNECT_PROTOCOL = connect_protocol - self.setup_services(broker_version=KafkaVersion(broker_version), auto_create_topics=auto_create_topics, security_protocol=security_protocol) + self.setup_services(broker_version=KafkaVersion(broker_version), auto_create_topics=auto_create_topics, + security_protocol=security_protocol, include_filestream_connectors=True) self.cc.set_configs(lambda node: self.render("connect-distributed.properties", node=node)) self.cc.start() diff --git a/tests/kafkatest/tests/connect/connect_rest_test.py b/tests/kafkatest/tests/connect/connect_rest_test.py index 4d978a232d20b..ff44d9412f1a0 100644 --- a/tests/kafkatest/tests/connect/connect_rest_test.py +++ b/tests/kafkatest/tests/connect/connect_rest_test.py @@ -73,7 +73,8 @@ def __init__(self, test_context): 'test': {'partitions': 1, 'replication-factor': 1} }) - self.cc = ConnectDistributedService(test_context, 2, self.kafka, [self.INPUT_FILE, self.INPUT_FILE2, self.OUTPUT_FILE]) + self.cc = ConnectDistributedService(test_context, 2, self.kafka, [self.INPUT_FILE, self.INPUT_FILE2, self.OUTPUT_FILE], + include_filestream_connectors=True) @cluster(num_nodes=4) @matrix(connect_protocol=['compatible', 'eager']) diff --git a/tests/kafkatest/tests/connect/connect_test.py b/tests/kafkatest/tests/connect/connect_test.py index 1a7f6abfeb8b7..4c2a91a6036b3 100644 --- a/tests/kafkatest/tests/connect/connect_test.py +++ b/tests/kafkatest/tests/connect/connect_test.py @@ -91,8 +91,10 @@ def test_file_source_and_sink(self, converter="org.apache.kafka.connect.json.Jso security_protocol=security_protocol, interbroker_security_protocol=security_protocol, topics=self.topics, controller_num_nodes_override=self.num_zk) - self.source = ConnectStandaloneService(self.test_context, self.kafka, [self.INPUT_FILE, self.OFFSETS_FILE]) - self.sink = ConnectStandaloneService(self.test_context, self.kafka, [self.OUTPUT_FILE, self.OFFSETS_FILE]) + self.source = ConnectStandaloneService(self.test_context, self.kafka, [self.INPUT_FILE, self.OFFSETS_FILE], + include_filestream_connectors=True) + self.sink = ConnectStandaloneService(self.test_context, self.kafka, [self.OUTPUT_FILE, self.OFFSETS_FILE], + include_filestream_connectors=True) self.consumer_validator = ConsoleConsumer(self.test_context, 1, self.kafka, self.TOPIC_TEST, consumer_timeout_ms=10000) @@ -164,8 +166,10 @@ def test_skip_and_log_to_dlq(self, error_tolerance): else: faulty_records = faulty_records[0] - self.source = ConnectStandaloneService(self.test_context, self.kafka, [self.INPUT_FILE, self.OFFSETS_FILE]) - self.sink = ConnectStandaloneService(self.test_context, self.kafka, [self.OUTPUT_FILE, self.OFFSETS_FILE]) + self.source = ConnectStandaloneService(self.test_context, self.kafka, [self.INPUT_FILE, self.OFFSETS_FILE], + include_filestream_connectors=True) + self.sink = ConnectStandaloneService(self.test_context, self.kafka, [self.OUTPUT_FILE, self.OFFSETS_FILE], + include_filestream_connectors=True) self.zk.start() self.kafka.start() From c270a7bed56b5c6264e893395661c68002b77293 Mon Sep 17 00:00:00 2001 From: Konstantine Karantasis Date: Fri, 18 Mar 2022 09:45:24 -0700 Subject: [PATCH 3/9] KAFKA-13748: Get home directory correctly --- tests/kafkatest/services/connect.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/kafkatest/services/connect.py b/tests/kafkatest/services/connect.py index 58da840f4e929..41c33ccb9e102 100644 --- a/tests/kafkatest/services/connect.py +++ b/tests/kafkatest/services/connect.py @@ -285,12 +285,16 @@ def append_to_environment_variable(self, envvar, value): def append_filestream_connectors_to_classpath(self): if self.include_filestream_connectors: cwd = os.getcwd() - self.logger.info("Including filestream connectors when starting Connect from: %s", cwd) - lib_dir = cwd + "/connect/file/build/libs/" - for pwd, dirs, files in os.walk(lib_dir): + self.logger.info("Including filestream connectors when starting Connect. " + "Looking for jar locally in: %s" % cwd) + relative_path = "/connect/file/build/libs/" + local_dir = cwd + relative_path + lib_dir = self.path.home() + relative_path + for pwd, dirs, files in os.walk(local_dir): for file in files: if file.startswith("connect-file") and file.endswith(".jar"): - file_path = os.path.abspath(os.path.join(pwd, file)) + # Use the expected directory on the node instead of the path in the driver node + file_path = lib_dir + file self.logger.debug("Appending %s to Connect worker's CLASSPATH" % file_path) return "export CLASSPATH=${CLASSPATH}:%s; " % file_path self.logger.info("Jar with filestream connectors was not found under %s" % lib_dir) @@ -378,11 +382,11 @@ def start_cmd(self, node, connector_configs): self.logs["connect_heap_dump_file"]["path"] other_kafka_opts = self.security_config.kafka_opts.strip('\"') cmd += "export KAFKA_OPTS=\"%s %s\"; " % (heap_kafka_opts, other_kafka_opts) - classpath = self.append_filestream_connectors_to_classpath() - cmd += classpath if classpath else "" - for envvar in self.environment: cmd += "export %s=%s; " % (envvar, str(self.environment[envvar])) + + classpath = self.append_filestream_connectors_to_classpath() + cmd += classpath if classpath else "" cmd += "%s %s " % (self.path.script("connect-distributed.sh", node), self.CONFIG_FILE) cmd += " & echo $! >&3 ) 1>> %s 2>> %s 3> %s" % (self.STDOUT_FILE, self.STDERR_FILE, self.PID_FILE) return cmd From 6fccd92f2732d818e8e90f68c94ebae277fd1f1d Mon Sep 17 00:00:00 2001 From: Konstantine Karantasis Date: Fri, 18 Mar 2022 14:33:37 -0700 Subject: [PATCH 4/9] KAFKA-13748: Fix use of argument in distributed tests --- tests/kafkatest/tests/connect/connect_distributed_test.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/kafkatest/tests/connect/connect_distributed_test.py b/tests/kafkatest/tests/connect/connect_distributed_test.py index d1b0285293c48..970779f723fb5 100644 --- a/tests/kafkatest/tests/connect/connect_distributed_test.py +++ b/tests/kafkatest/tests/connect/connect_distributed_test.py @@ -89,7 +89,8 @@ def setup_services(self, security_protocol=SecurityConfig.PLAINTEXT, timestamp_t for node in self.kafka.nodes: node.config[config_property.MESSAGE_TIMESTAMP_TYPE] = timestamp_type - self.cc = ConnectDistributedService(self.test_context, 3, self.kafka, [self.INPUT_FILE, self.OUTPUT_FILE], include_filestream_connectors) + self.cc = ConnectDistributedService(self.test_context, 3, self.kafka, [self.INPUT_FILE, self.OUTPUT_FILE], + include_filestream_connectors=include_filestream_connectors) self.cc.log_level = "DEBUG" self.zk.start() @@ -522,7 +523,7 @@ def test_bounce(self, clean, connect_protocol): @matrix(connect_protocol=['sessioned', 'compatible', 'eager']) def test_transformations(self, connect_protocol): self.CONNECT_PROTOCOL = connect_protocol - self.setup_services(timestamp_type='CreateTime') + self.setup_services(timestamp_type='CreateTime', include_filestream_connectors=True) self.cc.set_configs(lambda node: self.render("connect-distributed.properties", node=node)) self.cc.start() From 635e510c3f00d851306e91e79bbed15d05bbb4da Mon Sep 17 00:00:00 2001 From: Konstantine Karantasis Date: Mon, 21 Mar 2022 10:22:47 -0700 Subject: [PATCH 5/9] KAFKA-13748: Add a note to the docs --- docs/connect.html | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/connect.html b/docs/connect.html index 66d621248dec5..708e86377a192 100644 --- a/docs/connect.html +++ b/docs/connect.html @@ -74,6 +74,7 @@

Running Kafka Connectconfig.storage.topic (default connect-configs) - topic to use for storing connector and task configurations; note that this should be a single partition, highly replicated, compacted topic. You may need to manually create the topic to ensure the correct configuration as auto created topics may have multiple partitions or be automatically configured for deletion rather than compaction
  • offset.storage.topic (default connect-offsets) - topic to use for storing offsets; this topic should have many partitions, be replicated, and be configured for compaction
  • status.storage.topic (default connect-status) - topic to use for storing statuses; this topic can have multiple partitions, and should be replicated and configured for compaction
  • +
  • plugin.path (default empty) - a list of paths that contain plugins (connectors, converters, transformations). For the purpose of quick starts users will have to add the path that contains the FileStreamSourceConnector and FileStreamSinkConnector packaged in connect-file-"version".jar, because these connectors are not included by default to the CLASSPATH or the plugin.path of the Connect worker
  • Note that in distributed mode the connector configurations are not passed on the command line. Instead, use the REST API described below to create, modify, and destroy connectors.

    From ddc1b02e0217c6fbe7ad41206109888da44c50e5 Mon Sep 17 00:00:00 2001 From: Konstantine Karantasis Date: Wed, 23 Mar 2022 15:54:13 -0700 Subject: [PATCH 6/9] KAFKA-13748: Move note in docs to refer to both standalone and distributed --- docs/connect.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/connect.html b/docs/connect.html index 708e86377a192..b5c0080cbf5e1 100644 --- a/docs/connect.html +++ b/docs/connect.html @@ -48,6 +48,8 @@

    Running Kafka Connectbootstrap.servers - List of Kafka servers used to bootstrap connections to Kafka
  • key.converter - Converter class used to convert between Kafka Connect format and the serialized form that is written to Kafka. This controls the format of the keys in messages written to or read from Kafka, and since this is independent of connectors it allows any connector to work with any serialization format. Examples of common formats include JSON and Avro.
  • value.converter - Converter class used to convert between Kafka Connect format and the serialized form that is written to Kafka. This controls the format of the values in messages written to or read from Kafka, and since this is independent of connectors it allows any connector to work with any serialization format. Examples of common formats include JSON and Avro.
  • +
  • plugin.path (default empty) - a list of paths that contain + plugins (connectors, converters, transformations). For the purpose of quick starts users will have to add the path that contains the FileStreamSourceConnector and FileStreamSinkConnector packaged in connect-file-"version".jar, because these connectors are not included by default to the CLASSPATH or the plugin.path of the Connect worker.
  • The important configuration options specific to standalone mode are:

    @@ -74,7 +76,6 @@

    Running Kafka Connectconfig.storage.topic (default connect-configs) - topic to use for storing connector and task configurations; note that this should be a single partition, highly replicated, compacted topic. You may need to manually create the topic to ensure the correct configuration as auto created topics may have multiple partitions or be automatically configured for deletion rather than compaction
  • offset.storage.topic (default connect-offsets) - topic to use for storing offsets; this topic should have many partitions, be replicated, and be configured for compaction
  • status.storage.topic (default connect-status) - topic to use for storing statuses; this topic can have multiple partitions, and should be replicated and configured for compaction
  • -
  • plugin.path (default empty) - a list of paths that contain plugins (connectors, converters, transformations). For the purpose of quick starts users will have to add the path that contains the FileStreamSourceConnector and FileStreamSinkConnector packaged in connect-file-"version".jar, because these connectors are not included by default to the CLASSPATH or the plugin.path of the Connect worker
  • Note that in distributed mode the connector configurations are not passed on the command line. Instead, use the REST API described below to create, modify, and destroy connectors.

    From 1f20da2cf4e96e30c368f1749a0d58f761149737 Mon Sep 17 00:00:00 2001 From: Konstantine Karantasis Date: Fri, 25 Mar 2022 12:18:58 -0700 Subject: [PATCH 7/9] KAFKA-13748: Amend plugin.path bullet --- docs/connect.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/connect.html b/docs/connect.html index b5c0080cbf5e1..1251c3ce683e9 100644 --- a/docs/connect.html +++ b/docs/connect.html @@ -48,8 +48,7 @@

    Running Kafka Connectbootstrap.servers - List of Kafka servers used to bootstrap connections to Kafka
  • key.converter - Converter class used to convert between Kafka Connect format and the serialized form that is written to Kafka. This controls the format of the keys in messages written to or read from Kafka, and since this is independent of connectors it allows any connector to work with any serialization format. Examples of common formats include JSON and Avro.
  • value.converter - Converter class used to convert between Kafka Connect format and the serialized form that is written to Kafka. This controls the format of the values in messages written to or read from Kafka, and since this is independent of connectors it allows any connector to work with any serialization format. Examples of common formats include JSON and Avro.
  • -
  • plugin.path (default empty) - a list of paths that contain - plugins (connectors, converters, transformations). For the purpose of quick starts users will have to add the path that contains the FileStreamSourceConnector and FileStreamSinkConnector packaged in connect-file-"version".jar, because these connectors are not included by default to the CLASSPATH or the plugin.path of the Connect worker.
  • +
  • plugin.path (default empty) - a list of paths that contain Connect plugins (connectors, converters, transformations). Before running quick starts, users must add the absolute path that contains the example FileStreamSourceConnector and FileStreamSinkConnector packaged in connect-file-"version".jar, because these connectors are not included by default to the CLASSPATH or the plugin.path of the Connect worker (see plugin.path property for examples).
  • The important configuration options specific to standalone mode are:

    From 8f0b8b6502f4423e1b15bba943e1d62ceeb3d4e2 Mon Sep 17 00:00:00 2001 From: Konstantine Karantasis Date: Fri, 25 Mar 2022 12:40:38 -0700 Subject: [PATCH 8/9] KAFKA-13748: Add instruction to the quickstart --- docs/quickstart.html | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/quickstart.html b/docs/quickstart.html index 2ef56c8505745..3e601ab201e91 100644 --- a/docs/quickstart.html +++ b/docs/quickstart.html @@ -32,8 +32,8 @@

    the latest Kafka release and extract it:

    -
    $ tar -xzf kafka_2.13-3.1.0.tgz
    -$ cd kafka_2.13-3.1.0
    +
    $ tar -xzf kafka_{{scalaVersion}}-{{fullDotVersion}}.tgz
    +$ cd kafka_{{scalaVersion}}-{{fullDotVersion}}
    @@ -173,7 +173,11 @@

    - First, we'll start by creating some seed data to test with: + First, make sure to add connect-file-{{fullDotVersion}}.jar to the plugin.path property in the Connect worker's configuration (see plugin.path for examples). +

    + +

    + Then, start by creating some seed data to test with:

    
    From d1f8a108da0c9ada9549f010b09d4cd0fb9ff78a Mon Sep 17 00:00:00 2001
    From: Konstantine Karantasis 
    Date: Tue, 29 Mar 2022 14:22:44 -0700
    Subject: [PATCH 9/9] KAFKA-13748: Add an example
    
    ---
     docs/quickstart.html | 11 ++++++++++-
     1 file changed, 10 insertions(+), 1 deletion(-)
    
    diff --git a/docs/quickstart.html b/docs/quickstart.html
    index 3e601ab201e91..70b13146e6502 100644
    --- a/docs/quickstart.html
    +++ b/docs/quickstart.html
    @@ -173,9 +173,18 @@ 

    - First, make sure to add connect-file-{{fullDotVersion}}.jar to the plugin.path property in the Connect worker's configuration (see plugin.path for examples). + First, make sure to add connect-file-{{fullDotVersion}}.jar to the plugin.path property in the Connect worker's configuration. + For the purpose of this quickstart we'll use a relative path and consider the connectors' package as an uber jar, which works when the quickstart commands are run from the installation directory. + However, it's worth noting that for production deployments using absolute paths is always preferable. See plugin.path for a detailed description of how to set this config.

    +

    + Edit the config/connect-standalone.properties file, add or change the plugin.path configuration property match the following, and save the file: +

    + +
    +> echo "plugin.path=lib/connect-file-{{fullDotVersion}}.jar"
    +

    Then, start by creating some seed data to test with: