提交 5ba4f647 编写于 作者: X Xin,Zhang 提交者: wu-sheng

Fix #1296: Fix StringIndexOutOfBoundsException when mysql jdbc url without databaseName (#1314)

上级 a7d1dad0
......@@ -16,7 +16,6 @@
*
*/
package org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser;
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
......@@ -40,9 +39,32 @@ public class MysqlURLParser extends AbstractURLParser {
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("/");
......@@ -71,9 +93,9 @@ public class MysqlURLParser extends AbstractURLParser {
} else {
String[] hostAndPort = hostSegment[0].split(":");
if (hostAndPort.length != 1) {
return new ConnectionInfo(ComponentsDefine.MYSQL_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]), fetchDatabaseNameFromURL());
return new ConnectionInfo(ComponentsDefine.MYSQL_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]), fetchDatabaseNameFromURL(location.endIndex()));
} else {
return new ConnectionInfo(ComponentsDefine.MYSQL_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL());
return new ConnectionInfo(ComponentsDefine.MYSQL_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL(location.endIndex()));
}
}
}
......
......@@ -16,7 +16,6 @@
*
*/
package org.apache.skywalking.apm.plugin.jdbc.trace;
import org.apache.skywalking.apm.network.trace.component.OfficialComponent;
......@@ -35,7 +34,7 @@ public class ConnectionInfo {
/**
* Operation database name.
*/
private final String databaseName;
private String databaseName;
private String databasePeer;
......@@ -74,4 +73,7 @@ public class ConnectionInfo {
return component;
}
public void setDatabaseName(String dataBaseName) {
this.databaseName = dataBaseName;
}
}
......@@ -34,6 +34,14 @@ public class URLParserTest {
assertThat(connectionInfo.getDatabasePeer(), is("primaryhost:3306"));
}
@Test
public void testParseMysqlJDBCURLWithoutDB() {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:mysql//primaryhost?profileSQL=true");
assertThat(connectionInfo.getDBType(), is("Mysql"));
assertThat(connectionInfo.getDatabaseName(), is(""));
assertThat(connectionInfo.getDatabasePeer(), is("primaryhost:3306"));
}
@Test
public void testParseMysqlJDBCURLWithHostAndPort() {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:mysql//primaryhost:3307/test?profileSQL=true");
......
/*
* 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.mysql;
import java.lang.reflect.Method;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
public class SetCatalogInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) throws Throwable {
Object dynamicField = objInst.getSkyWalkingDynamicField();
if (dynamicField instanceof ConnectionInfo) {
((ConnectionInfo)dynamicField).setDatabaseName(String.valueOf(allArguments[0]));
}
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
return ret;
}
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
Class<?>[] argumentsTypes, Throwable t) {
}
}
......@@ -97,6 +97,19 @@ public abstract class ConnectionInstrumentation extends ClassInstanceMethodsEnha
return Constants.SERVICE_METHOD_INTERCEPT_CLASS;
}
@Override public boolean isOverrideArgs() {
return false;
}
},
new InstanceMethodsInterceptPoint() {
@Override public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("setCatalog");
}
@Override public String getMethodsInterceptor() {
return "org.apache.skywalking.apm.plugin.jdbc.mysql.SetCatalogInterceptor";
}
@Override public boolean isOverrideArgs() {
return false;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册