diff --git a/.github/workflows/plugins-test.1.yaml b/.github/workflows/plugins-test.1.yaml index b00d01906c6cad95948fa83b834b3822bee08791..a55ba6dc0171ac97a26dccb6ef60151bf97ac4e4 100644 --- a/.github/workflows/plugins-test.1.yaml +++ b/.github/workflows/plugins-test.1.yaml @@ -60,6 +60,7 @@ jobs: - mongodb-4.x-scenario - netty-socketio-scenario - postgresql-above9.4.1207-scenario + - mssql-jtds-scenario steps: - uses: actions/checkout@v2 with: diff --git a/CHANGES.md b/CHANGES.md index 4ea802ea0903482097b39aaf03c8ab20f17806d2..bf8c6b79489fee663a6d478d78fd463314f04b83 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,6 +18,7 @@ Release Notes. * Add the plugin for async-http-client 2.x * Fix NPE in the nutz plugin. * Provide Apache Commons DBCP 2.x plugin. +* Add the plugin for mssql-jtds 1.x plugin. #### OAP-Backend * Add the `@SuperDataset` annotation for BrowserErrorLog. diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java index 0146301edb9a451070f9f999e485e502682ee872..acdd5a8d2ce12b68caf2eaef28e97b2f508726bd 100755 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -188,4 +188,6 @@ public class ComponentsDefine { public static final OfficialComponent ASYNC_HTTP_CLIENT = new OfficialComponent(102, "AsyncHttpClient"); public static final OfficialComponent DBCP = new OfficialComponent(103, "dbcp"); + + public static final OfficialComponent MSSQL_JDBC_DRIVER = new OfficialComponent(104, "mssql-jdbc-driver"); } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MssqlJtdsURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MssqlJtdsURLParser.java new file mode 100644 index 0000000000000000000000000000000000000000..639d141b308c4788d90a660c2ac9e645bde8d164 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/MssqlJtdsURLParser.java @@ -0,0 +1,122 @@ +/* + * 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.jdbc.connectionurl.parser; + +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.apache.skywalking.apm.network.trace.component.OfficialComponent; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; + +/** + * {@link MssqlJtdsURLParser} parse connection url of mssql. + */ +public class MssqlJtdsURLParser extends AbstractURLParser { + + private static final int DEFAULT_PORT = 1433; + private String dbType = "Mssql"; + private OfficialComponent component = ComponentsDefine.MSSQL_JDBC_DRIVER; + private static ILog LOGGER = LogManager.getLogger(MssqlJtdsURLParser.class); + + public MssqlJtdsURLParser(String url) { + super(url); + } + + public MssqlJtdsURLParser(String url, String dbType, OfficialComponent component) { + super(url); + this.dbType = dbType; + this.component = component; + } + + @Override + protected URLLocation fetchDatabaseHostsIndexRange() { + int hostLabelStartIndex = url.indexOf("//"); + int hostLabelEndIndex = url.indexOf(";", hostLabelStartIndex + 2); + if (hostLabelEndIndex == -1) { + hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2); + } + return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex); + } + + protected String fetchDatabaseNameFromURL(int startSize) { + URLLocation hostsLocation = fetchDatabaseNameIndexRange(startSize); + if (hostsLocation == null) { + return ""; + } + return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex()); + } + + protected URLLocation fetchDatabaseNameIndexRange(int startSize) { + int databaseStartTag = url.indexOf("/", startSize); + if (databaseStartTag == -1) { + return null; + } + int databaseEndTag = url.indexOf(";", databaseStartTag); + if (databaseEndTag == -1) { + databaseEndTag = url.length(); + } + return new URLLocation(databaseStartTag + 1, databaseEndTag); + } + + @Override + protected URLLocation fetchDatabaseNameIndexRange() { + int databaseStartTag = url.lastIndexOf("/"); + int databaseEndTag = url.indexOf(";", databaseStartTag); + if (databaseEndTag == -1) { + databaseEndTag = url.length(); + } + return new URLLocation(databaseStartTag + 1, databaseEndTag); + } + + @Override + public ConnectionInfo parse() { + try { + URLLocation location = fetchDatabaseHostsIndexRange(); + String hosts = url.substring(location.startIndex(), location.endIndex()); + String[] hostSegment = hosts.split(","); + if (hostSegment.length > 1) { + StringBuilder sb = new StringBuilder(); + for (String host : hostSegment) { + if (host.split(":").length == 1) { + sb.append(host).append(":").append(DEFAULT_PORT).append(","); + } else { + sb.append(host).append(","); + } + } + return new ConnectionInfo( + component, dbType, sb.substring(0, sb.length() - 1), fetchDatabaseNameFromURL()); + } else { + String[] hostAndPort = hostSegment[0].split(":"); + if (hostAndPort.length != 1) { + return new ConnectionInfo( + component, dbType, hostAndPort[0], Integer.valueOf(hostAndPort[1]), + fetchDatabaseNameFromURL(location.endIndex()) + ); + } else { + return new ConnectionInfo( + component, dbType, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL(location + .endIndex())); + } + } + } catch (Exception e) { + LOGGER.error(e, "parse mssql connection info error, url:{}", url); + return new ConnectionInfo(component, dbType, url, "UNKNOWN"); + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java index 12c6e042c546109a23e51f62d2826af9bc5bf67d..e31f70606bd3754b282d714ead461c84acc72dd7 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java @@ -31,6 +31,7 @@ public class URLParser { private static final String H2_JDBC_URL_PREFIX = "jdbc:h2"; private static final String POSTGRESQL_JDBC_URL_PREFIX = "jdbc:postgresql"; private static final String MARIADB_JDBC_URL_PREFIX = "jdbc:mariadb"; + private static final String MSSQL_JTDS_URL_PREFIX = "jdbc:jtds:sqlserver:"; public static ConnectionInfo parser(String url) { ConnectionURLParser parser = null; @@ -45,6 +46,8 @@ public class URLParser { parser = new PostgreSQLURLParser(url); } else if (lowerCaseUrl.startsWith(MARIADB_JDBC_URL_PREFIX)) { parser = new MariadbURLParser(url); + } else if (lowerCaseUrl.startsWith(MSSQL_JTDS_URL_PREFIX)) { + parser = new MssqlJtdsURLParser(url); } return parser.parse(); } diff --git a/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..a117949419495199c5ceefa8467d0c2f99b7c9c8 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/pom.xml @@ -0,0 +1,52 @@ + + + + + apm-sdk-plugin + org.apache.skywalking + 8.3.0-SNAPSHOT + + 4.0.0 + + apm-mssql-jtds-1.x-plugin + jar + + mssql-jtds-1.x-plugin + http://maven.apache.org + + + 1.2.6 + + + + + org.apache.skywalking + apm-jdbc-commons + ${project.version} + provided + + + + net.sourceforge.jtds + jtds + ${mssql-jtds.version} + provided + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mssql/jtds/v1/define/AbstractConnectionInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mssql/jtds/v1/define/AbstractConnectionInstrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..2a3c2ab6fd03c16d594cc06b3da7089b083fa135 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mssql/jtds/v1/define/AbstractConnectionInstrumentation.java @@ -0,0 +1,150 @@ +/* + * 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.mssql.jtds.v1.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.plugin.jdbc.define.Constants; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; + +/** + * {@link AbstractConnectionInstrumentation} define how to enhance the following methods that the class which extend + * {@link java.sql.Connection}. + *

+ * 1. Enhance prepareStatement by org.apache.skywalking.apm.plugin.jdbc.define.JDBCPrepareStatementInterceptor + * 2. Enhance prepareCall by org.apache.skywalking.apm.plugin.jdbc.define.JDBCPrepareCallInterceptor + * 3. Enhance createStatement by org.apache.skywalking.apm.plugin.jdbc.define.JDBCStatementInterceptor + * 4. Enhance commit, rollback, close, releaseSavepoint by org.apache.skywalking.apm.plugin.jdbc.define.ConnectionServiceMethodInterceptor + */ +public abstract class AbstractConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(1)); + } + + @Override + public String getMethodsInterceptor() { + return Constants.PREPARE_STATEMENT_INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(3)); + } + + @Override + public String getMethodsInterceptor() { + return Constants.PREPARE_STATEMENT_INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(4)); + } + + @Override + public String getMethodsInterceptor() { + return Constants.PREPARE_STATEMENT_INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.PREPARE_CALL_METHOD_NAME); + } + + @Override + public String getMethodsInterceptor() { + return Constants.PREPARE_CALL_INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.CREATE_STATEMENT_METHOD_NAME); + } + + @Override + public String getMethodsInterceptor() { + return Constants.CREATE_STATEMENT_INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.COMMIT_METHOD_NAME).or(named(Constants.ROLLBACK_METHOD_NAME)) + .or(named(Constants.CLOSE_METHOD_NAME)) + .or(named(Constants.RELEASE_SAVE_POINT_METHOD_NAME)); + } + + @Override + public String getMethodsInterceptor() { + return Constants.SERVICE_METHOD_INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mssql/jtds/v1/define/ConnectionInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mssql/jtds/v1/define/ConnectionInstrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..2fdde6c4fc99725acfa21a26d2d9a2a278ddf985 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mssql/jtds/v1/define/ConnectionInstrumentation.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.mssql.jtds.v1.define; + +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch; + +/** + * {@link ConnectionInstrumentation} presents that skywalking intercepts. + */ +public class ConnectionInstrumentation extends AbstractConnectionInstrumentation { + public static final String ENHANCE_CONNECTION_JDBC2_CLASS = "net.sourceforge.jtds.jdbc.ConnectionJDBC2"; + public static final String ENHANCE_JTDS_CONNECTION_CLASS = "net.sourceforge.jtds.jdbc.JtdsConnection"; + + @Override + protected ClassMatch enhanceClass() { + return MultiClassNameMatch.byMultiClassMatch(ENHANCE_CONNECTION_JDBC2_CLASS, ENHANCE_JTDS_CONNECTION_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mssql/jtds/v1/define/DriverInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mssql/jtds/v1/define/DriverInstrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..f7dbc58f540a21a0587751ac1b4b129070d2fb0f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mssql/jtds/v1/define/DriverInstrumentation.java @@ -0,0 +1,36 @@ +/* + * 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.mssql.jtds.v1.define; + +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation; + +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * {@link DriverInstrumentation} presents that skywalking intercepts {@link net.sourceforge.jtds.jdbc.Driver}. + */ +public class DriverInstrumentation extends AbstractDriverInstrumentation { + private static final String ENHANCE_CLASS = "net.sourceforge.jtds.jdbc.Driver"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000000000000000000000000000000000..a977975ec93810d0c19c08686447d68eac837234 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/mssql-jtds-1.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,18 @@ +# 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. + +mssql-jtds-1.x=org.apache.skywalking.apm.plugin.mssql.jtds.v1.define.DriverInstrumentation +mssql-jtds-1.x=org.apache.skywalking.apm.plugin.mssql.jtds.v1.define.ConnectionInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 6aade3e86b481a0e5114eb76f568ea02df8b06c2..12205a7ce294de7e4b01802ce5a02c6bbbd7fe94 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -104,6 +104,7 @@ httpclient-commons asynchttpclient-2.x-plugin dbcp-2.x-plugin + mssql-jtds-1.x-plugin pom 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 322e839921d9c22489b3da5b771f2e869c48ffe6..f6a28bc4b9f1c12463803b4fc1b68fa326e1ecc6 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -109,3 +109,4 @@ - vertx-core-3.x - xxl-job-2.x - zookeeper-3.4.x +- mssql-jtds-1.x \ No newline at end of file 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 e4ba36726f05696a062f4481c27bff9482d653a2..5234c4c5fd02a968238ad63d970c8e797c670868 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -39,6 +39,7 @@ metrics based on the tracing data. * PostgreSQL Driver 8.x, 9.x, 42.x * Mariadb Driver 2.x, 1.8 * [InfluxDB](https://github.com/influxdata/influxdb-java) 2.5 -> 2.17 + * [Mssql-Jtds](https://github.com/milesibastos/jTDS) 1.x * RPC Frameworks * [Dubbo](https://github.com/alibaba/dubbo) 2.5.4 -> 2.6.0 * [Dubbox](https://github.com/dangdangdotcom/dubbox) 2.8.4 diff --git a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml index aba07b1f0efbf6ae3fa7edca50f7439bb80ebe8a..c7de4d95f4a50ab258a5a5c1c5ea263ee9136e4e 100755 --- a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml +++ b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml @@ -341,6 +341,9 @@ AsyncHttpClient: dbcp: id: 103 languages: Java +mssql-jdbc-driver: + id: 104 + languages: Java # .NET/.NET Core components # [3000, 4000) for C#/.NET only @@ -361,7 +364,7 @@ StackExchange.Redis: languages: C# SqlServer: id: 3006 - languages: C# + languages: C#,Java Npgsql: id: 3007 languages: C# @@ -537,4 +540,5 @@ Component-Server-Mappings: influxdb-java: InfluxDB Predis: Redis PyMysql: Mysql - spring-kafka-consumer: kafka-consumer \ No newline at end of file + spring-kafka-consumer: kafka-consumer + mssql-jdbc-driver: SqlServer \ No newline at end of file diff --git a/test/plugin/scenarios/mssql-jtds-scenario/bin/startup.sh b/test/plugin/scenarios/mssql-jtds-scenario/bin/startup.sh new file mode 100644 index 0000000000000000000000000000000000000000..2737b9eeb992edb735c636f681927d2229bed511 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-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} ${home}/../libs/mssql-jtds-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/mssql-jtds-scenario/config/expectedData.yaml b/test/plugin/scenarios/mssql-jtds-scenario/config/expectedData.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4277047fec056f671320223ec464f5f36cadc8b5 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/config/expectedData.yaml @@ -0,0 +1,106 @@ +# 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: mssql-jtds-scenario + segmentSize: ge 2 + segments: + - segmentId: not null + spans: + - operationName: Mssql/JDBI/PreparedStatement/execute + operationId: eq 0 + parentSpanId: 0 + spanId: 1 + tags: + - {key: db.type, value: sql} + - {key: db.instance, value: tempdb} + - key: db.statement + value: "CREATE TABLE test_007(\nid VARCHAR(1) PRIMARY KEY, \nvalue VARCHAR(1)\ + \ NOT NULL)" + logs: [] + startTime: nq 0 + endTime: nq 0 + isError: false + spanLayer: Database + spanType: Exit + componentId: 104 + peer: mssql-server:1433 + skipAnalysis: 'false' + - operationName: Mssql/JDBI/PreparedStatement/execute + operationId: eq 0 + parentSpanId: 0 + spanId: 2 + tags: + - {key: db.type, value: sql} + - {key: db.instance, value: tempdb} + - {key: db.statement, value: 'INSERT INTO test_007(id, value) VALUES(?,?)'} + logs: [] + startTime: nq 0 + endTime: nq 0 + isError: false + spanLayer: Database + spanType: Exit + componentId: 104 + peer: mssql-server:1433 + skipAnalysis: 'false' + - operationName: Mssql/JDBI/Statement/execute + operationId: eq 0 + parentSpanId: 0 + spanId: 3 + tags: + - {key: db.type, value: sql} + - {key: db.instance, value: tempdb} + - {key: db.statement, value: DROP table test_007} + logs: [] + startTime: nq 0 + endTime: nq 0 + isError: false + spanLayer: Database + spanType: Exit + componentId: 104 + peer: mssql-server:1433 + skipAnalysis: 'false' + - operationName: Mssql/JDBI/Connection/close + operationId: eq 0 + parentSpanId: 0 + spanId: 4 + tags: + - {key: db.type, value: sql} + - {key: db.instance, value: tempdb} + - {key: db.statement, value: ''} + logs: [] + startTime: nq 0 + endTime: nq 0 + isError: false + spanLayer: Database + spanType: Exit + componentId: 104 + peer: mssql-server:1433 + skipAnalysis: 'false' + - operationName: /mssql-jtds-scenario/case/mssql-jtds-scenario + operationId: eq 0 + parentSpanId: -1 + spanId: 0 + startTime: nq 0 + endTime: nq 0 + spanLayer: Http + isError: false + spanType: Entry + componentId: 1 + tags: + - {key: url, value: 'http://localhost:8080/mssql-jtds-scenario/case/mssql-jtds-scenario'} + - {key: http.method, value: GET} + logs: [] + skipAnalysis: 'false' diff --git a/test/plugin/scenarios/mssql-jtds-scenario/configuration.yml b/test/plugin/scenarios/mssql-jtds-scenario/configuration.yml new file mode 100644 index 0000000000000000000000000000000000000000..d97ac50b76a447dfc185cd863a91e8c4a68422de --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/configuration.yml @@ -0,0 +1,32 @@ +# 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/mssql-jtds-scenario/case/mssql-jtds-scenario +healthCheck: http://localhost:8080/mssql-jtds-scenario/case/healthCheck +startScript: ./bin/startup.sh +environment: +depends_on: + - mssql-server +dependencies: + mssql-server: + image: microsoft/mssql-server-linux + hostname: mssql-server + expose: + - "1433" + environment: + - SA_PASSWORD=yourStrong(!)Password + - ACCEPT_EULA=Y \ No newline at end of file diff --git a/test/plugin/scenarios/mssql-jtds-scenario/pom.xml b/test/plugin/scenarios/mssql-jtds-scenario/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..514a6583c51e97a84f0b9907ff9f10e354db62b8 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/pom.xml @@ -0,0 +1,120 @@ + + + + + org.apache.skywalking.apm.testcase + mssql-jtds-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 1.8 + + 1.3.1 + ${test.framework.version} + + 2.1.6.RELEASE + + + skywalking-mssql-jtds-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 + + + + net.sourceforge.jtds + jtds + ${test.framework.version} + + + + + mssql-jtds-scenario + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + maven-compiler-plugin + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/mssql-jtds-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/mssql-jtds-scenario/src/main/assembly/assembly.xml new file mode 100644 index 0000000000000000000000000000000000000000..cd201d769f1535f6a511b50cb2010efb6489ffd0 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/mssql-jtds-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/Application.java b/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/Application.java new file mode 100644 index 0000000000000000000000000000000000000000..988b2f42965c840ac56071c3c52da5e12a11cc69 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/Application.java @@ -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. + * + */ + +package org.apache.skywalking.apm.testcase.mssql; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + try { + SpringApplication.run(Application.class, args); + } catch (Exception e) { + // Never do this + } + } +} diff --git a/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/MssqlConfig.java b/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/MssqlConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..fe08ca8415490691c7d52ea146c6908f0902ab90 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/MssqlConfig.java @@ -0,0 +1,58 @@ +/* + * 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.mssql; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class MssqlConfig { + private static final Logger LOGGER = LogManager.getLogger(MssqlConfig.class); + private static String url; + private static String userName; + private static String password; + + static { + InputStream inputStream = MssqlConfig.class.getClassLoader().getResourceAsStream("jdbc.properties"); + Properties properties = new Properties(); + try { + properties.load(inputStream); + } catch (IOException e) { + LOGGER.error("Failed to load config", e); + } + + url = properties.getProperty("mssql.url"); + userName = properties.getProperty("mssql.username"); + password = properties.getProperty("mssql.password"); + } + + public static String getUrl() { + return url; + } + + public static String getUserName() { + return userName; + } + + public static String getPassword() { + return password; + } +} diff --git a/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/SQLExecutor.java b/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/SQLExecutor.java new file mode 100644 index 0000000000000000000000000000000000000000..32a45af8a5d5acaa1a7cb30ed36a65dbcde5bfce --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/SQLExecutor.java @@ -0,0 +1,88 @@ +/* + * 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.mssql; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; + +public class SQLExecutor implements AutoCloseable { + private Connection connection; + + public SQLExecutor() throws SQLException { + try { + Class.forName("net.sourceforge.jtds.jdbc.Driver"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + connection = DriverManager.getConnection(MssqlConfig.getUrl(), MssqlConfig.getUserName(), MssqlConfig.getPassword()); + } + + public void createTable(String sql) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.execute(); + preparedStatement.close(); + } + + public void insertData(String sql, String id, String value) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.setString(1, id); + preparedStatement.setString(2, value); + preparedStatement.execute(); + preparedStatement.close(); + } + + public void dropTable(String sql) throws SQLException { + executeStatement(sql); + } + + public void createProcedure(String sql) throws SQLException { + executeStatement(sql); + } + + public void dropProcedure(String sql) throws SQLException { + executeStatement(sql); + } + + public void callProcedure(String sql, String id) throws SQLException { + PreparedStatement preparedStatement = connection.prepareCall(sql); + preparedStatement.setString(1, id); + preparedStatement.execute(); + preparedStatement.close(); + } + + public void executeStatement(String sql) throws SQLException { + Statement preparedStatement = connection.createStatement(); + preparedStatement.execute(sql); + preparedStatement.close(); + } + + public void closeConnection() throws SQLException { + if (this.connection != null) { + this.connection.close(); + } + } + + @Override + public void close() throws Exception { + closeConnection(); + } +} diff --git a/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/controller/CaseController.java b/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/controller/CaseController.java new file mode 100644 index 0000000000000000000000000000000000000000..47f9d00fff1c943c29b62527ec04a2dd779cb071 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/src/main/java/org/apache/skywalking/apm/testcase/mssql/controller/CaseController.java @@ -0,0 +1,65 @@ +/* + * 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.mssql.controller; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.skywalking.apm.testcase.mssql.SQLExecutor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/case") +public class CaseController { + + private static final Logger LOGGER = LogManager.getLogger(CaseController.class); + + private static final String SUCCESS = "Success"; + + private static final String CREATE_TABLE_SQL = "CREATE TABLE test_007(\n" + "id VARCHAR(1) PRIMARY KEY, \n" + "value VARCHAR(1) NOT NULL)"; + private static final String INSERT_DATA_SQL = "INSERT INTO test_007(id, value) VALUES(?,?)"; + private static final String QUERY_DATA_SQL = "SELECT id, value FROM test_007 WHERE id=?"; + private static final String DELETE_DATA_SQL = "DELETE FROM test_007 WHERE id=?"; + private static final String DROP_TABLE_SQL = "DROP table test_007"; + + @RequestMapping("/mssql-jtds-scenario") + @ResponseBody + public String testcase() throws Exception { + try (SQLExecutor sqlExecute = new SQLExecutor()) { + sqlExecute.createTable(CREATE_TABLE_SQL); + sqlExecute.insertData(INSERT_DATA_SQL, "1", "1"); + sqlExecute.dropTable(DROP_TABLE_SQL); + } catch (Exception e) { + LOGGER.error("Failed to execute sql.", e); + throw e; + } + return SUCCESS; + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() throws Exception { + try (SQLExecutor sqlExecutor = new SQLExecutor()) { + // ignore + } + return SUCCESS; + } + +} diff --git a/test/plugin/scenarios/mssql-jtds-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/mssql-jtds-scenario/src/main/resources/application.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7bf316a0e895f6542e3dbbec3130ce215f5658b4 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/src/main/resources/application.yaml @@ -0,0 +1,23 @@ +# +# 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 + servlet: + context-path: /mssql-jtds-scenario +logging: + config: classpath:log4j2.xml \ No newline at end of file diff --git a/test/plugin/scenarios/mssql-jtds-scenario/src/main/resources/jdbc.properties b/test/plugin/scenarios/mssql-jtds-scenario/src/main/resources/jdbc.properties new file mode 100644 index 0000000000000000000000000000000000000000..718ac4858008baec722e3c1d6239c8164274e0a0 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/src/main/resources/jdbc.properties @@ -0,0 +1,18 @@ +# 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 +# "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. +mssql.url=jdbc:jtds:sqlserver://mssql-server:1433/tempdb +mssql.username=SA +mssql.password=yourStrong(!)Password diff --git a/test/plugin/scenarios/mssql-jtds-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/mssql-jtds-scenario/src/main/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..9849ed5a8abd116a9000e64cc18f05e583f21c98 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/mssql-jtds-scenario/support-version.list b/test/plugin/scenarios/mssql-jtds-scenario/support-version.list new file mode 100644 index 0000000000000000000000000000000000000000..a313c107fe62002b40a3eb0f2ec2fbbeb46d4618 --- /dev/null +++ b/test/plugin/scenarios/mssql-jtds-scenario/support-version.list @@ -0,0 +1,23 @@ +# 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 +# "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. + +1.2.2 +1.2.4 +1.2.6 +1.2.7 +1.2.8 +1.3.0 +1.3.1 \ No newline at end of file