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 @@ + + + + + 4.0.0 + + + apm-sdk-plugin + org.apache.skywalking + 9.7.0-SNAPSHOT + + + apm-elasticsearch-java-plugin + jar + + elasticsearch-java-plugin + + + 8.17.0 + + + + + co.elastic.clients + elasticsearch-java + ${elasticsearch-java.version} + provided + + + 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. + *

+ * 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 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). + *

+ * 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 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 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 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. + *

+ * 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 @@ elasticsearch-5.x-plugin elasticsearch-6.x-plugin elasticsearch-7.x-plugin + elasticsearch-java-plugin undertow-plugins rabbitmq-plugin dubbo-conflict-patch 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 @@ + + + + + org.apache.skywalking.apm.testcase + elasticsearch-java-9.x-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 17 + 3.8.1 + + 9.0.0 + + 3.0.13 + + + skywalking-elasticsearch-java-9.x-scenario + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + jul-to-slf4j + org.slf4j + + + + + + co.elastic.clients + elasticsearch-java + ${test.framework.version} + + + + org.elasticsearch.client + elasticsearch-rest-client + ${test.framework.version} + + + com.fasterxml.jackson.core + jackson-databind + + + + + elasticsearch-java-9.x-scenario + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + 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 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/elasticsearch-java-9.x-scenario.jar + ./libs + 0775 + + + 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 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 getResp = client.get(g -> g.index("test-index").id("1"), Map.class); + + // Search + SearchResponse 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 @@ + + + + + + + + + + + + + + \ 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 @@ + + + + + org.apache.skywalking.apm.testcase + elasticsearch-java-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 1.8 + 3.8.1 + + 8.12.0 + + 2.1.6.RELEASE + + + skywalking-elasticsearch-java-scenario + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + jul-to-slf4j + org.slf4j + + + + + + co.elastic.clients + elasticsearch-java + ${test.framework.version} + + + + org.elasticsearch.client + elasticsearch-rest-client + ${test.framework.version} + + + com.fasterxml.jackson.core + jackson-databind + + + + + elasticsearch-java-scenario + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + 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 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/elasticsearch-java-scenario.jar + ./libs + 0775 + + + 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 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 getResp = client.get(g -> g.index("test-index").id("1"), Map.class); + + // Search + SearchResponse 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 @@ + + + + + + + + + + + + + + \ 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