• Elasticsearch:从零开始创建一个 REST handler 插件


    Kibana 的 console 中,我们可以使用一些命令对 Elasticsearch 进行交互。那么我们是否可以扩展我们需要的一些命令呢?比如:

    在上面,我们打入 GET _cat/example,它将显示右边的输出。这个是我们扩展的一个命令。

    Elasticsearch 带有一组可以执行各种任务的功能。 但是,如果你想实现自己的任何功能,则需要在 Elasticsearch 的主代码库中实现。 为了保护你免受所有这些额外步骤的影响,Elasticsearch 提供了在 Elasticsearch 代码中添加插件的选项,该插件能够实现你的功能。

    在今天的展示中,我将使用最新的 Elastic Stack 8.4.0 来进行展示。

    安装

    如果你还没有安装好自己的 Elastic Stack,请参考如下的文章来安装 Elasticsearch 及 Kibana:

    创建插件模板

    在我之前的文章 

    我已经展示了如何为 ingest pipeline 创建 processors。在上面的第二篇文章中,我使用了一个叫做 elasticsearch-plugin-archtype 的插件。我们可以使用如下的命令来创建一个最为基本的插件模板:

    1. mvn archetype:generate \
    2. -DarchetypeGroupId=org.codelibs \
    3. -DarchetypeArtifactId=elasticsearch-plugin-archetype \
    4. -DarchetypeVersion=6.6.0 \
    5. -DgroupId=com.liuxg \
    6. -DartifactId=elasticsearch-plugin \
    7. -Dversion=1.0-SNAPSHOT \
    8. -DpluginName=rest_handler

    上面已经帮我们创建了一个最为基本的插件模板。它在当前的目录下创建了一个叫做 elasticsearch-plugin 的目录。我们首先进入到该目录中:

    1. $ pwd
    2. /Users/liuxg/java/plugins/elasticsearch-plugin
    3. $ tree -L 8
    4. .
    5. ├── pom.xml
    6. └── src
    7. └── main
    8. ├── assemblies
    9. │   └── plugin.xml
    10. ├── java
    11. │   └── com
    12. │   └── liuxg
    13. │   ├── rest
    14. │   │   └── Restrest_handlerAction.java
    15. │   └── rest_handlerPlugin.java
    16. └── plugin-metadata
    17. └── plugin-descriptor.properties

    上面是它的文件结构。因为我们想为 Elastic Stack 8.4.0 构建插件,所以,我们必须在 pom.xml 中修改相应的版本信息:

    pom.xml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <name>elasticsearch-plugin</name>
    5. <modelVersion>4.0.0</modelVersion>
    6. <groupId>com.liuxg</groupId>
    7. <artifactId>elasticsearch-plugin</artifactId>
    8. <version>1.0-SNAPSHOT</version>
    9. <packaging>jar</packaging>
    10. <description>elasticsearch rest_handler plugin</description>
    11. <inceptionYear>2019</inceptionYear>
    12. <licenses>
    13. <license>
    14. <name>The Apache Software License, Version 2.0</name>
    15. <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
    16. <distribution>repo</distribution>
    17. </license>
    18. </licenses>
    19. <properties>
    20. <elasticsearch.version>8.4.0</elasticsearch.version>
    21. <elasticsearch.plugin.classname>com.liuxg.rest_handlerPlugin</elasticsearch.plugin.classname>
    22. <log4j.version>2.11.1</log4j.version>
    23. <maven.compiler.source>1.8</maven.compiler.source>
    24. <maven.compiler.target>1.8</maven.compiler.target>
    25. </properties>
    26. <build>
    27. <plugins>
    28. <plugin>
    29. <artifactId>maven-compiler-plugin</artifactId>
    30. <version>3.8.0</version>
    31. <configuration>
    32. <source>${maven.compiler.source}</source>
    33. <target>${maven.compiler.target}</target>
    34. <encoding>UTF-8</encoding>
    35. </configuration>
    36. </plugin>
    37. <plugin>
    38. <artifactId>maven-surefire-plugin</artifactId>
    39. <version>2.22.1</version>
    40. <configuration>
    41. <includes>
    42. <include>**/*Tests.java</include>
    43. </includes>
    44. </configuration>
    45. </plugin>
    46. <plugin>
    47. <artifactId>maven-source-plugin</artifactId>
    48. <version>3.0.1</version>
    49. <executions>
    50. <execution>
    51. <id>attach-sources</id>
    52. <goals>
    53. <goal>jar</goal>
    54. </goals>
    55. </execution>
    56. </executions>
    57. </plugin>
    58. <plugin>
    59. <artifactId>maven-assembly-plugin</artifactId>
    60. <version>3.1.0</version>
    61. <configuration>
    62. <appendAssemblyId>false</appendAssemblyId>
    63. <outputDirectory>${project.build.directory}/releases/</outputDirectory>
    64. <descriptors>
    65. <descriptor>${basedir}/src/main/assemblies/plugin.xml</descriptor>
    66. </descriptors>
    67. </configuration>
    68. <executions>
    69. <execution>
    70. <phase>package</phase>
    71. <goals>
    72. <goal>single</goal>
    73. </goals>
    74. </execution>
    75. </executions>
    76. </plugin>
    77. </plugins>
    78. </build>
    79. <dependencies>
    80. <dependency>
    81. <groupId>org.elasticsearch</groupId>
    82. <artifactId>elasticsearch</artifactId>
    83. <version>${elasticsearch.version}</version>
    84. <scope>provided</scope>
    85. </dependency>
    86. <dependency>
    87. <groupId>org.apache.logging.log4j</groupId>
    88. <artifactId>log4j-api</artifactId>
    89. <version>${log4j.version}</version>
    90. <scope>provided</scope>
    91. </dependency>
    92. </dependencies>
    93. </project>

    在上面,我们把 elasticsearch.version 设置为 8.4.0。其它的保持不变。

    接下来,我们来修改 rest_handlerPlugin.java 文件:

    rest_handlerPlugin.java

    1. package com.liuxg;
    2. import java.util.List;
    3. import java.util.function.Supplier;
    4. import com.liuxg.rest.Restrest_handlerAction;
    5. import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
    6. import org.elasticsearch.cluster.node.DiscoveryNodes;
    7. import org.elasticsearch.common.settings.ClusterSettings;
    8. import org.elasticsearch.common.settings.IndexScopedSettings;
    9. import org.elasticsearch.common.settings.Settings;
    10. import org.elasticsearch.common.settings.SettingsFilter;
    11. import org.elasticsearch.plugins.ActionPlugin;
    12. import org.elasticsearch.plugins.Plugin;
    13. import org.elasticsearch.rest.RestController;
    14. import org.elasticsearch.rest.RestHandler;
    15. import static java.util.Collections.singletonList;
    16. public class rest_handlerPlugin extends Plugin implements ActionPlugin {
    17. @Override
    18. public List<RestHandler> getRestHandlers(final Settings settings,
    19. final RestController restController,
    20. final ClusterSettings clusterSettings,
    21. final IndexScopedSettings indexScopedSettings,
    22. final SettingsFilter settingsFilter,
    23. final IndexNameExpressionResolver indexNameExpressionResolver,
    24. final Supplier<DiscoveryNodes> nodesInCluster) {
    25. return singletonList(new Restrest_handlerAction());
    26. }
    27. }

    这个文件会让 Elasticsearch 知道你的插件。

    我们接下来修改 Restrest_handlerAction.java 文件如下:

    Restrest_handlerAction.java

    1. package com.liuxg.rest;
    2. import org.elasticsearch.client.internal.node.NodeClient;
    3. import org.elasticsearch.common.Table;
    4. import org.elasticsearch.rest.RestRequest;
    5. import org.elasticsearch.rest.RestResponse;
    6. import org.elasticsearch.rest.action.cat.AbstractCatAction;
    7. import org.elasticsearch.rest.action.cat.RestTable;
    8. import java.util.List;
    9. import static org.elasticsearch.rest.RestRequest.Method.GET;
    10. import static org.elasticsearch.rest.RestRequest.Method.POST;
    11. public class Restrest_handlerAction extends AbstractCatAction {
    12. @Override
    13. public List routes() {
    14. return List.of(
    15. new Route(GET, "/_cat/example"),
    16. new Route(POST, "/_cat/example"));
    17. }
    18. @Override
    19. public String getName() {
    20. return "rest_handler_cat_example";
    21. }
    22. @Override
    23. protected RestChannelConsumer doCatRequest(final RestRequest request, final NodeClient client) {
    24. final String message = request.param("message", "Hello from Cat Example action");
    25. Table table = getTableWithHeader(request);
    26. table.startRow();
    27. table.addCell(message);
    28. table.endRow();
    29. return channel -> {
    30. try {
    31. channel.sendResponse(RestTable.buildResponse(table, channel));
    32. } catch (final Exception e) {
    33. channel.sendResponse(new RestResponse(channel, e));
    34. }
    35. };
    36. }
    37. @Override
    38. protected void documentation(StringBuilder sb) {
    39. sb.append(documentation());
    40. }
    41. public static String documentation() {
    42. return "/_cat/example\n";
    43. }
    44. @Override
    45. protected Table getTableWithHeader(RestRequest request) {
    46. final Table table = new Table();
    47. table.startHeaders();
    48. table.addCell("test", "desc:test");
    49. table.endHeaders();
    50. return table;
    51. }
    52. }

    该文件将定义插件的路由和处理这些路由的代码。

    这样我们就修改完了我们的代码。

    编译

    我们在项目的根目录下使人如下的命令来进行编译:

    mvn clean install
    1. $ mvn clean install
    2. [INFO] Scanning for projects...
    3. [INFO]
    4. [INFO] -------------------< com.liuxg:elasticsearch-plugin >-------------------
    5. [INFO] Building elasticsearch-plugin 1.0-SNAPSHOT
    6. [INFO] --------------------------------[ jar ]---------------------------------
    7. [INFO]
    8. [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ elasticsearch-plugin ---
    9. [INFO]
    10. [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ elasticsearch-plugin ---
    11. [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
    12. [INFO] skip non existing resourceDirectory /Users/liuxg/java/plugins/elasticsearch-plugin/src/main/resources
    13. [INFO]
    14. [INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ elasticsearch-plugin ---
    15. [INFO] Changes detected - recompiling the module!
    16. [INFO] Compiling 2 source files to /Users/liuxg/java/plugins/elasticsearch-plugin/target/classes
    17. [INFO]
    18. [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ elasticsearch-plugin ---
    19. [WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
    20. [INFO] skip non existing resourceDirectory /Users/liuxg/java/plugins/elasticsearch-plugin/src/test/resources
    21. [INFO]
    22. [INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ elasticsearch-plugin ---
    23. [INFO] No sources to compile
    24. [INFO]
    25. [INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ elasticsearch-plugin ---
    26. [INFO] No tests to run.
    27. [INFO]
    28. [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ elasticsearch-plugin ---
    29. [INFO] Building jar: /Users/liuxg/java/plugins/elasticsearch-plugin/target/elasticsearch-plugin-1.0-SNAPSHOT.jar
    30. [INFO]
    31. [INFO] >>> maven-source-plugin:3.0.1:jar (attach-sources) > generate-sources @ elasticsearch-plugin >>>
    32. [INFO]
    33. [INFO] <<< maven-source-plugin:3.0.1:jar (attach-sources) < generate-sources @ elasticsearch-plugin <<<
    34. [INFO]
    35. [INFO]
    36. [INFO] --- maven-source-plugin:3.0.1:jar (attach-sources) @ elasticsearch-plugin ---
    37. [INFO] Building jar: /Users/liuxg/java/plugins/elasticsearch-plugin/target/elasticsearch-plugin-1.0-SNAPSHOT-sources.jar
    38. [INFO]
    39. [INFO] --- maven-assembly-plugin:3.1.0:single (default) @ elasticsearch-plugin ---
    40. [INFO] Reading assembly descriptor: /Users/liuxg/java/plugins/elasticsearch-plugin/src/main/assemblies/plugin.xml
    41. [WARNING] The following patterns were never triggered in this artifact exclusion filter:
    42. o 'org.elasticsearch:elasticsearch'
    43. [INFO] Building zip: /Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
    44. [INFO]
    45. [INFO] --- maven-install-plugin:2.4:install (default-install) @ elasticsearch-plugin ---
    46. [INFO] Installing /Users/liuxg/java/plugins/elasticsearch-plugin/target/elasticsearch-plugin-1.0-SNAPSHOT.jar to /Users/liuxg/.m2/repository/com/liuxg/elasticsearch-plugin/1.0-SNAPSHOT/elasticsearch-plugin-1.0-SNAPSHOT.jar
    47. [INFO] Installing /Users/liuxg/java/plugins/elasticsearch-plugin/pom.xml to /Users/liuxg/.m2/repository/com/liuxg/elasticsearch-plugin/1.0-SNAPSHOT/elasticsearch-plugin-1.0-SNAPSHOT.pom
    48. [INFO] Installing /Users/liuxg/java/plugins/elasticsearch-plugin/target/elasticsearch-plugin-1.0-SNAPSHOT-sources.jar to /Users/liuxg/.m2/repository/com/liuxg/elasticsearch-plugin/1.0-SNAPSHOT/elasticsearch-plugin-1.0-SNAPSHOT-sources.jar
    49. [INFO] Installing /Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip to /Users/liuxg/.m2/repository/com/liuxg/elasticsearch-plugin/1.0-SNAPSHOT/elasticsearch-plugin-1.0-SNAPSHOT.zip
    50. [INFO] ------------------------------------------------------------------------
    51. [INFO] BUILD SUCCESS
    52. [INFO] ------------------------------------------------------------------------
    53. [INFO] Total time: 5.352 s
    54. [INFO] Finished at: 2022-09-06T10:55:38+08:00
    55. [INFO] ------------------------------------------------------------------------

    编译成功后,我们可以在 target 目录先看到如下的安装文件:

    1. $ pwd
    2. /Users/liuxg/java/plugins/elasticsearch-plugin
    3. $ ls target/releases
    4. elasticsearch-plugin-1.0-SNAPSHOT.zip

    上面显示的 elasticsearch-plugin-1.0-SNAPSHOT.zip 就是我们可以安装的插件文件。

    安装插件并测试插件

    我们接下来换到 Elasticsearch 的安装目录下,并打入如下的命令:

    1. $ pwd
    2. /Users/liuxg/elastic0/elasticsearch-8.4.0
    3. $ bin/elasticsearch-plugin install file:Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
    4. -> Installing file:Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
    5. -> Downloading file:Users/liuxg/java/plugins/elasticsearch-plugin/target/releases/elasticsearch-plugin-1.0-SNAPSHOT.zip
    6. [=================================================] 100%  
    7. -> Installed rest_handler
    8. -> Please restart Elasticsearch to activate any plugins installed
    9. $ ./bin/elasticsearch-plugin list
    10. rest_handler

    从上面的显示中,我们可以看出来 rest_handler 插件已经被成功地安装。我们接下来需要重新启动 Elasticsearch。这个非常重要!

    我们打开 Kibana,并打入如下的命令:

    我们也可以直接在 terminal 中打入如下的命令:

    curl -k --user elastic:V_USqc1cWM40W_pIHnni https://localhost:9200/_cat/example
    1. $ curl -k --user elastic:V_USqc1cWM40W_pIHnni https://localhost:9200/_cat/example
    2. Hello from Cat Example action

     整个项目的代码可以在地址下载:GitHub - liu-xiao-guo/rest_handler_plugin

    参考:

    【1】elasticsearch/plugins/examples at main · elastic/elasticsearch · GitHub

  • 相关阅读:
    js数组去重的10种方法
    提升职场竞争力,掌握高级开发面试知识!
    MyBatisPlus知识点总结-DX的笔记
    基于Java的毕业设计选题管理系统设计与实现(源码+lw+部署文档+讲解等)
    leetcode每日一题寒假版-1805.字符串中不同整数的数目(easy)
    视频号视频提取小程序,快速下载视频号视频
    天地图自定义标记点
    阿里云Serverless 极速搭建Hexo博客
    网络安全:windows批处理写病毒的一些基本命令.
    国庆要闻回顾 | OpenAI 拟研发 AI 手机;9月以太坊上NFT销售量创2021年2月以来最低记录...
  • 原文地址:https://blog.csdn.net/UbuntuTouch/article/details/126717927