This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-java.git


The following commit(s) were added to refs/heads/main by this push:
     new e732a3222f Add Elasticsearch Java client plugin for 7.16.x-9.x (#804)
e732a3222f is described below

commit e732a3222f4a58844c6062a1dfa74f2d871f2835
Author: 吴晟 Wu Sheng <[email protected]>
AuthorDate: Fri Apr 10 16:03:31 2026 +0800

    Add Elasticsearch Java client plugin for 7.16.x-9.x (#804)
    
      Add Elasticsearch Java client (co.elastic.clients:elasticsearch-java) 
plugin for 7.16.x-9.x
    
      Instrument RestClientTransport and ElasticsearchTransportBase to create 
ExitSpans for Elasticsearch operations. Captures db.type, db.instance (index 
name), and db.statement
      (request DSL) tags, aligned with existing ES plugin conventions. Tested 
across 26 versions covering every minor from 7.16 to 9.3.
---
 .github/workflows/plugins-jdk17-test.1.yaml        |   1 +
 .github/workflows/plugins-test.2.yaml              |   1 +
 CHANGES.md                                         |   1 +
 .../elasticsearch-java-plugin/pom.xml              |  48 +++++++
 .../java/ElasticsearchPluginConfig.java            |  35 ++++++
 .../ElasticsearchTransportBaseInstrumentation.java |  81 ++++++++++++
 .../define/RestClientTransportInstrumentation.java |  97 +++++++++++++++
 .../RestClientTransportConstructorInterceptor.java |  43 +++++++
 .../TransportPerformRequestInterceptor.java        | 114 +++++++++++++++++
 .../src/main/resources/skywalking-plugin.def       |  19 +++
 apm-sniffer/apm-sdk-plugin/pom.xml                 |   1 +
 .../setup/service-agent/java-agent/Plugin-list.md  |   1 +
 .../service-agent/java-agent/Supported-list.md     |   1 +
 .../elasticsearch-java-9.x-scenario/bin/startup.sh |  21 ++++
 .../config/expectedData.yaml                       | 125 +++++++++++++++++++
 .../configuration.yml                              |  34 +++++
 .../elasticsearch-java-9.x-scenario/pom.xml        | 138 +++++++++++++++++++++
 .../src/main/assembly/assembly.xml                 |  41 ++++++
 .../apm/testcase/elasticsearch/Application.java    |  30 +++++
 .../elasticsearch/controller/CaseController.java   |  96 ++++++++++++++
 .../src/main/resources/application.yaml            |  21 ++++
 .../src/main/resources/log4j2.xml                  |  30 +++++
 .../support-version.list                           |  22 ++++
 .../elasticsearch-java-scenario/bin/startup.sh     |  21 ++++
 .../config/expectedData.yaml                       | 125 +++++++++++++++++++
 .../elasticsearch-java-scenario/configuration.yml  |  34 +++++
 .../scenarios/elasticsearch-java-scenario/pom.xml  | 138 +++++++++++++++++++++
 .../src/main/assembly/assembly.xml                 |  41 ++++++
 .../apm/testcase/elasticsearch/Application.java    |  29 +++++
 .../elasticsearch/controller/CaseController.java   |  97 +++++++++++++++
 .../src/main/resources/application.yaml            |  21 ++++
 .../src/main/resources/log4j2.xml                  |  30 +++++
 .../support-version.list                           |  42 +++++++
 33 files changed, 1579 insertions(+)

diff --git a/.github/workflows/plugins-jdk17-test.1.yaml 
b/.github/workflows/plugins-jdk17-test.1.yaml
index 939393713b..ed6efcfef4 100644
--- a/.github/workflows/plugins-jdk17-test.1.yaml
+++ b/.github/workflows/plugins-jdk17-test.1.yaml
@@ -81,6 +81,7 @@ jobs:
           - spring-scheduled-6.x-scenario
           - caffeine-3.x-scenario
           - lettuce-webflux-6x-scenario
+          - elasticsearch-java-9.x-scenario
     steps:
       - uses: actions/checkout@v2
         with:
diff --git a/.github/workflows/plugins-test.2.yaml 
b/.github/workflows/plugins-test.2.yaml
index 5fe28c244f..1bbf07ef31 100644
--- a/.github/workflows/plugins-test.2.yaml
+++ b/.github/workflows/plugins-test.2.yaml
@@ -97,6 +97,7 @@ jobs:
           - nacos-client-2.x-scenario
           - rocketmq-scenario
           - rocketmq-5-grpc-scenario
+          - elasticsearch-java-scenario
     steps:
       - uses: actions/checkout@v2
         with:
diff --git a/CHANGES.md b/CHANGES.md
index ad1e3f6c51..237ce9ff0c 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -21,6 +21,7 @@ Release Notes.
 * Enhance test/plugin/run.sh to support extra Maven properties per version in 
support-version.list (format: version,key=value).
 * Add MariaDB 3.x plugin (all classes renamed in 3.x).
 * Extend Jedis 4.x plugin to support Jedis 5.x (fix witness method for 5.x 
compatibility).
+* Add Elasticsearch Java client (co.elastic.clients:elasticsearch-java) plugin 
for 7.x-9.x.
 
 All issues and pull requests are 
[here](https://github.com/apache/skywalking/milestone/249?closed=1)
 
diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/pom.xml 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/pom.xml
new file mode 100644
index 0000000000..0126147e82
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>apm-sdk-plugin</artifactId>
+        <groupId>org.apache.skywalking</groupId>
+        <version>9.7.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>apm-elasticsearch-java-plugin</artifactId>
+    <packaging>jar</packaging>
+
+    <name>elasticsearch-java-plugin</name>
+
+    <properties>
+        <elasticsearch-java.version>8.17.0</elasticsearch-java.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>co.elastic.clients</groupId>
+            <artifactId>elasticsearch-java</artifactId>
+            <version>${elasticsearch-java.version}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
diff --git 
a/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/ElasticsearchPluginConfig.java
 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/ElasticsearchPluginConfig.java
new file mode 100644
index 0000000000..c435f439a8
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/ElasticsearchPluginConfig.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.elasticsearch.java;
+
+import org.apache.skywalking.apm.agent.core.boot.PluginConfig;
+
+public class ElasticsearchPluginConfig {
+    public static class Plugin {
+        @PluginConfig(root = ElasticsearchPluginConfig.class)
+        public static class Elasticsearch {
+            /**
+             * If true, trace all the DSL(Domain Specific Language) in 
ElasticSearch access, default is false
+             */
+            public static boolean TRACE_DSL = false;
+
+            public static int ELASTICSEARCH_DSL_LENGTH_THRESHOLD = 1024;
+        }
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/define/ElasticsearchTransportBaseInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/define/ElasticsearchTransportBaseInstrumentation.java
new file mode 100644
index 0000000000..6ac75f023c
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/define/ElasticsearchTransportBaseInstrumentation.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.elasticsearch.java.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+/**
+ * Enhance {@code co.elastic.clients.transport.ElasticsearchTransportBase}
+ * which exists in elasticsearch-java 8.x+. The performRequest method
+ * moved from RestClientTransport to this base class in 8.x.
+ * <p>
+ * The peer is propagated from RestClientTransport (subclass) via dynamic 
field.
+ */
+public class ElasticsearchTransportBaseInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
+
+    private static final String ENHANCE_CLASS = 
"co.elastic.clients.transport.ElasticsearchTransportBase";
+
+    private static final String PERFORM_REQUEST_INTERCEPTOR =
+        
"org.apache.skywalking.apm.plugin.elasticsearch.java.interceptor.TransportPerformRequestInterceptor";
+
+    @Override
+    protected String[] witnessClasses() {
+        return new String[] {ENHANCE_CLASS};
+    }
+
+    @Override
+    protected ClassMatch enhanceClass() {
+        return byName(ENHANCE_CLASS);
+    }
+
+    @Override
+    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[0];
+    }
+
+    @Override
+    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() 
{
+        return new InstanceMethodsInterceptPoint[] {
+            new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("performRequest");
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return PERFORM_REQUEST_INTERCEPTOR;
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            }
+        };
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/define/RestClientTransportInstrumentation.java
 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/define/RestClientTransportInstrumentation.java
new file mode 100644
index 0000000000..e5dacab15f
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/define/RestClientTransportInstrumentation.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.elasticsearch.java.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static 
org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
+import static 
org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+/**
+ * Enhance {@code co.elastic.clients.transport.rest_client.RestClientTransport}
+ * for the Elasticsearch Java client (co.elastic.clients:elasticsearch-java).
+ * <p>
+ * Covers both 7.x (performRequest on RestClientTransport) and 8.x+
+ * (performRequest inherited from ElasticsearchTransportBase, but constructor 
on RestClientTransport).
+ */
+public class RestClientTransportInstrumentation extends 
ClassInstanceMethodsEnhancePluginDefine {
+
+    private static final String ENHANCE_CLASS = 
"co.elastic.clients.transport.rest_client.RestClientTransport";
+
+    private static final String CONSTRUCTOR_INTERCEPTOR =
+        
"org.apache.skywalking.apm.plugin.elasticsearch.java.interceptor.RestClientTransportConstructorInterceptor";
+
+    private static final String PERFORM_REQUEST_INTERCEPTOR =
+        
"org.apache.skywalking.apm.plugin.elasticsearch.java.interceptor.TransportPerformRequestInterceptor";
+
+    @Override
+    protected String[] witnessClasses() {
+        return new String[] {ENHANCE_CLASS};
+    }
+
+    @Override
+    protected ClassMatch enhanceClass() {
+        return byName(ENHANCE_CLASS);
+    }
+
+    @Override
+    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[] {
+            new ConstructorInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> 
getConstructorMatcher() {
+                    return takesArgumentWithType(0, 
"org.elasticsearch.client.RestClient");
+                }
+
+                @Override
+                public String getConstructorInterceptor() {
+                    return CONSTRUCTOR_INTERCEPTOR;
+                }
+            }
+        };
+    }
+
+    @Override
+    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() 
{
+        return new InstanceMethodsInterceptPoint[] {
+            new InstanceMethodsInterceptPoint() {
+                @Override
+                public ElementMatcher<MethodDescription> getMethodsMatcher() {
+                    return named("performRequest");
+                }
+
+                @Override
+                public String getMethodsInterceptor() {
+                    return PERFORM_REQUEST_INTERCEPTOR;
+                }
+
+                @Override
+                public boolean isOverrideArgs() {
+                    return false;
+                }
+            }
+        };
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/interceptor/RestClientTransportConstructorInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/interceptor/RestClientTransportConstructorInterceptor.java
new file mode 100644
index 0000000000..e96932ace3
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/interceptor/RestClientTransportConstructorInterceptor.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.elasticsearch.java.interceptor;
+
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+import org.elasticsearch.client.Node;
+import org.elasticsearch.client.RestClient;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Intercept RestClientTransport constructor to extract peer address from 
RestClient nodes.
+ */
+public class RestClientTransportConstructorInterceptor implements 
InstanceConstructorInterceptor {
+
+    @Override
+    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+        RestClient restClient = (RestClient) allArguments[0];
+        List<Node> nodes = restClient.getNodes();
+        String peers = nodes.stream()
+            .map(node -> node.getHost().toHostString())
+            .collect(Collectors.joining(","));
+        objInst.setSkyWalkingDynamicField(peers);
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/interceptor/TransportPerformRequestInterceptor.java
 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/interceptor/TransportPerformRequestInterceptor.java
new file mode 100644
index 0000000000..ebf8ec6d41
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/java/interceptor/TransportPerformRequestInterceptor.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.elasticsearch.java.interceptor;
+
+import co.elastic.clients.transport.Endpoint;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import 
org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import 
org.apache.skywalking.apm.plugin.elasticsearch.java.ElasticsearchPluginConfig;
+
+import java.lang.reflect.Method;
+
+/**
+ * Intercept ElasticsearchTransport.performRequest() to create exit spans.
+ * <p>
+ * Args: [0] request, [1] endpoint (Endpoint), [2] options (TransportOptions)
+ * The endpoint.id() provides the operation name (e.g., "search", "index", 
"bulk").
+ */
+public class TransportPerformRequestInterceptor implements 
InstanceMethodsAroundInterceptor {
+
+    private static final String DB_TYPE = "Elasticsearch";
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] 
allArguments,
+                             Class<?>[] argumentsTypes, MethodInterceptResult 
result) throws Throwable {
+        Endpoint endpoint = (Endpoint) allArguments[1];
+        String operationName = "Elasticsearch/" + endpoint.id();
+
+        String peers = (String) objInst.getSkyWalkingDynamicField();
+        if (peers == null || peers.isEmpty()) {
+            peers = "Unknown";
+        }
+
+        AbstractSpan span = ContextManager.createExitSpan(operationName, 
peers);
+        span.setComponent(ComponentsDefine.REST_HIGH_LEVEL_CLIENT);
+        Tags.DB_TYPE.set(span, DB_TYPE);
+        SpanLayer.asDB(span);
+
+        Object request = allArguments[0];
+        String requestUrl = endpoint.requestUrl(request);
+        String index = extractIndex(requestUrl);
+        if (index != null) {
+            span.tag(Tags.ofKey("db.instance"), index);
+        }
+        if (ElasticsearchPluginConfig.Plugin.Elasticsearch.TRACE_DSL) {
+            String dsl = request.toString();
+            if (dsl != null && !dsl.isEmpty()) {
+                int maxLen = 
ElasticsearchPluginConfig.Plugin.Elasticsearch.ELASTICSEARCH_DSL_LENGTH_THRESHOLD;
+                if (maxLen > 0 && dsl.length() > maxLen) {
+                    dsl = dsl.substring(0, maxLen) + "...";
+                }
+                Tags.DB_STATEMENT.set(span, dsl);
+            }
+        }
+    }
+
+    @Override
+    public Object afterMethod(EnhancedInstance objInst, Method method, 
Object[] allArguments,
+                              Class<?>[] argumentsTypes, Object ret) throws 
Throwable {
+        ContextManager.stopSpan();
+        return ret;
+    }
+
+    @Override
+    public void handleMethodException(EnhancedInstance objInst, Method method, 
Object[] allArguments,
+                                      Class<?>[] argumentsTypes, Throwable t) {
+        ContextManager.activeSpan().log(t);
+        ContextManager.activeSpan().errorOccurred();
+    }
+
+    /**
+     * Extract index name from request URL.
+     * E.g., "/test-index/_doc/1" → "test-index", "/_bulk" → null
+     */
+    static String extractIndex(String requestUrl) {
+        if (requestUrl == null || requestUrl.isEmpty()) {
+            return null;
+        }
+        // Remove leading slash
+        String path = requestUrl.startsWith("/") ? requestUrl.substring(1) : 
requestUrl;
+        if (path.isEmpty()) {
+            return null;
+        }
+        // First segment before '/' or '_' prefix means no index
+        int slashIdx = path.indexOf('/');
+        String firstSegment = slashIdx > 0 ? path.substring(0, slashIdx) : 
path;
+        if (firstSegment.startsWith("_")) {
+            return null;
+        }
+        return firstSegment;
+    }
+}
diff --git 
a/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/resources/skywalking-plugin.def
 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 0000000000..b13b674473
--- /dev/null
+++ 
b/apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Elasticsearch Java client (co.elastic.clients:elasticsearch-java) 7.16.x-9.x
+elasticsearch-java=org.apache.skywalking.apm.plugin.elasticsearch.java.define.RestClientTransportInstrumentation
+elasticsearch-java=org.apache.skywalking.apm.plugin.elasticsearch.java.define.ElasticsearchTransportBaseInstrumentation
diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml 
b/apm-sniffer/apm-sdk-plugin/pom.xml
index 775ec34e12..5d09bd0957 100644
--- a/apm-sniffer/apm-sdk-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/pom.xml
@@ -71,6 +71,7 @@
         <module>elasticsearch-5.x-plugin</module>
         <module>elasticsearch-6.x-plugin</module>
         <module>elasticsearch-7.x-plugin</module>
+        <module>elasticsearch-java-plugin</module>
         <module>undertow-plugins</module>
         <module>rabbitmq-plugin</module>
         <module>dubbo-conflict-patch</module>
diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md 
b/docs/en/setup/service-agent/java-agent/Plugin-list.md
index 2bfd58f872..ed16dc1f85 100644
--- a/docs/en/setup/service-agent/java-agent/Plugin-list.md
+++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md
@@ -25,6 +25,7 @@
 - elasticsearch-5.x
 - elasticsearch-6.x
 - elasticsearch-7.x
+- elasticsearch-java
 - fastjson-1.2.x
 - feign-default-http-9.x
 - feign-pathvar-9.x
diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md 
b/docs/en/setup/service-agent/java-agent/Supported-list.md
index 772f169c39..ca6f481f06 100644
--- a/docs/en/setup/service-agent/java-agent/Supported-list.md
+++ b/docs/en/setup/service-agent/java-agent/Supported-list.md
@@ -101,6 +101,7 @@ metrics based on the tracing data.
     * 
[transport-client](https://github.com/elastic/elasticsearch/tree/7.0/client/transport)
 7.0.0-7.5.2
     * 
[rest-high-level-client](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/6.7/index.html)
 6.7.1-6.8.4
     * 
[rest-high-level-client](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.0/java-rest-high.html)
 7.x
+    * 
[elasticsearch-java](https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/index.html)
 7.17.x-9.x
   * [Solr](https://github.com/apache/solr/)
     * [SolrJ](https://github.com/apache/solr/tree/main/solr/solrj) 7.x
   * [Cassandra](https://github.com/apache/cassandra) 3.x
diff --git 
a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/bin/startup.sh 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/bin/startup.sh
new file mode 100644
index 0000000000..e054a8dc76
--- /dev/null
+++ b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -jar ${agent_opts} -Dskywalking.plugin.elasticsearch.trace_dsl=true 
${home}/../libs/elasticsearch-java-9.x-scenario.jar &
diff --git 
a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/config/expectedData.yaml
 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/config/expectedData.yaml
new file mode 100644
index 0000000000..b9af4b71cc
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/config/expectedData.yaml
@@ -0,0 +1,125 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+segmentItems:
+- serviceName: elasticsearch-java-9.x-scenario
+  segmentSize: ge 2
+  segments:
+  - segmentId: not null
+    spans:
+    - operationName: Elasticsearch/es/indices.create
+      parentSpanId: 0
+      spanId: 1
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/index
+      parentSpanId: 0
+      spanId: 2
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/get
+      parentSpanId: 0
+      spanId: 3
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/search
+      parentSpanId: 0
+      spanId: 4
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/delete
+      parentSpanId: 0
+      spanId: 5
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/indices.delete
+      parentSpanId: 0
+      spanId: 6
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: GET:/elasticsearch-java-case/case/elasticsearch
+      parentSpanId: -1
+      spanId: 0
+      startTime: nq 0
+      endTime: nq 0
+      spanLayer: Http
+      isError: false
+      spanType: Entry
+      componentId: 1
+      tags:
+      - {key: url, value: not null}
+      - {key: http.method, value: GET}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
diff --git 
a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/configuration.yml 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/configuration.yml
new file mode 100644
index 0000000000..f660224a0f
--- /dev/null
+++ b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/configuration.yml
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+type: jvm
+entryService: http://localhost:8080/elasticsearch-java-case/case/elasticsearch
+healthCheck: http://localhost:8080/elasticsearch-java-case/case/healthCheck
+startScript: ./bin/startup.sh
+environment:
+- elasticsearch.server=elasticsearch-server:9200
+dependencies:
+  elasticsearch-server:
+    image: docker.elastic.co/elasticsearch/elasticsearch:9.0.0
+    hostname: elasticsearch-server
+    removeOnExit: true
+    expose:
+    - 9200
+    environment:
+    - cluster.name=docker-node
+    - xpack.security.enabled=false
+    - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
+    - discovery.type=single-node
diff --git a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/pom.xml 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/pom.xml
new file mode 100644
index 0000000000..8ca30a4aa0
--- /dev/null
+++ b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/pom.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+    <groupId>org.apache.skywalking.apm.testcase</groupId>
+    <artifactId>elasticsearch-java-9.x-scenario</artifactId>
+    <version>1.0.0</version>
+    <packaging>jar</packaging>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <compiler.version>17</compiler.version>
+        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
+
+        <test.framework.version>9.0.0</test.framework.version>
+
+        <spring.boot.version>3.0.13</spring.boot.version>
+    </properties>
+
+    <name>skywalking-elasticsearch-java-9.x-scenario</name>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring.boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>jul-to-slf4j</artifactId>
+                    <groupId>org.slf4j</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- Elasticsearch Java client -->
+        <dependency>
+            <groupId>co.elastic.clients</groupId>
+            <artifactId>elasticsearch-java</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+        <!-- Must match elasticsearch-java version, override Spring Boot BOM 
-->
+        <dependency>
+            <groupId>org.elasticsearch.client</groupId>
+            <artifactId>elasticsearch-rest-client</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>elasticsearch-java-9.x-scenario</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring.boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <source>${compiler.version}</source>
+                    <target>${compiler.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                
<descriptor>src/main/assembly/assembly.xml</descriptor>
+                            </descriptors>
+                            <outputDirectory>./target/</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git 
a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/assembly/assembly.xml
 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 0000000000..42a1323949
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+<assembly
+    
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
 http://maven.apache.org/xsd/assembly-1.1.2.xsd";>
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <fileSets>
+        <fileSet>
+            <directory>./bin</directory>
+            <fileMode>0775</fileMode>
+        </fileSet>
+    </fileSets>
+
+    <files>
+        <file>
+            
<source>${project.build.directory}/elasticsearch-java-9.x-scenario.jar</source>
+            <outputDirectory>./libs</outputDirectory>
+            <fileMode>0775</fileMode>
+        </file>
+    </files>
+</assembly>
diff --git 
a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/Application.java
 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/Application.java
new file mode 100644
index 0000000000..3ce49f987a
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/Application.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.testcase.elasticsearch;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import 
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration;
+
+@SpringBootApplication(exclude = ElasticsearchClientAutoConfiguration.class)
+public class Application {
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
diff --git 
a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/controller/CaseController.java
 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/controller/CaseController.java
new file mode 100644
index 0000000000..3f2be16239
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/controller/CaseController.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.testcase.elasticsearch.controller;
+
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.elasticsearch.core.IndexResponse;
+import co.elastic.clients.elasticsearch.core.GetResponse;
+import co.elastic.clients.elasticsearch.core.SearchResponse;
+import co.elastic.clients.elasticsearch.core.DeleteResponse;
+import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
+import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse;
+import co.elastic.clients.json.jackson.JacksonJsonpMapper;
+import co.elastic.clients.transport.rest_client.RestClientTransport;
+import org.apache.http.HttpHost;
+import org.elasticsearch.client.RestClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/elasticsearch-java-case/case")
+public class CaseController {
+
+    @Value("${elasticsearch.server}")
+    private String elasticsearchServer;
+
+    @GetMapping("/healthCheck")
+    public String healthCheck() throws IOException {
+        RestClient restClient = 
RestClient.builder(HttpHost.create(elasticsearchServer)).build();
+        RestClientTransport transport = new RestClientTransport(restClient, 
new JacksonJsonpMapper());
+        ElasticsearchClient client = new ElasticsearchClient(transport);
+        try {
+            client.info();
+            return "Success";
+        } finally {
+            restClient.close();
+        }
+    }
+
+    @GetMapping("/elasticsearch")
+    public String elasticsearch() throws IOException {
+        RestClient restClient = 
RestClient.builder(HttpHost.create(elasticsearchServer)).build();
+        RestClientTransport transport = new RestClientTransport(restClient, 
new JacksonJsonpMapper());
+        ElasticsearchClient client = new ElasticsearchClient(transport);
+        try {
+
+            // Create index
+            CreateIndexResponse createResp = client.indices().create(c -> 
c.index("test-index"));
+
+            // Index document
+            Map<String, Object> doc = new HashMap<>();
+            doc.put("name", "test");
+            doc.put("value", "skywalking");
+            IndexResponse indexResp = client.index(i -> 
i.index("test-index").id("1").document(doc));
+
+            // Get document
+            GetResponse<Map> getResp = client.get(g -> 
g.index("test-index").id("1"), Map.class);
+
+            // Search
+            SearchResponse<Map> searchResp = client.search(s -> s
+                .index("test-index")
+                .query(q -> q.match(m -> m.field("name").query("test"))), 
Map.class);
+
+            // Delete document
+            DeleteResponse deleteResp = client.delete(d -> 
d.index("test-index").id("1"));
+
+            // Delete index
+            DeleteIndexResponse deleteIndexResp = client.indices().delete(d -> 
d.index("test-index"));
+
+            return "Success";
+        } finally {
+            restClient.close();
+        }
+    }
+}
diff --git 
a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/resources/application.yaml
 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/resources/application.yaml
new file mode 100644
index 0000000000..ba18cc1c03
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/resources/application.yaml
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+server:
+  port: 8080
+logging:
+  config: classpath:log4j2.xml
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/resources/log4j2.xml
 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..9849ed5a8a
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/src/main/resources/log4j2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+<Configuration status="WARN">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_ERR">
+            <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd 
HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="WARN">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/elasticsearch-java-9.x-scenario/support-version.list 
b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/support-version.list
new file mode 100644
index 0000000000..2f8cf94b33
--- /dev/null
+++ b/test/plugin/scenarios/elasticsearch-java-9.x-scenario/support-version.list
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# co.elastic.clients:elasticsearch-java 9.x (requires JDK 17)
+# Versions must match elasticsearch-rest-client available versions
+9.0.8
+9.1.10
+9.2.8
+9.3.3
diff --git a/test/plugin/scenarios/elasticsearch-java-scenario/bin/startup.sh 
b/test/plugin/scenarios/elasticsearch-java-scenario/bin/startup.sh
new file mode 100644
index 0000000000..eb5ce9db9e
--- /dev/null
+++ b/test/plugin/scenarios/elasticsearch-java-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -jar ${agent_opts} -Dskywalking.plugin.elasticsearch.trace_dsl=true 
${home}/../libs/elasticsearch-java-scenario.jar &
diff --git 
a/test/plugin/scenarios/elasticsearch-java-scenario/config/expectedData.yaml 
b/test/plugin/scenarios/elasticsearch-java-scenario/config/expectedData.yaml
new file mode 100644
index 0000000000..0d79dbce45
--- /dev/null
+++ b/test/plugin/scenarios/elasticsearch-java-scenario/config/expectedData.yaml
@@ -0,0 +1,125 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+segmentItems:
+- serviceName: elasticsearch-java-scenario
+  segmentSize: ge 2
+  segments:
+  - segmentId: not null
+    spans:
+    - operationName: Elasticsearch/es/indices.create
+      parentSpanId: 0
+      spanId: 1
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/index
+      parentSpanId: 0
+      spanId: 2
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/get
+      parentSpanId: 0
+      spanId: 3
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/search
+      parentSpanId: 0
+      spanId: 4
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/delete
+      parentSpanId: 0
+      spanId: 5
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: Elasticsearch/es/indices.delete
+      parentSpanId: 0
+      spanId: 6
+      spanLayer: Database
+      startTime: nq 0
+      endTime: nq 0
+      componentId: 77
+      isError: false
+      spanType: Exit
+      peer: not null
+      skipAnalysis: false
+      tags:
+      - {key: db.type, value: Elasticsearch}
+      - {key: db.instance, value: test-index}
+      - {key: db.statement, value: not null}
+    - operationName: GET:/elasticsearch-java-case/case/elasticsearch
+      parentSpanId: -1
+      spanId: 0
+      startTime: nq 0
+      endTime: nq 0
+      spanLayer: Http
+      isError: false
+      spanType: Entry
+      componentId: 1
+      tags:
+      - {key: url, value: not null}
+      - {key: http.method, value: GET}
+      - {key: http.status_code, value: '200'}
+      skipAnalysis: 'false'
diff --git 
a/test/plugin/scenarios/elasticsearch-java-scenario/configuration.yml 
b/test/plugin/scenarios/elasticsearch-java-scenario/configuration.yml
new file mode 100644
index 0000000000..a6b201e828
--- /dev/null
+++ b/test/plugin/scenarios/elasticsearch-java-scenario/configuration.yml
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+type: jvm
+entryService: http://localhost:8080/elasticsearch-java-case/case/elasticsearch
+healthCheck: http://localhost:8080/elasticsearch-java-case/case/healthCheck
+startScript: ./bin/startup.sh
+environment:
+- elasticsearch.server=elasticsearch-server:9200
+dependencies:
+  elasticsearch-server:
+    image: docker.elastic.co/elasticsearch/elasticsearch:8.17.0
+    hostname: elasticsearch-server
+    removeOnExit: true
+    expose:
+    - 9200
+    environment:
+    - cluster.name=docker-node
+    - xpack.security.enabled=false
+    - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
+    - discovery.type=single-node
diff --git a/test/plugin/scenarios/elasticsearch-java-scenario/pom.xml 
b/test/plugin/scenarios/elasticsearch-java-scenario/pom.xml
new file mode 100644
index 0000000000..275b963cd2
--- /dev/null
+++ b/test/plugin/scenarios/elasticsearch-java-scenario/pom.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+    <groupId>org.apache.skywalking.apm.testcase</groupId>
+    <artifactId>elasticsearch-java-scenario</artifactId>
+    <version>1.0.0</version>
+    <packaging>jar</packaging>
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <compiler.version>1.8</compiler.version>
+        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
+
+        <test.framework.version>8.12.0</test.framework.version>
+
+        <spring.boot.version>2.1.6.RELEASE</spring.boot.version>
+    </properties>
+
+    <name>skywalking-elasticsearch-java-scenario</name>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring.boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-log4j2</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>jul-to-slf4j</artifactId>
+                    <groupId>org.slf4j</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- Elasticsearch Java client -->
+        <dependency>
+            <groupId>co.elastic.clients</groupId>
+            <artifactId>elasticsearch-java</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+        <!-- Must match elasticsearch-java version, override Spring Boot BOM 
-->
+        <dependency>
+            <groupId>org.elasticsearch.client</groupId>
+            <artifactId>elasticsearch-rest-client</artifactId>
+            <version>${test.framework.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>elasticsearch-java-scenario</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring.boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <source>${compiler.version}</source>
+                    <target>${compiler.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>assemble</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                
<descriptor>src/main/assembly/assembly.xml</descriptor>
+                            </descriptors>
+                            <outputDirectory>./target/</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git 
a/test/plugin/scenarios/elasticsearch-java-scenario/src/main/assembly/assembly.xml
 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 0000000000..20d778c34c
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+<assembly
+    
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2";
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+    
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
 http://maven.apache.org/xsd/assembly-1.1.2.xsd";>
+    <formats>
+        <format>zip</format>
+    </formats>
+
+    <fileSets>
+        <fileSet>
+            <directory>./bin</directory>
+            <fileMode>0775</fileMode>
+        </fileSet>
+    </fileSets>
+
+    <files>
+        <file>
+            
<source>${project.build.directory}/elasticsearch-java-scenario.jar</source>
+            <outputDirectory>./libs</outputDirectory>
+            <fileMode>0775</fileMode>
+        </file>
+    </files>
+</assembly>
diff --git 
a/test/plugin/scenarios/elasticsearch-java-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/Application.java
 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/Application.java
new file mode 100644
index 0000000000..2cf2b3e563
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/Application.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.testcase.elasticsearch;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
diff --git 
a/test/plugin/scenarios/elasticsearch-java-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/controller/CaseController.java
 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/controller/CaseController.java
new file mode 100644
index 0000000000..66180bfcd9
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/java/org/apache/skywalking/apm/testcase/elasticsearch/controller/CaseController.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.testcase.elasticsearch.controller;
+
+import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.elasticsearch.core.IndexResponse;
+import co.elastic.clients.elasticsearch.core.GetResponse;
+import co.elastic.clients.elasticsearch.core.SearchResponse;
+import co.elastic.clients.elasticsearch.core.DeleteResponse;
+import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
+import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse;
+import co.elastic.clients.elasticsearch._types.FieldValue;
+import co.elastic.clients.json.jackson.JacksonJsonpMapper;
+import co.elastic.clients.transport.rest_client.RestClientTransport;
+import org.apache.http.HttpHost;
+import org.elasticsearch.client.RestClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/elasticsearch-java-case/case")
+public class CaseController {
+
+    @Value("${elasticsearch.server}")
+    private String elasticsearchServer;
+
+    @GetMapping("/healthCheck")
+    public String healthCheck() throws IOException {
+        RestClient restClient = 
RestClient.builder(HttpHost.create(elasticsearchServer)).build();
+        RestClientTransport transport = new RestClientTransport(restClient, 
new JacksonJsonpMapper());
+        ElasticsearchClient client = new ElasticsearchClient(transport);
+        try {
+            client.info();
+            return "Success";
+        } finally {
+            restClient.close();
+        }
+    }
+
+    @GetMapping("/elasticsearch")
+    public String elasticsearch() throws IOException {
+        RestClient restClient = 
RestClient.builder(HttpHost.create(elasticsearchServer)).build();
+        RestClientTransport transport = new RestClientTransport(restClient, 
new JacksonJsonpMapper());
+        ElasticsearchClient client = new ElasticsearchClient(transport);
+        try {
+
+            // Create index
+            CreateIndexResponse createResp = client.indices().create(c -> 
c.index("test-index"));
+
+            // Index document
+            Map<String, Object> doc = new HashMap<>();
+            doc.put("name", "test");
+            doc.put("value", "skywalking");
+            IndexResponse indexResp = client.index(i -> 
i.index("test-index").id("1").document(doc));
+
+            // Get document
+            GetResponse<Map> getResp = client.get(g -> 
g.index("test-index").id("1"), Map.class);
+
+            // Search
+            SearchResponse<Map> searchResp = client.search(s -> s
+                .index("test-index")
+                .query(q -> q.match(m -> 
m.field("name").query(FieldValue.of("test")))), Map.class);
+
+            // Delete document
+            DeleteResponse deleteResp = client.delete(d -> 
d.index("test-index").id("1"));
+
+            // Delete index
+            DeleteIndexResponse deleteIndexResp = client.indices().delete(d -> 
d.index("test-index"));
+
+            return "Success";
+        } finally {
+            restClient.close();
+        }
+    }
+}
diff --git 
a/test/plugin/scenarios/elasticsearch-java-scenario/src/main/resources/application.yaml
 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/resources/application.yaml
new file mode 100644
index 0000000000..ba18cc1c03
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/resources/application.yaml
@@ -0,0 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+server:
+  port: 8080
+logging:
+  config: classpath:log4j2.xml
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/elasticsearch-java-scenario/src/main/resources/log4j2.xml
 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/resources/log4j2.xml
new file mode 100644
index 0000000000..9849ed5a8a
--- /dev/null
+++ 
b/test/plugin/scenarios/elasticsearch-java-scenario/src/main/resources/log4j2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+<Configuration status="WARN">
+    <Appenders>
+        <Console name="Console" target="SYSTEM_ERR">
+            <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd 
HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="WARN">
+            <AppenderRef ref="Console"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git 
a/test/plugin/scenarios/elasticsearch-java-scenario/support-version.list 
b/test/plugin/scenarios/elasticsearch-java-scenario/support-version.list
new file mode 100644
index 0000000000..114e16d1bf
--- /dev/null
+++ b/test/plugin/scenarios/elasticsearch-java-scenario/support-version.list
@@ -0,0 +1,42 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# co.elastic.clients:elasticsearch-java
+# ES server fixed at 8.17.0 (backward compatible with 7.x/8.x clients)
+# 7.16+: co.elastic.clients.transport.rest_client.RestClientTransport
+# 8.x: ElasticsearchTransportBase.performRequest
+7.16.3
+7.17.29
+8.0.1
+8.1.3
+8.2.3
+8.3.3
+8.4.3
+8.5.3
+8.6.2
+8.7.1
+8.8.2
+8.9.2
+8.10.4
+8.11.4
+8.12.2
+8.13.4
+8.14.3
+8.15.5
+8.16.6
+8.17.10
+8.18.8
+8.19.14

Reply via email to