creating-stable-plugins.asciidoc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. [[creating-stable-plugins]]
  2. === Creating text analysis plugins with the stable plugin API
  3. Text analysis plugins provide {es} with custom {ref}/analysis.html[Lucene
  4. analyzers, token filters, character filters, and tokenizers].
  5. [discrete]
  6. ==== The stable plugin API
  7. Text analysis plugins can be developed against the stable plugin API. This API
  8. consists of the following dependencies:
  9. * `plugin-api` - an API used by plugin developers to implement custom {es}
  10. plugins.
  11. * `plugin-analysis-api` - an API used by plugin developers to implement analysis
  12. plugins and integrate them into {es}.
  13. * `lucene-analysis-common` - a dependency of `plugin-analysis-api` that contains
  14. core Lucene analysis interfaces like `Tokenizer`, `Analyzer`, and `TokenStream`.
  15. For new versions of {es} within the same major version, plugins built against
  16. this API do not need to be recompiled. Future versions of the API will be
  17. backwards compatible and plugins are binary compatible with future versions of
  18. {es}. In other words, once you have a working artifact, you can re-use it when
  19. you upgrade {es} to a new bugfix or minor version.
  20. A text analysis plugin can implement four factory classes that are provided by
  21. the analysis plugin API.
  22. * `AnalyzerFactory` to create a Lucene analyzer
  23. * `CharFilterFactory` to create a character character filter
  24. * `TokenFilterFactory` to create a Lucene token filter
  25. * `TokenizerFactory` to create a Lucene tokenizer
  26. The key to implementing a stable plugin is the `@NamedComponent` annotation.
  27. Many of {es}'s components have names that are used in configurations. For
  28. example, the keyword analyzer is referenced in configuration with the name
  29. `"keyword"`. Once your custom plugin is installed in your cluster, your named
  30. components may be referenced by name in these configurations as well.
  31. You can also create text analysis plugins as a <<creating-classic-plugins,
  32. classic plugin>>. However, classic plugins are pinned to a specific version of
  33. {es}. You need to recompile them when upgrading {es}. Because classic plugins
  34. are built against internal APIs that can change, upgrading to a new version may
  35. require code changes.
  36. [discrete]
  37. ==== Stable plugin file structure
  38. Stable plugins are ZIP files composed of JAR files and two metadata files:
  39. * `stable-plugin-descriptor.properties` - a Java properties file that describes
  40. the plugin. Refer to <<plugin-descriptor-file-{plugin-type}>>.
  41. * `named_components.json` - a JSON file mapping interfaces to key-value pairs
  42. of component names and implementation classes.
  43. Note that only JAR files at the root of the plugin are added to the classpath
  44. for the plugin. If you need other resources, package them into a resources JAR.
  45. [discrete]
  46. ==== Development process
  47. Elastic provides a Grade plugin, `elasticsearch.stable-esplugin`, that makes it
  48. easier to develop and package stable plugins. The steps in this section assume
  49. you use this plugin. However, you don't need Gradle to create plugins.
  50. The {es} Github repository contains
  51. {es-repo}tree/main/plugins/examples/stable-analysis[an example analysis plugin].
  52. The example `build.gradle` build script provides a good starting point for
  53. developing your own plugin.
  54. [discrete]
  55. ===== Prerequisites
  56. Plugins are written in Java, so you need to install a Java Development Kit
  57. (JDK). Install Gradle if you want to use Gradle.
  58. [discrete]
  59. ===== Step by step
  60. . Create a directory for your project.
  61. . Copy the example `build.gradle` build script to your project directory. Note
  62. that this build script uses the `elasticsearch.stable-esplugin` gradle plugin to
  63. build your plugin.
  64. . Edit the `build.gradle` build script:
  65. ** Add a definition for the `pluginApiVersion` and matching `luceneVersion`
  66. variables to the top of the file. You can find these versions in the
  67. `build-tools-internal/version.properties` file in the {es-repo}[Elasticsearch
  68. Github repository].
  69. ** Edit the `name` and `description` in the `esplugin` section of the build
  70. script. This will create the plugin descriptor file. If you're not using the
  71. `elasticsearch.stable-esplugin` gradle plugin, refer to
  72. <<plugin-descriptor-file-{plugin-type}>> to create the file manually.
  73. ** Add module information.
  74. ** Ensure you have declared the following compile-time dependencies. These
  75. dependencies are compile-time only because {es} will provide these libraries at
  76. runtime.
  77. *** `org.elasticsearch.plugin:elasticsearch-plugin-api`
  78. *** `org.elasticsearch.plugin:elasticsearch-plugin-analysis-api`
  79. *** `org.apache.lucene:lucene-analysis-common`
  80. ** For unit testing, ensure these dependencies have also been added to the
  81. `build.gradle` script as `testImplementation` dependencies.
  82. . Implement an interface from the analysis plugin API, annotating it with
  83. `NamedComponent`. Refer to <<example-text-analysis-plugin>> for an example.
  84. . You should now be able to assemble a plugin ZIP file by running:
  85. +
  86. [source,sh]
  87. ----
  88. gradle bundlePlugin
  89. ----
  90. The resulting plugin ZIP file is written to the `build/distributions`
  91. directory.
  92. [discrete]
  93. ===== YAML REST tests
  94. The Gradle `elasticsearch.yaml-rest-test` plugin enables testing of your
  95. plugin using the {es-repo}blob/main/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/README.asciidoc[{es} yamlRestTest framework].
  96. These tests use a YAML-formatted domain language to issue REST requests against
  97. an internal {es} cluster that has your plugin installed, and to check the
  98. results of those requests. The structure of a YAML REST test directory is as
  99. follows:
  100. * A test suite class, defined under `src/yamlRestTest/java`. This class should
  101. extend `ESClientYamlSuiteTestCase`.
  102. * The YAML tests themselves should be defined under
  103. `src/yamlRestTest/resources/test/`.
  104. [[plugin-descriptor-file-stable]]
  105. ==== The plugin descriptor file for stable plugins
  106. include::plugin-descriptor-file.asciidoc[]