C0urante commented on code in PR #14068:
URL: https://github.com/apache/kafka/pull/14068#discussion_r1286204067


##########
docs/connect.html:
##########
@@ -543,6 +543,67 @@ <h6>ACL requirements</h6>
         </tbody>
     </table>
 
+    <h4><a id="connect_plugindiscovery" href="#connect_plugindiscovery">Plugin 
Discovery</a></h4>
+
+    <p>Plugin discovery is the name for the strategy which the Connect worker 
uses to find plugin classes and make them accessible to configure and run in 
connectors. This is controlled by the <a 
href="#connectconfigs_plugin.discovery">plugin.discovery</a> worker 
configuration, and has a significant impact on worker startup time. 
<code>service_load</code> is the fastest strategy, but will hide incompatible 
plugins and may make some unusable. Care should be taken to verify that plugins 
are compatible before setting this configuration to 
<code>service_load</code>.</p>
+
+    <p>Prior to version 3.6, this strategy was not configurable, and behaved 
like the <code>only_scan</code> mode which is compatible with all plugins. For 
version 3.6 and later, this mode defaults to <code>hybrid_warn</code> which is 
also compatible with all plugins, but logs a warning for plugins which are 
incompatible with <code>service_load</code>. The <code>hybrid_fail</code> 
strategy stops the worker with an error if a plugin incompatible with 
<code>service_load</code> is detected, asserting that all plugins are 
compatible. Finally, the <code>service_load</code> strategy will hide 
incompatible plugins in the REST API, and may make some unusable entirely.</p>

Review Comment:
   I don't love the level of detail in "hide incompatible plugins in the REST 
API, and may make some unusable entirely", since this isn't really behavior 
that we've implemented intentionally. I'd rather be more general here and just 
say "may make some plugins unusable"; IMO the term "unusable" gives us enough 
wiggle room that it covers both "completely" unusable (i.e., unloadable) and 
"partially" unusable (i.e., hidden but loadable).



##########
docs/connect.html:
##########
@@ -543,6 +543,67 @@ <h6>ACL requirements</h6>
         </tbody>
     </table>
 
+    <h4><a id="connect_plugindiscovery" href="#connect_plugindiscovery">Plugin 
Discovery</a></h4>
+
+    <p>Plugin discovery is the name for the strategy which the Connect worker 
uses to find plugin classes and make them accessible to configure and run in 
Connectors and Tasks. This is controlled by the <a 
href="#connectconfigs_plugin.discovery"><code>plugin.discovery</code> worker 
configuration</a>, and has a significant impact on worker startup time. 
<code>SERVICE_LOAD</code> is the fastest strategy, but care should be taken to 
verify that plugins are compatible before setting this configuration to 
<code>SERVICE_LOAD</code>.</p>
+
+    <p>Prior to version 3.6, this strategy was not configurable, and behaved 
like the <code>ONLY_SCAN</code> mode which is compatible with all plugins. For 
version 3.6 and later, this mode defaults to <code>HYBRID_WARN</code> which is 
also compatible with all plugins, but logs a warning for all plugins which are 
incompatible with the other modes. For unit-test environments that use the 
<code>EmbeddedConnectCluster</code> this defaults to the 
<code>HYBRID_FAIL</code> strategy, which stops the worker with an error if an 
incompatible plugin is detected. Finally, the <code>SERVICE_LOAD</code> 
strategy will silently hide incompatible plugins and make them unusable.</p>

Review Comment:
   > I think that including "incompatible with service_load" is less correct 
but less confusing.
   
   My take is that in general, it's okay to provide information that is not 
comprehensive but, within a limited scope, accurate. The idea is to only cover 
scenarios that are highly relevant to users. For example: yes, it's technically 
correct that plugins without manifests are incompatible with `hybrid_warn`, but 
since the ultimate goal of this feature is to progress towards `service_load`, 
it's okay if we only provide information with that context in mind.



##########
docs/connect.html:
##########
@@ -577,7 +638,11 @@ <h4><a id="connect_developing" 
href="#connect_developing">Developing a Simple Co
 
     <h5><a id="connect_connectorexample" 
href="#connect_connectorexample">Connector Example</a></h5>
 
-    <p>We'll cover the <code>SourceConnector</code> as a simple example. 
<code>SinkConnector</code> implementations are very similar. Start by creating 
the class that inherits from <code>SourceConnector</code> and add a field that 
will store the configuration information to be propagated to the task(s) (the 
topic to send data to, and optionally - the filename to read from and the 
maximum batch size):</p>
+    <p>We'll cover the <code>SourceConnector</code> as a simple example. 
<code>SinkConnector</code> implementations are very similar. Pick a package and 
class name, these examples will use the <code>FileStreamSourceConnector</code> 
but substitute your own class name where appropriate. In order to <a 
href="#connect_plugindiscovery">make the plugin discoverable at runtime</a>, 
add a ServiceLoader manifest to your resources in 
<code>META-INF/services/org.apache.kafka.connect.source.SourceConnector</code> 
with your fully-qualified class name on a single line:</p>
+    <pre class="brush: resource;">
+com.example.FileStreamSourceConnector</pre>
+
+    <p>Create a class that inherits from <code>SourceConnector</code> and add 
a field that will store the configuration information to be propagated to the 
task(s) (the topic to send data to, and optionally - the filename to read from 
and the maximum batch size):</p>

Review Comment:
   Worth adding the `package com.example` directive to the `public class 
FileStreamSourceConnector ...` code snippet, since the package name serves a 
functional purpose now?



##########
docs/connect.html:
##########
@@ -543,6 +543,67 @@ <h6>ACL requirements</h6>
         </tbody>
     </table>
 
+    <h4><a id="connect_plugindiscovery" href="#connect_plugindiscovery">Plugin 
Discovery</a></h4>
+
+    <p>Plugin discovery is the name for the strategy which the Connect worker 
uses to find plugin classes and make them accessible to configure and run in 
Connectors and Tasks. This is controlled by the <a 
href="#connectconfigs_plugin.discovery"><code>plugin.discovery</code> worker 
configuration</a>, and has a significant impact on worker startup time. 
<code>SERVICE_LOAD</code> is the fastest strategy, but care should be taken to 
verify that plugins are compatible before setting this configuration to 
<code>SERVICE_LOAD</code>.</p>
+
+    <p>Prior to version 3.6, this strategy was not configurable, and behaved 
like the <code>ONLY_SCAN</code> mode which is compatible with all plugins. For 
version 3.6 and later, this mode defaults to <code>HYBRID_WARN</code> which is 
also compatible with all plugins, but logs a warning for all plugins which are 
incompatible with the other modes. For unit-test environments that use the 
<code>EmbeddedConnectCluster</code> this defaults to the 
<code>HYBRID_FAIL</code> strategy, which stops the worker with an error if an 
incompatible plugin is detected. Finally, the <code>SERVICE_LOAD</code> 
strategy will silently hide incompatible plugins and make them unusable.</p>
+
+    <h5><a id="connect_plugindiscovery_compatibility" 
href="#connect_plugindiscovery_compatibility">Verifying Plugin 
Compatibility</a></h5>
+
+    <p>To verify if all of your plugins are compatible, first ensure that you 
are using version 3.6 or later of the Connect runtime. You can then perform one 
of the following checks:</p>
+
+    <ul>
+        <li>Start your worker with the default 
<code>HYBRID_WARN</code>strategy, and WARN logs enabled for the 
<code>org.apache.kafka.connect</code> package. At least one WARN log message 
mentioning the <code>plugin.discovery</code> configuration should be printed. 
This log message will explicitly say that all plugins are compatible, or list 
the incompatible plugins.</li>
+        <li>Start your worker in a test environment with 
<code>HYBRID_FAIL</code>. If all plugins are compatible, startup will succeed. 
If at least one plugin is not compatible the worker will fail to start up, and 
all incompatible plugins will be listed in the exception.</li>
+    </ul>
+
+    <p>If the verification step succeeds, then your current set of installed 
plugins are compatible, and it should be safe to change the 
<code>plugin.discovery</code> configuration to <code>SERVICE_LOAD</code>. If 
you change the set of already-installed plugins, they may no longer be 
compatible, and you should repeat the above verification. If the verification 
fails, you must address the incompatible plugins before using the 
<code>SERVICE_LOAD</code> strategy.</p>

Review Comment:
   Ah, gotcha--I think as long as we stick with the semantics for the CLI that 
treat classpath plugins differently, this should be fine.



##########
docs/connect.html:
##########
@@ -543,6 +543,67 @@ <h6>ACL requirements</h6>
         </tbody>
     </table>
 
+    <h4><a id="connect_plugindiscovery" href="#connect_plugindiscovery">Plugin 
Discovery</a></h4>
+
+    <p>Plugin discovery is the name for the strategy which the Connect worker 
uses to find plugin classes and make them accessible to configure and run in 
Connectors and Tasks. This is controlled by the <a 
href="#connectconfigs_plugin.discovery"><code>plugin.discovery</code> worker 
configuration</a>, and has a significant impact on worker startup time. 
<code>SERVICE_LOAD</code> is the fastest strategy, but care should be taken to 
verify that plugins are compatible before setting this configuration to 
<code>SERVICE_LOAD</code>.</p>
+
+    <p>Prior to version 3.6, this strategy was not configurable, and behaved 
like the <code>ONLY_SCAN</code> mode which is compatible with all plugins. For 
version 3.6 and later, this mode defaults to <code>HYBRID_WARN</code> which is 
also compatible with all plugins, but logs a warning for all plugins which are 
incompatible with the other modes. For unit-test environments that use the 
<code>EmbeddedConnectCluster</code> this defaults to the 
<code>HYBRID_FAIL</code> strategy, which stops the worker with an error if an 
incompatible plugin is detected. Finally, the <code>SERVICE_LOAD</code> 
strategy will silently hide incompatible plugins and make them unusable.</p>

Review Comment:
   > Some of this is covered in the end of the previous paragraph as a lead-in 
to this one; I changed this a bit, but want to avoid repeating myself so I kept 
the performance discussion in the first paragraph, and added more specifics 
about incompatible plugins to this paragraph.
   
   The issue with this is that it make it seem like the `service_load` mode 
only comes with downsides. IMO it's fine to repeat the benefits as long as 
we're brief. How does "Finally, although it offers the best performance, the 
`service_load` strategy will hide incompatible plugins..." sound?



##########
docs/connect.html:
##########
@@ -543,6 +543,67 @@ <h6>ACL requirements</h6>
         </tbody>
     </table>
 
+    <h4><a id="connect_plugindiscovery" href="#connect_plugindiscovery">Plugin 
Discovery</a></h4>
+
+    <p>Plugin discovery is the name for the strategy which the Connect worker 
uses to find plugin classes and make them accessible to configure and run in 
Connectors and Tasks. This is controlled by the <a 
href="#connectconfigs_plugin.discovery"><code>plugin.discovery</code> worker 
configuration</a>, and has a significant impact on worker startup time. 
<code>SERVICE_LOAD</code> is the fastest strategy, but care should be taken to 
verify that plugins are compatible before setting this configuration to 
<code>SERVICE_LOAD</code>.</p>
+
+    <p>Prior to version 3.6, this strategy was not configurable, and behaved 
like the <code>ONLY_SCAN</code> mode which is compatible with all plugins. For 
version 3.6 and later, this mode defaults to <code>HYBRID_WARN</code> which is 
also compatible with all plugins, but logs a warning for all plugins which are 
incompatible with the other modes. For unit-test environments that use the 
<code>EmbeddedConnectCluster</code> this defaults to the 
<code>HYBRID_FAIL</code> strategy, which stops the worker with an error if an 
incompatible plugin is detected. Finally, the <code>SERVICE_LOAD</code> 
strategy will silently hide incompatible plugins and make them unusable.</p>
+
+    <h5><a id="connect_plugindiscovery_compatibility" 
href="#connect_plugindiscovery_compatibility">Verifying Plugin 
Compatibility</a></h5>
+
+    <p>To verify if all of your plugins are compatible, first ensure that you 
are using version 3.6 or later of the Connect runtime. You can then perform one 
of the following checks:</p>
+
+    <ul>
+        <li>Start your worker with the default 
<code>HYBRID_WARN</code>strategy, and WARN logs enabled for the 
<code>org.apache.kafka.connect</code> package. At least one WARN log message 
mentioning the <code>plugin.discovery</code> configuration should be printed. 
This log message will explicitly say that all plugins are compatible, or list 
the incompatible plugins.</li>
+        <li>Start your worker in a test environment with 
<code>HYBRID_FAIL</code>. If all plugins are compatible, startup will succeed. 
If at least one plugin is not compatible the worker will fail to start up, and 
all incompatible plugins will be listed in the exception.</li>
+    </ul>
+
+    <p>If the verification step succeeds, then your current set of installed 
plugins are compatible, and it should be safe to change the 
<code>plugin.discovery</code> configuration to <code>SERVICE_LOAD</code>. If 
you change the set of already-installed plugins, they may no longer be 
compatible, and you should repeat the above verification. If the verification 
fails, you must address the incompatible plugins before using the 
<code>SERVICE_LOAD</code> strategy.</p>
+
+    <h5><a id="connect_plugindiscovery_migrateartifact" 
href="#connect_plugindiscovery_migrateartifact">Operators: Artifact 
Migration</a></h5>
+
+    <p>As an operator of Connect, if you discover incompatible plugins, there 
are multiple ways to try to resolve the incompatibility. They are listed below 
from most to least preferable.</p>
+
+    <ol>
+        <li>Upgrade your incompatible plugins to the latest release version 
from your plugin provider.</li>
+        <li>Contact your plugin provider and request that they migrate the 
plugin to be compatible, following the <a 
href="#connect_plugindiscovery_migratesource">source migration 
instructions</a>, and then upgrade to the migrated version.</li>
+        <li>Migrate the plugin artifacts yourself using the included migration 
script.</li>
+    </ol>
+
+    <p>The migration script is located in 
<code>bin/connect-plugin-path.sh</code> and 
<code>bin\windows\connect-plugin-path.bat</code> of your Kafka installation. 
The script can migrate incompatible plugin artifacts already installed on your 
Connect worker's <code>plugin.path</code> by adding or modifying JAR or 
resource files. This is not suitable for environments using code-signing, as 
this may change the artifacts such that they will fail signature verification. 
View the built-in help with <code>--help</code>.</p>
+
+    <p>To perform a migration, first use the <code>list</code> subcommand to 
get an overview of the plugins available to the script. You must tell the 
script where to find plugins, which can be done with the repeatable 
<code>--worker-config</code>, <code>--plugin-path</code>, and 
<code>--plugin-location</code> arguments. The script will only migrate plugins 
present in the paths specified, so if you add plugins to your worker's 
classpath, then you will need to specify those plugins via one or more 
<code>--plugin-location</code> arguments.</p>

Review Comment:
   Hmmm... I agree with the reservations about modifying JAR files in-flight. 
Do we have to actually write to those JAR files, though? Could we create/modify 
a service loader manifest on the file system instead of inside a JAR file?
   
   I know this is a little inelegant but IMO it's worth considering since it 
would reduce the potential for footguns related to classpath plugins and would 
increase the general utility of the CLI tool.



##########
docs/connect.html:
##########
@@ -543,6 +543,67 @@ <h6>ACL requirements</h6>
         </tbody>
     </table>
 
+    <h4><a id="connect_plugindiscovery" href="#connect_plugindiscovery">Plugin 
Discovery</a></h4>
+
+    <p>Plugin discovery is the name for the strategy which the Connect worker 
uses to find plugin classes and make them accessible to configure and run in 
Connectors and Tasks. This is controlled by the <a 
href="#connectconfigs_plugin.discovery"><code>plugin.discovery</code> worker 
configuration</a>, and has a significant impact on worker startup time. 
<code>SERVICE_LOAD</code> is the fastest strategy, but care should be taken to 
verify that plugins are compatible before setting this configuration to 
<code>SERVICE_LOAD</code>.</p>
+
+    <p>Prior to version 3.6, this strategy was not configurable, and behaved 
like the <code>ONLY_SCAN</code> mode which is compatible with all plugins. For 
version 3.6 and later, this mode defaults to <code>HYBRID_WARN</code> which is 
also compatible with all plugins, but logs a warning for all plugins which are 
incompatible with the other modes. For unit-test environments that use the 
<code>EmbeddedConnectCluster</code> this defaults to the 
<code>HYBRID_FAIL</code> strategy, which stops the worker with an error if an 
incompatible plugin is detected. Finally, the <code>SERVICE_LOAD</code> 
strategy will silently hide incompatible plugins and make them unusable.</p>
+
+    <h5><a id="connect_plugindiscovery_compatibility" 
href="#connect_plugindiscovery_compatibility">Verifying Plugin 
Compatibility</a></h5>
+
+    <p>To verify if all of your plugins are compatible, first ensure that you 
are using version 3.6 or later of the Connect runtime. You can then perform one 
of the following checks:</p>
+
+    <ul>
+        <li>Start your worker with the default 
<code>HYBRID_WARN</code>strategy, and WARN logs enabled for the 
<code>org.apache.kafka.connect</code> package. At least one WARN log message 
mentioning the <code>plugin.discovery</code> configuration should be printed. 
This log message will explicitly say that all plugins are compatible, or list 
the incompatible plugins.</li>
+        <li>Start your worker in a test environment with 
<code>HYBRID_FAIL</code>. If all plugins are compatible, startup will succeed. 
If at least one plugin is not compatible the worker will fail to start up, and 
all incompatible plugins will be listed in the exception.</li>
+    </ul>
+
+    <p>If the verification step succeeds, then your current set of installed 
plugins are compatible, and it should be safe to change the 
<code>plugin.discovery</code> configuration to <code>SERVICE_LOAD</code>. If 
you change the set of already-installed plugins, they may no longer be 
compatible, and you should repeat the above verification. If the verification 
fails, you must address the incompatible plugins before using the 
<code>SERVICE_LOAD</code> strategy.</p>
+
+    <h5><a id="connect_plugindiscovery_migrateartifact" 
href="#connect_plugindiscovery_migrateartifact">Operators: Artifact 
Migration</a></h5>
+
+    <p>As an operator of Connect, if you discover incompatible plugins, there 
are multiple ways to try to resolve the incompatibility. They are listed below 
from most to least preferable.</p>
+
+    <ol>
+        <li>Upgrade your incompatible plugins to the latest release version 
from your plugin provider.</li>

Review Comment:
   My intention with the language "Check the latest release" is to imply 
searching documentation, release notes, even source code, before installing 
that new version onto your Connect worker, which takes more effort from cluster 
administrators and introduces the usual risks associated with bumping any 
dependency.



##########
docs/connect.html:
##########
@@ -543,6 +543,67 @@ <h6>ACL requirements</h6>
         </tbody>
     </table>
 
+    <h4><a id="connect_plugindiscovery" href="#connect_plugindiscovery">Plugin 
Discovery</a></h4>
+
+    <p>Plugin discovery is the name for the strategy which the Connect worker 
uses to find plugin classes and make them accessible to configure and run in 
Connectors and Tasks. This is controlled by the <a 
href="#connectconfigs_plugin.discovery"><code>plugin.discovery</code> worker 
configuration</a>, and has a significant impact on worker startup time. 
<code>SERVICE_LOAD</code> is the fastest strategy, but care should be taken to 
verify that plugins are compatible before setting this configuration to 
<code>SERVICE_LOAD</code>.</p>
+
+    <p>Prior to version 3.6, this strategy was not configurable, and behaved 
like the <code>ONLY_SCAN</code> mode which is compatible with all plugins. For 
version 3.6 and later, this mode defaults to <code>HYBRID_WARN</code> which is 
also compatible with all plugins, but logs a warning for all plugins which are 
incompatible with the other modes. For unit-test environments that use the 
<code>EmbeddedConnectCluster</code> this defaults to the 
<code>HYBRID_FAIL</code> strategy, which stops the worker with an error if an 
incompatible plugin is detected. Finally, the <code>SERVICE_LOAD</code> 
strategy will silently hide incompatible plugins and make them unusable.</p>
+
+    <h5><a id="connect_plugindiscovery_compatibility" 
href="#connect_plugindiscovery_compatibility">Verifying Plugin 
Compatibility</a></h5>
+
+    <p>To verify if all of your plugins are compatible, first ensure that you 
are using version 3.6 or later of the Connect runtime. You can then perform one 
of the following checks:</p>
+
+    <ul>
+        <li>Start your worker with the default 
<code>HYBRID_WARN</code>strategy, and WARN logs enabled for the 
<code>org.apache.kafka.connect</code> package. At least one WARN log message 
mentioning the <code>plugin.discovery</code> configuration should be printed. 
This log message will explicitly say that all plugins are compatible, or list 
the incompatible plugins.</li>
+        <li>Start your worker in a test environment with 
<code>HYBRID_FAIL</code>. If all plugins are compatible, startup will succeed. 
If at least one plugin is not compatible the worker will fail to start up, and 
all incompatible plugins will be listed in the exception.</li>
+    </ul>
+
+    <p>If the verification step succeeds, then your current set of installed 
plugins are compatible, and it should be safe to change the 
<code>plugin.discovery</code> configuration to <code>SERVICE_LOAD</code>. If 
you change the set of already-installed plugins, they may no longer be 
compatible, and you should repeat the above verification. If the verification 
fails, you must address the incompatible plugins before using the 
<code>SERVICE_LOAD</code> strategy.</p>
+
+    <h5><a id="connect_plugindiscovery_migrateartifact" 
href="#connect_plugindiscovery_migrateartifact">Operators: Artifact 
Migration</a></h5>
+
+    <p>As an operator of Connect, if you discover incompatible plugins, there 
are multiple ways to try to resolve the incompatibility. They are listed below 
from most to least preferable.</p>
+
+    <ol>
+        <li>Upgrade your incompatible plugins to the latest release version 
from your plugin provider.</li>
+        <li>Contact your plugin provider and request that they migrate the 
plugin to be compatible, following the <a 
href="#connect_plugindiscovery_migratesource">source migration 
instructions</a>, and then upgrade to the migrated version.</li>
+        <li>Migrate the plugin artifacts yourself using the included migration 
script.</li>
+    </ol>
+
+    <p>The migration script is located in 
<code>bin/connect-plugin-path.sh</code> and 
<code>bin\windows\connect-plugin-path.bat</code> of your Kafka installation. 
The script can migrate incompatible plugin artifacts already installed on your 
Connect worker's <code>plugin.path</code> by adding or modifying JAR or 
resource files. This is not suitable for environments using code-signing, as 
this may change the artifacts such that they will fail signature verification. 
View the built-in help with <code>--help</code>.</p>
+
+    <p>To perform a migration, first use the <code>list</code> subcommand to 
get an overview of the plugins available to the script. You must tell the 
script where to find plugins, which can be done with the repeatable 
<code>--worker-config</code>, <code>--plugin-path</code>, and 
<code>--plugin-location</code> arguments. The script will only migrate plugins 
present in the paths specified, so if you add plugins to your worker's 
classpath, then you will need to specify those plugins via one or more 
<code>--plugin-location</code> arguments.</p>
+
+    <p>Once you see that all incompatible plugins are included in the listing, 
you can proceed to dry-run the migration with <code>sync-manifests 
--dry-run</code>. This will perform all parts of the migration, except for 
writing the results of the migration to disk. Note that the 
<code>sync-manifests</code> command requires all specified paths to be 
writable, and may alter the contents of the directories. Make a backup of the 
specified paths, or copy them to a writable directory.</p>

Review Comment:
   Ahh, thanks for enlightening me! I had a different flow in mind where 
cluster administrators relied more-heavily on the `list` command to discover 
incompatible plugins. If we assume that Connect worker startup is the primary 
mechanism for users to discover incompatible plugins, then I think the current 
language is better than my suggestion.
   
   > If I change this to `If incompatible plugins are shown` then the 
sync-manifests may be incomplete, and the verification steps may fail. I guess 
since they should do that verification anyway, having them cross-check the 
errors and list output is a bit redundant. WDYT?
   
   I actually really like establishing this expectation. We could add 1-2 extra 
sentences instructing users to take note of the list of incompatible plugins 
reported by their Connect worker during startup. If we do that, then the 
language used here wouldn't really need any modifications since "incompatible 
plugins" would clearly reference that list.



##########
docs/connect.html:
##########
@@ -543,6 +543,67 @@ <h6>ACL requirements</h6>
         </tbody>
     </table>
 
+    <h4><a id="connect_plugindiscovery" href="#connect_plugindiscovery">Plugin 
Discovery</a></h4>
+
+    <p>Plugin discovery is the name for the strategy which the Connect worker 
uses to find plugin classes and make them accessible to configure and run in 
Connectors and Tasks. This is controlled by the <a 
href="#connectconfigs_plugin.discovery"><code>plugin.discovery</code> worker 
configuration</a>, and has a significant impact on worker startup time. 
<code>SERVICE_LOAD</code> is the fastest strategy, but care should be taken to 
verify that plugins are compatible before setting this configuration to 
<code>SERVICE_LOAD</code>.</p>
+
+    <p>Prior to version 3.6, this strategy was not configurable, and behaved 
like the <code>ONLY_SCAN</code> mode which is compatible with all plugins. For 
version 3.6 and later, this mode defaults to <code>HYBRID_WARN</code> which is 
also compatible with all plugins, but logs a warning for all plugins which are 
incompatible with the other modes. For unit-test environments that use the 
<code>EmbeddedConnectCluster</code> this defaults to the 
<code>HYBRID_FAIL</code> strategy, which stops the worker with an error if an 
incompatible plugin is detected. Finally, the <code>SERVICE_LOAD</code> 
strategy will silently hide incompatible plugins and make them unusable.</p>
+
+    <h5><a id="connect_plugindiscovery_compatibility" 
href="#connect_plugindiscovery_compatibility">Verifying Plugin 
Compatibility</a></h5>
+
+    <p>To verify if all of your plugins are compatible, first ensure that you 
are using version 3.6 or later of the Connect runtime. You can then perform one 
of the following checks:</p>
+
+    <ul>
+        <li>Start your worker with the default 
<code>HYBRID_WARN</code>strategy, and WARN logs enabled for the 
<code>org.apache.kafka.connect</code> package. At least one WARN log message 
mentioning the <code>plugin.discovery</code> configuration should be printed. 
This log message will explicitly say that all plugins are compatible, or list 
the incompatible plugins.</li>
+        <li>Start your worker in a test environment with 
<code>HYBRID_FAIL</code>. If all plugins are compatible, startup will succeed. 
If at least one plugin is not compatible the worker will fail to start up, and 
all incompatible plugins will be listed in the exception.</li>
+    </ul>
+
+    <p>If the verification step succeeds, then your current set of installed 
plugins are compatible, and it should be safe to change the 
<code>plugin.discovery</code> configuration to <code>SERVICE_LOAD</code>. If 
you change the set of already-installed plugins, they may no longer be 
compatible, and you should repeat the above verification. If the verification 
fails, you must address the incompatible plugins before using the 
<code>SERVICE_LOAD</code> strategy.</p>
+
+    <h5><a id="connect_plugindiscovery_migrateartifact" 
href="#connect_plugindiscovery_migrateartifact">Operators: Artifact 
Migration</a></h5>
+
+    <p>As an operator of Connect, if you discover incompatible plugins, there 
are multiple ways to try to resolve the incompatibility. They are listed below 
from most to least preferable.</p>
+
+    <ol>
+        <li>Upgrade your incompatible plugins to the latest release version 
from your plugin provider.</li>
+        <li>Contact your plugin provider and request that they migrate the 
plugin to be compatible, following the <a 
href="#connect_plugindiscovery_migratesource">source migration 
instructions</a>, and then upgrade to the migrated version.</li>
+        <li>Migrate the plugin artifacts yourself using the included migration 
script.</li>
+    </ol>
+
+    <p>The migration script is located in 
<code>bin/connect-plugin-path.sh</code> and 
<code>bin\windows\connect-plugin-path.bat</code> of your Kafka installation. 
The script can migrate incompatible plugin artifacts already installed on your 
Connect worker's <code>plugin.path</code> by adding or modifying JAR or 
resource files. This is not suitable for environments using code-signing, as 
this may change the artifacts such that they will fail signature verification. 
View the built-in help with <code>--help</code>.</p>
+
+    <p>To perform a migration, first use the <code>list</code> subcommand to 
get an overview of the plugins available to the script. You must tell the 
script where to find plugins, which can be done with the repeatable 
<code>--worker-config</code>, <code>--plugin-path</code>, and 
<code>--plugin-location</code> arguments. The script will only migrate plugins 
present in the paths specified, so if you add plugins to your worker's 
classpath, then you will need to specify those plugins via one or more 
<code>--plugin-location</code> arguments.</p>
+
+    <p>Once you see that all incompatible plugins are included in the listing, 
you can proceed to dry-run the migration with <code>sync-manifests 
--dry-run</code>. This will perform all parts of the migration, except for 
writing the results of the migration to disk. Note that the 
<code>sync-manifests</code> command requires all specified paths to be 
writable, and may alter the contents of the directories. Make a backup of the 
specified paths, or copy them to a writable directory.</p>
+
+    <p>Ensure that you have a backup and the dry-run succeeds before removing 
the <code>--dry-run</code> flag and actually running the migration. If the 
migration fails without the <code>--dry-run</code> flag, then the partially 
migrated artifacts should be discarded. The migration is idempotent, so running 
it multiple times and on already-migrated plugins is safe. After the migration 
is completed, you should <a 
href="#connect_plugindiscovery_compatibility">verify the migration is 
complete</a>. These migration and verification steps may be put into a 
Continuous Integration process to automatically migrate plugins.</p>
+
+    <h5><a id="connect_plugindiscovery_migratesource" 
href="#connect_plugindiscovery_migratesource">Developers: Source 
Migration</a></h5>
+
+    <p>To make plugins compatible with <code>SERVICE_LOAD</code>, it is 
necessary to add <a 
href="https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html";>ServiceLoader</a>
 manifests to your source code, which should then be packaged in the release 
artifact. Manifests are resource files in <code>META-INF/services/</code> named 
after their superclass type, and contain a list of fully-qualified subclass 
names, one on each line. Manifests should be located in the same module as the 
classes they refer to, not in the corresponding test resources.</p>

Review Comment:
   Hmm... I'm leaning slightly towards this sentence being unnecessary, since 
we specify earlier that manifests "should then be packaged in the release 
artifact."
   
   But, if you want to be explicit about this (which I'm not opposed to), I 
think we should frame this more clearly as a warning about a potential footgun; 
for example, "Be careful when testing plugin compatibility using the 
`hybrid_fail` mode; ensure that the service loader manifest for the plugin is 
included in any release artifacts produced for the plugin, instead of only 
included in the testing environment for the plugin" (something less wordy would 
be nice).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: jira-unsubscr...@kafka.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to