提交 772b4428 编写于 作者: A ascrutae

fix occur ClassCastException when return generate key

上级 1cf06583
......@@ -27,15 +27,11 @@ import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.util.StringUtil;
/**
* {@link ConnectionServiceMethodInterceptor} create an exit span when the client call the following methods in the class
* that extend {@link java.sql.Connection}.
* 1. close
* 2. rollback
* 3. releaseSavepoint
* 4. commit
* {@link ConnectionServiceMethodInterceptor} create an exit span when the client call the following methods in the
* class that extend {@link java.sql.Connection}. 1. close 2. rollback 3. releaseSavepoint 4. commit
*
* @author zhangxin
*/
public class ConnectionServiceMethodInterceptor implements InstanceMethodsAroundInterceptor {
......@@ -45,13 +41,7 @@ public class ConnectionServiceMethodInterceptor implements InstanceMethodsAround
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
ConnectionInfo connectInfo = (ConnectionInfo)objInst.getSkyWalkingDynamicField();
String remotePeer;
if (!StringUtil.isEmpty(connectInfo.getHosts())) {
remotePeer = connectInfo.getHosts();
} else {
remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort();
}
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Connection/" + method.getName(), remotePeer);
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Connection/" + method.getName(), connectInfo.getDatabasePeer());
Tags.DB_TYPE.set(span, "sql");
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
Tags.DB_STATEMENT.set(span, "");
......
......@@ -23,7 +23,6 @@ import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.tag.Tags;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.util.StringUtil;
/**
* {@link CallableStatementTracing} create an exit span when the client call the method in the class that extend {@link
......@@ -37,13 +36,7 @@ public class CallableStatementTracing {
ConnectionInfo connectInfo, String method, String sql, Executable<R> exec)
throws SQLException {
try {
String remotePeer;
if (!StringUtil.isEmpty(connectInfo.getHosts())) {
remotePeer = connectInfo.getHosts();
} else {
remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort();
}
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/CallableStatement/" + method, remotePeer);
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/CallableStatement/" + method, connectInfo.getDatabasePeer());
Tags.DB_TYPE.set(span, "sql");
SpanLayer.asDB(span);
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
......
......@@ -31,22 +31,12 @@ public class ConnectionInfo {
* DB type, such as mysql, oracle, h2.
*/
private final String dbType;
/**
* Database host name.
*/
private String host;
/**
* Database port.
*/
private int port;
/**
* Operation database name.
*/
private final String databaseName;
/**
* Database hosts.
*/
private String hosts;
private String databasePeer;
/**
* Component
......@@ -55,15 +45,14 @@ public class ConnectionInfo {
public ConnectionInfo(OfficialComponent component, String dbType, String host, int port, String databaseName) {
this.dbType = dbType;
this.host = host;
this.port = port;
this.databasePeer = host + ":" + port;
this.databaseName = databaseName;
this.component = component;
}
public ConnectionInfo(OfficialComponent component, String dbType, String hosts, String databaseName) {
this.dbType = dbType;
this.hosts = hosts;
this.databasePeer = hosts;
this.databaseName = databaseName;
this.component = component;
}
......@@ -72,20 +61,12 @@ public class ConnectionInfo {
return dbType;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public String getDatabaseName() {
return databaseName;
}
public String getHosts() {
return hosts;
public String getDatabasePeer() {
return databasePeer;
}
public OfficialComponent getComponent() {
......
......@@ -23,7 +23,6 @@ import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.tag.Tags;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.util.StringUtil;
/**
* {@link PreparedStatementTracing} create an exit span when the client call the method in the class that extend {@link
......@@ -37,14 +36,7 @@ public class PreparedStatementTracing {
ConnectionInfo connectInfo, String method, String sql, Executable<R> exec)
throws SQLException {
try {
String remotePeer;
if (!StringUtil.isEmpty(connectInfo.getHosts())) {
remotePeer = connectInfo.getHosts();
} else {
remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort();
}
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/PreparedStatement/" + method, remotePeer);
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/PreparedStatement/" + method, connectInfo.getDatabasePeer());
Tags.DB_TYPE.set(span, "sql");
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
Tags.DB_STATEMENT.set(span, sql);
......
......@@ -23,7 +23,6 @@ import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.tag.Tags;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.util.StringUtil;
/**
* {@link PreparedStatementTracing} create an exit span when the client call the method in the class that extend {@link
......@@ -36,14 +35,7 @@ public class StatementTracing {
ConnectionInfo connectInfo, String method, String sql, Executable<R> exec)
throws SQLException {
try {
String remotePeer;
if (!StringUtil.isEmpty(connectInfo.getHosts())) {
remotePeer = connectInfo.getHosts();
} else {
remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort();
}
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Statement/" + method, remotePeer);
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Statement/" + method, connectInfo.getDatabasePeer());
Tags.DB_TYPE.set(span, "sql");
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
Tags.DB_STATEMENT.set(span, sql);
......
......@@ -24,7 +24,6 @@ import org.skywalking.apm.agent.core.context.tag.Tags;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import org.skywalking.apm.util.StringUtil;
public class ConnectionTracing {
......@@ -32,13 +31,7 @@ public class ConnectionTracing {
ConnectionInfo connectInfo, String method, String sql, Executable<R> exec)
throws SQLException {
try {
String remotePeer;
if (!StringUtil.isEmpty(connectInfo.getHosts())) {
remotePeer = connectInfo.getHosts();
} else {
remotePeer = connectInfo.getHost() + ":" + connectInfo.getPort();
}
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Connection/" + method, remotePeer);
AbstractSpan span = ContextManager.createExitSpan(connectInfo.getDBType() + "/JDBI/Connection/" + method, connectInfo.getDatabasePeer());
Tags.DB_TYPE.set(span, "sql");
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
Tags.DB_STATEMENT.set(span, sql);
......
......@@ -30,8 +30,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:mysql//primaryhost/test");
assertThat(connectionInfo.getDBType(), is("Mysql"));
assertThat(connectionInfo.getDatabaseName(), is("test"));
assertThat(connectionInfo.getHost(), is("primaryhost"));
assertThat(connectionInfo.getPort(), is(3306));
assertThat(connectionInfo.getDatabasePeer(), is("primaryhost:3306"));
}
@Test
......@@ -39,8 +38,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:mysql//primaryhost:3307/test?profileSQL=true");
assertThat(connectionInfo.getDBType(), is("Mysql"));
assertThat(connectionInfo.getDatabaseName(), is("test"));
assertThat(connectionInfo.getHost(), is("primaryhost"));
assertThat(connectionInfo.getPort(), is(3307));
assertThat(connectionInfo.getDatabasePeer(), is("primaryhost:3307"));
}
@Test
......@@ -48,7 +46,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:mysql//primaryhost:3307,secondaryhost1,secondaryhost2/test?profileSQL=true");
assertThat(connectionInfo.getDBType(), is("Mysql"));
assertThat(connectionInfo.getDatabaseName(), is("test"));
assertThat(connectionInfo.getHosts(), is("primaryhost:3307,secondaryhost1:3306,secondaryhost2:3306,"));
assertThat(connectionInfo.getDatabasePeer(), is("primaryhost:3307,secondaryhost1:3306,secondaryhost2:3306,"));
}
@Test
......@@ -56,7 +54,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:mysql:replication://master,slave1,slave2,slave3/test");
assertThat(connectionInfo.getDBType(), is("Mysql"));
assertThat(connectionInfo.getDatabaseName(), is("test"));
assertThat(connectionInfo.getHosts(), is("master:3306,slave1:3306,slave2:3306,slave3:3306,"));
assertThat(connectionInfo.getDatabasePeer(), is("master:3306,slave1:3306,slave2:3306,slave3:3306,"));
}
@Test
......@@ -64,8 +62,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:oracle:thin:@localhost:orcl");
assertThat(connectionInfo.getDBType(), is("Oracle"));
assertThat(connectionInfo.getDatabaseName(), is("orcl"));
assertThat(connectionInfo.getHost(), is("localhost"));
assertThat(connectionInfo.getPort(), is(1521));
assertThat(connectionInfo.getDatabasePeer(), is("localhost:1521"));
}
@Test
......@@ -73,8 +70,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:oracle:thin:@localhost:1522:orcl");
assertThat(connectionInfo.getDBType(), is("Oracle"));
assertThat(connectionInfo.getDatabaseName(), is("orcl"));
assertThat(connectionInfo.getHost(), is("localhost"));
assertThat(connectionInfo.getPort(), is(1522));
assertThat(connectionInfo.getDatabasePeer(), is("localhost:1522"));
}
@Test
......@@ -82,8 +78,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:oracle:thin:scott/tiger@myhost:1521:orcl");
assertThat(connectionInfo.getDBType(), is("Oracle"));
assertThat(connectionInfo.getDatabaseName(), is("orcl"));
assertThat(connectionInfo.getHost(), is("myhost"));
assertThat(connectionInfo.getPort(), is(1521));
assertThat(connectionInfo.getDatabasePeer(), is("myhost:1521"));
}
@Test
......@@ -91,8 +86,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:h2:file:/data/sample");
assertThat(connectionInfo.getDBType(), is("H2"));
assertThat(connectionInfo.getDatabaseName(), is("/data/sample"));
assertThat(connectionInfo.getHost(), is("localhost"));
assertThat(connectionInfo.getPort(), is(-1));
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
}
@Test
......@@ -100,8 +94,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:h2:file:C:/data/sample");
assertThat(connectionInfo.getDBType(), is("H2"));
assertThat(connectionInfo.getDatabaseName(), is("C:/data/sample"));
assertThat(connectionInfo.getHost(), is("localhost"));
assertThat(connectionInfo.getPort(), is(-1));
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
}
@Test
......@@ -109,8 +102,7 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:h2:mem:test_mem");
assertThat(connectionInfo.getDBType(), is("H2"));
assertThat(connectionInfo.getDatabaseName(), is("test_mem"));
assertThat(connectionInfo.getHost(), is("localhost"));
assertThat(connectionInfo.getPort(), is(-1));
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
}
@Test
......@@ -118,7 +110,6 @@ public class URLParserTest {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:h2:tcp://localhost:8084/~/sample");
assertThat(connectionInfo.getDBType(), is("H2"));
assertThat(connectionInfo.getDatabaseName(), is("sample"));
assertThat(connectionInfo.getHost(), is("localhost"));
assertThat(connectionInfo.getPort(), is(8084));
assertThat(connectionInfo.getDatabasePeer(), is("localhost:8084"));
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.mysql.define.StatementEnhanceInfos;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link CreateStatementInterceptor} intercepts the {@link com.mysql.jdbc.ConnectionImpl#createStatement()} method in
* the {@link com.mysql.jdbc.ConnectionImpl} class.
*
* @author zhangxin
*/
public class CreateCallableStatementInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
if (ret instanceof EnhancedInstance) {
((EnhancedInstance)ret).setSkyWalkingDynamicField(new StatementEnhanceInfos((ConnectionInfo)objInst.getSkyWalkingDynamicField(), (String)allArguments[0], "CallableStatement"));
}
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.mysql.define.StatementEnhanceInfos;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link CreateStatementInterceptor} intercepts the {@link com.mysql.jdbc.ConnectionImpl#prepareStatement()} method in
* the {@link com.mysql.jdbc.ConnectionImpl} class.
*
* @author zhangxin
*/
public class CreatePreparedStatementInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
if (ret instanceof EnhancedInstance) {
((EnhancedInstance)ret).setSkyWalkingDynamicField(new StatementEnhanceInfos((ConnectionInfo)objInst.getSkyWalkingDynamicField(), (String)allArguments[0], "PreparedStatement"));
}
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.mysql.define.StatementEnhanceInfos;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link CreateStatementInterceptor} intercepts the {@link com.mysql.jdbc.ConnectionImpl#createStatement()} method in
* the {@link com.mysql.jdbc.ConnectionImpl} class.
*
* @author zhangxin
*/
public class CreateStatementInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
if (ret instanceof EnhancedInstance) {
((EnhancedInstance)ret).setSkyWalkingDynamicField(new StatementEnhanceInfos((ConnectionInfo)objInst.getSkyWalkingDynamicField(), "", "CallableStatement"));
}
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql;
import java.lang.reflect.Method;
import org.skywalking.apm.agent.core.context.ContextManager;
import org.skywalking.apm.agent.core.context.tag.Tags;
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.skywalking.apm.plugin.jdbc.mysql.define.StatementEnhanceInfos;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link StatementExecuteMethodsInterceptor} create the exit span when the client call the interceptor methods.
*
* @author zhangxin
*/
public class StatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos)objInst.getSkyWalkingDynamicField();
ConnectionInfo connectInfo = cacheObject.getConnectionInfo();
if (connectInfo != null) {
AbstractSpan span = ContextManager.createExitSpan(buildOperationName(connectInfo, method.getName(), cacheObject.getStatementName()), connectInfo.getDatabasePeer());
Tags.DB_TYPE.set(span, "sql");
Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
Tags.DB_STATEMENT.set(span, cacheObject.getSql());
span.setComponent(connectInfo.getComponent());
SpanLayer.asDB(span);
}
}
@Override
public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes,
Object ret) throws Throwable {
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos)objInst.getSkyWalkingDynamicField();
if (cacheObject.getConnectionInfo() != null) {
ContextManager.stopSpan();
}
return ret;
}
@Override public final void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
StatementEnhanceInfos cacheObject = (StatementEnhanceInfos)objInst.getSkyWalkingDynamicField();
if (cacheObject.getConnectionInfo() != null) {
ContextManager.activeSpan().errorOccurred().log(t);
}
}
private String buildOperationName(ConnectionInfo connectionInfo, String methodName, String statementName) {
return connectionInfo.getDBType() + "/JDBI/" + statementName + "/" + methodName;
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import static net.bytebuddy.matcher.ElementMatchers.named;
/**
* {@link AbstractPreparedStatementInstrumentation} define that the mysql-2.x plugin intercepts the following methods in
* the {@link com.mysql.jdbc.JDBC42PreparedStatement} and {@link com.mysql.jdbc.PreparedStatement} class.
* 1. execute <br/>
* 2. executeQuery <br/>
* 3. executeUpdate <br/>
* 4. executeLargeUpdate <br/>
* 5. addBatch <br/>
*
* @author zhangxin
*/
public abstract class AbstractPreparedStatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String SERVICE_METHOD_INTERCEPTOR = "org.skywalking.apm.plugin.jdbc.mysql.StatementExecuteMethodsInterceptor";
@Override protected final ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("execute")
.or(named("executeQuery"))
.or(named("executeUpdate"))
.or(named("executeLargeUpdate"))
.or(named("addBatch"));
}
@Override public String getMethodsInterceptor() {
return SERVICE_METHOD_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMath;
/**
* {@link CallableInstrumentation} define that the mysql-2.x plugin intercepts the following methods in the {@link
* com.mysql.jdbc.CallableStatement} by {@link org.skywalking.apm.plugin.jdbc.mysql.CallableStatementInterceptor}. 1.
* execute <br/> 2. executeQuery <br/> 3. executeUpdate <br/>
*
* @author zhangxin
*/
public class CallableInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ENHANCE_CLASS = "com.mysql.jdbc.CallableStatement";
private static final String SERVICE_METHOD_INTERCEPTOR = "org.skywalking.apm.plugin.jdbc.mysql.StatementExecuteMethodsInterceptor";
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("execute")
.or(named("executeQuery"))
.or(named("executeUpdate"));
}
@Override public String getMethodsInterceptor() {
return SERVICE_METHOD_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override protected ClassMatch enhanceClass() {
return byMultiClassMath(ENHANCE_CLASS, "com.mysql.jdbc.cj.CallableStatement");
}
}
......@@ -27,21 +27,18 @@ import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CLOSE_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.COMMIT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.CREATE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_CALL_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.define.Constants.PREPARE_STATEMENT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.RELEASE_SAVE_POINT_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.ROLLBACK_METHOD_NAME;
import static org.skywalking.apm.plugin.jdbc.define.Constants.SERVICE_METHOD_INTERCEPT_CLASS;
import static org.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMath;
/**
* {@link ConnectionInstrumentation} intercept the following methods that the class which extend {@link
* {@link ConnectionInstrumentation} intercepts the following methods that the class which extend {@link
* com.mysql.jdbc.ConnectionImpl}. <br/>
*
* 1. Enhance <code>prepareStatement</code> by <code>org.skywalking.apm.plugin.jdbc.define.JDBCPrepareStatementInterceptor</code>
......@@ -67,7 +64,7 @@ public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePlugin
}
@Override public String getMethodsInterceptor() {
return PREPARE_STATEMENT_INTERCEPT_CLASS;
return "org.skywalking.apm.plugin.jdbc.mysql.CreatePreparedStatementInterceptor";
}
@Override public boolean isOverrideArgs() {
......@@ -80,7 +77,7 @@ public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePlugin
}
@Override public String getMethodsInterceptor() {
return PREPARE_CALL_INTERCEPT_CLASS;
return "org.skywalking.apm.plugin.jdbc.mysql.CreateCallableStatementInterceptor";
}
@Override public boolean isOverrideArgs() {
......@@ -93,7 +90,7 @@ public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePlugin
}
@Override public String getMethodsInterceptor() {
return CREATE_STATEMENT_INTERCEPT_CLASS;
return "org.skywalking.apm.plugin.jdbc.mysql.CreateStatementInterceptor";
}
@Override public boolean isOverrideArgs() {
......@@ -118,6 +115,6 @@ public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePlugin
}
@Override protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
return byMultiClassMath(ENHANCE_CLASS, "com.mysql.cj.jdbc.ConnectionImpl");
}
}
......@@ -21,7 +21,7 @@ package org.skywalking.apm.plugin.jdbc.mysql.define;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
import static org.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMath;
/**
* {@link DriverInstrumentation} presents that skywalking intercepts {@link com.mysql.jdbc.Driver}.
......@@ -31,6 +31,6 @@ import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
public class DriverInstrumentation extends AbstractDriverInstrumentation {
@Override
protected ClassMatch enhanceClass() {
return byName("com.mysql.jdbc.Driver");
return byMultiClassMath("com.mysql.jdbc.Driver", "com.mysql.cj.jdbc.Driver");
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql.define;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
/**
* {@link JDBC42PreparedStatementInstrumentation} intercepts {@link com.mysql.jdbc.JDBC42PreparedStatement} class.
*
* @author zhangxin
*/
public class JDBC42PreparedStatementInstrumentation extends AbstractPreparedStatementInstrumentation {
private static final String ENHANCE_CLASS = "com.mysql.jdbc.JDBC42PreparedStatement";
@Override protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql.define;
import java.util.Arrays;
import java.util.List;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.skywalking.apm.agent.core.plugin.match.IndirectMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
/**
* Match multiple classes name with an explicit class name.
*
* @author zhangxin
*/
public class MultiClassNameMatch implements IndirectMatch {
private List<String> matchClassNames;
private MultiClassNameMatch(String[] classNames) {
if (classNames == null || classNames.length == 0) {
throw new IllegalArgumentException("match class names is null");
}
this.matchClassNames = Arrays.asList(classNames);
}
@Override
public ElementMatcher.Junction buildJunction() {
ElementMatcher.Junction junction = null;
for (String name : matchClassNames) {
if (junction == null) {
junction = named(name);
} else {
junction = junction.or(named(name));
}
}
return junction;
}
@Override
public boolean isMatch(TypeDescription typeDescription) {
return matchClassNames.contains(typeDescription.getTypeName());
}
public static ClassMatch byMultiClassMath(String... classNames) {
return new MultiClassNameMatch(classNames);
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql.define;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static org.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMath;
/**
* {@link JDBC42PreparedStatementInstrumentation} intercepts {@link com.mysql.jdbc.PreparedStatement} class.
*
* @author zhangxin
*/
public class PreparedStatementInstrumentation extends AbstractPreparedStatementInstrumentation {
private static final String ENHANCE_CLASS = "com.mysql.jdbc.PreparedStatement";
@Override protected ClassMatch enhanceClass() {
return byMultiClassMath(ENHANCE_CLASS, "com.mysql.cj.jdbc.PreparedStatement");
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql.define;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
/**
* {@link StatementEnhanceInfos} contain the {@link org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo} and
* <code>sql</code> for trace mysql.
*
* @author zhangxin
*/
public class StatementEnhanceInfos {
private ConnectionInfo connectionInfo;
private String statementName;
private String sql;
public StatementEnhanceInfos(ConnectionInfo connectionInfo, String sql, String statementName) {
this.connectionInfo = connectionInfo;
this.sql = sql;
this.statementName = statementName;
}
public ConnectionInfo getConnectionInfo() {
return connectionInfo;
}
public String getSql() {
return sql;
}
public String getStatementName() {
return statementName;
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql.define;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMath;
/**
* {@link JDBC42PreparedStatementInstrumentation} intercepts the following methods in the {@link
* com.mysql.jdbc.JDBC42PreparedStatement} class.
* 1. execute <br/>
* 2. executeQuery <br/>
* 3. executeUpdate <br/>
* 4. executeLargeUpdate <br/>
* 5. addBatch <br/>
* 6. executeBatchInternal <br/>
* 7. executeUpdateInternal <br/>
* 8. executeQuery <br/>
* 9. executeBatch <br/>
*
* @author zhangxin
*/
public class StatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
private static final String ENHANCE_CLASS = "com.mysql.jdbc.StatementImpl";
private static final String SERVICE_METHOD_INTERCEPTOR = "org.skywalking.apm.plugin.jdbc.mysql.StatementExecuteMethodsInterceptor";
@Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
return new ConstructorInterceptPoint[0];
}
@Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("execute")
.or(named("executeQuery"))
.or(named("executeUpdate"))
.or(named("executeLargeUpdate"))
.or(named("addBatch"))
.or(named("executeBatchInternal"))
.or(named("executeUpdateInternal"))
.or(named("executeQuery"))
.or(named("executeBatch"));
}
@Override public String getMethodsInterceptor() {
return SERVICE_METHOD_INTERCEPTOR;
}
@Override public boolean isOverrideArgs() {
return false;
}
}
};
}
@Override protected ClassMatch enhanceClass() {
return byMultiClassMath(ENHANCE_CLASS, "com.mysql.cj.jdbc.StatementImpl");
}
}
mysql=org.skywalking.apm.plugin.jdbc.mysql.define.DriverInstrumentation
mysql=org.skywalking.apm.plugin.jdbc.mysql.define.ConnectionInstrumentation
mysql=org.skywalking.apm.plugin.jdbc.mysql.define.CallableInstrumentation
mysql=org.skywalking.apm.plugin.jdbc.mysql.define.PreparedStatementInstrumentation
mysql=org.skywalking.apm.plugin.jdbc.mysql.define.JDBC42PreparedStatementInstrumentation
mysql=org.skywalking.apm.plugin.jdbc.mysql.define.StatementInstrumentation
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(MockitoJUnitRunner.class)
public class CreateCallableStatementInterceptorTest {
private CreateCallableStatementInterceptor interceptor;
@Mock
private EnhancedInstance ret;
@Mock
private EnhancedInstance objectInstance;
@Mock
private ConnectionInfo connectionInfo;
@Before
public void setUp() {
interceptor = new CreateCallableStatementInterceptor();
when(objectInstance.getSkyWalkingDynamicField()).thenReturn(connectionInfo);
}
@Test
public void testResultIsEnhanceInstance() throws Throwable {
interceptor.afterMethod(objectInstance, null, new Object[] {"SELECT * FROM test"}, null, ret);
verify(ret, times(1)).setSkyWalkingDynamicField(Matchers.any());
}
@Test
public void testResultIsNotEnhanceInstance() throws Throwable {
interceptor.afterMethod(objectInstance, null, new Object[] {"SELECT * FROM test"}, null, new Object());
verify(ret, times(0)).setSkyWalkingDynamicField(Matchers.any());
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(MockitoJUnitRunner.class)
public class CreatePreparedStatementInterceptorTest {
private CreatePreparedStatementInterceptor interceptor;
@Mock
private EnhancedInstance ret;
@Mock
private EnhancedInstance objectInstance;
@Mock
private ConnectionInfo connectionInfo;
@Before
public void setUp() {
interceptor = new CreatePreparedStatementInterceptor();
when(objectInstance.getSkyWalkingDynamicField()).thenReturn(connectionInfo);
}
@Test
public void testResultIsEnhanceInstance() throws Throwable {
interceptor.afterMethod(objectInstance, null, new Object[] {"SELECT * FROM test"}, null, ret);
verify(ret, times(1)).setSkyWalkingDynamicField(Matchers.any());
}
@Test
public void testResultIsNotEnhanceInstance() throws Throwable {
interceptor.afterMethod(objectInstance, null, new Object[] {"SELECT * FROM test"}, null, new Object());
verify(ret, times(0)).setSkyWalkingDynamicField(Matchers.any());
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(MockitoJUnitRunner.class)
public class CreateStatementInterceptorTest {
private CreateStatementInterceptor interceptor;
@Mock
private EnhancedInstance ret;
@Mock
private EnhancedInstance objectInstance;
@Mock
private ConnectionInfo connectionInfo;
@Before
public void setUp() {
interceptor = new CreateStatementInterceptor();
when(objectInstance.getSkyWalkingDynamicField()).thenReturn(connectionInfo);
}
@Test
public void testResultIsEnhanceInstance() throws Throwable {
interceptor.afterMethod(objectInstance, null, new Object[] {"SELECT * FROM test"}, null, ret);
verify(ret, times(1)).setSkyWalkingDynamicField(Matchers.any());
}
@Test
public void testResultIsNotEnhanceInstance() throws Throwable {
interceptor.afterMethod(objectInstance, null, new Object[] {"SELECT * FROM test"}, null, new Object());
verify(ret, times(0)).setSkyWalkingDynamicField(Matchers.any());
}
}
/*
* Copyright 2017, OpenSkywalking Organization All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Project repository: https://github.com/OpenSkywalking/skywalking
*/
package org.skywalking.apm.plugin.jdbc.mysql;
import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.skywalking.apm.agent.test.helper.SegmentHelper;
import org.skywalking.apm.agent.test.tools.AgentServiceRule;
import org.skywalking.apm.agent.test.tools.SegmentStorage;
import org.skywalking.apm.agent.test.tools.SegmentStoragePoint;
import org.skywalking.apm.agent.test.tools.SpanAssert;
import org.skywalking.apm.agent.test.tools.TracingSegmentRunner;
import org.skywalking.apm.network.trace.component.ComponentsDefine;
import org.skywalking.apm.plugin.jdbc.mysql.define.StatementEnhanceInfos;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
public class StatementExecuteMethodsInterceptorTest {
@SegmentStoragePoint
private SegmentStorage segmentStorage;
@Rule
public AgentServiceRule serviceRule = new AgentServiceRule();
private StatementExecuteMethodsInterceptor serviceMethodInterceptor;
@Mock
private ConnectionInfo connectionInfo;
@Mock
private EnhancedInstance objectInstance;
@Mock
private Method method;
private StatementEnhanceInfos enhanceRequireCacheObject;
@Before
public void setUp() {
serviceMethodInterceptor = new StatementExecuteMethodsInterceptor();
enhanceRequireCacheObject = new StatementEnhanceInfos(connectionInfo, "SELECT * FROM test", "CallableStatement");
when(objectInstance.getSkyWalkingDynamicField()).thenReturn(enhanceRequireCacheObject);
when(method.getName()).thenReturn("executeQuery");
when(connectionInfo.getComponent()).thenReturn(ComponentsDefine.H2);
when(connectionInfo.getDBType()).thenReturn("H2");
when(connectionInfo.getDatabaseName()).thenReturn("test");
when(connectionInfo.getDatabasePeer()).thenReturn("localhost:3307");
}
@Test
public void testCreateDatabaseSpan() throws Throwable {
serviceMethodInterceptor.beforeMethod(objectInstance, method, null, null, null);
serviceMethodInterceptor.afterMethod(objectInstance, method, null, null, null);
assertThat(segmentStorage.getTraceSegments().size(), is(1));
TraceSegment segment = segmentStorage.getTraceSegments().get(0);
assertThat(SegmentHelper.getSpans(segment).size(), is(1));
AbstractTracingSpan span = SegmentHelper.getSpans(segment).get(0);
SpanAssert.assertLayer(span, SpanLayer.DB);
assertThat(span.getOperationName(), is("H2/JDBI/CallableStatement/"));
SpanAssert.assertTag(span, 0, "sql");
SpanAssert.assertTag(span, 1, "test");
SpanAssert.assertTag(span, 2, "SELECT * FROM test");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册