Add pool metrics support for Derby/Sybase/SQLite/DB2/OceanBase jdbc URL format in URLParser (#687)
This commit is contained in:
parent
1e5463c3cc
commit
7dd7914765
|
|
@ -10,6 +10,7 @@ Release Notes.
|
|||
* Support for C3P0 connection pool tracing.
|
||||
* Use a daemon thread to flush logs.
|
||||
* Fix typos in `URLParser`.
|
||||
* Add support for `Derby`/`Sybase`/`SQLite`/`DB2`/`OceanBase` jdbc url format in `URLParser`.
|
||||
|
||||
All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/213?closed=1)
|
||||
|
||||
|
|
|
|||
|
|
@ -247,4 +247,15 @@ public class ComponentsDefine {
|
|||
|
||||
public static final OfficialComponent C3P0 = new OfficialComponent(152, "c3p0");
|
||||
|
||||
public static final OfficialComponent DERBY_JDBC_DRIVER = new OfficialComponent(153, "Derby-jdbc-driver");
|
||||
|
||||
public static final OfficialComponent SQLITE_JDBC_DRIVER = new OfficialComponent(154, "Sqlite-jdbc-driver");
|
||||
|
||||
public static final OfficialComponent DB2_JDBC_DRIVER = new OfficialComponent(155, "Db2-jdbc-driver");
|
||||
|
||||
public static final OfficialComponent SYBASE_JDBC_DRIVER = new OfficialComponent(156, "Sybase-jdbc-driver");
|
||||
|
||||
public static final OfficialComponent OCEANBASE_JDBC_DRIVER = new OfficialComponent(157, "OceanBase-jdbc-driver");
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* 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.network.trace.component.ComponentsDefine;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
|
||||
public class Db2URLParser extends AbstractURLParser {
|
||||
private static final String DEFAULT_HOST = "localhost";
|
||||
private static final int DEFAULT_PORT = 50000;
|
||||
private static final String DB_TYPE = "DB2";
|
||||
private static final String JDBC_PREFIX = "jdbc:db2:";
|
||||
|
||||
public Db2URLParser(String url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URLLocation fetchDatabaseHostsIndexRange() {
|
||||
int hostLabelStartIndex = url.indexOf("//");
|
||||
if (hostLabelStartIndex == -1) {
|
||||
return null;
|
||||
}
|
||||
int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
|
||||
int hostLabelEndIndexWithParameter = url.indexOf(":", hostLabelEndIndex + 1);
|
||||
if (hostLabelEndIndex == -1) {
|
||||
hostLabelEndIndex = hostLabelEndIndexWithParameter;
|
||||
}
|
||||
if (hostLabelEndIndexWithParameter < hostLabelEndIndex && hostLabelEndIndexWithParameter != -1) {
|
||||
hostLabelEndIndex = hostLabelEndIndexWithParameter;
|
||||
}
|
||||
if (hostLabelEndIndex == -1) {
|
||||
hostLabelEndIndex = url.length();
|
||||
}
|
||||
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);
|
||||
int parameterStartTag = url.indexOf(":", startSize);
|
||||
if (parameterStartTag < databaseStartTag && parameterStartTag != -1) {
|
||||
return null;
|
||||
}
|
||||
if (databaseStartTag == -1) {
|
||||
databaseStartTag = startSize - 1;
|
||||
}
|
||||
int databaseEndTag = url.indexOf(":", startSize);
|
||||
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() {
|
||||
URLLocation location = fetchDatabaseHostsIndexRange();
|
||||
if (location == null) {
|
||||
return new ConnectionInfo(
|
||||
ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, DEFAULT_HOST, DEFAULT_PORT,
|
||||
fetchDatabaseNameFromURL(JDBC_PREFIX.length())
|
||||
);
|
||||
}
|
||||
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(
|
||||
ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, sb.substring(0, sb.length() - 1),
|
||||
fetchDatabaseNameFromURL()
|
||||
);
|
||||
} else {
|
||||
String[] hostAndPort = hostSegment[0].split(":");
|
||||
if (hostAndPort.length != 1) {
|
||||
return new ConnectionInfo(
|
||||
ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]),
|
||||
fetchDatabaseNameFromURL(location
|
||||
.endIndex())
|
||||
);
|
||||
} else {
|
||||
return new ConnectionInfo(
|
||||
ComponentsDefine.DB2_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT,
|
||||
fetchDatabaseNameFromURL(location
|
||||
.endIndex())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* 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.network.trace.component.ComponentsDefine;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
|
||||
public class DerbyURLParser extends AbstractURLParser {
|
||||
|
||||
private static final String DEFAULT_HOST = "localhost";
|
||||
private static final int DEFAULT_PORT = 1527;
|
||||
private static final String DB_TYPE = "Derby";
|
||||
private static final String DERBY_JDBC_URL_PREFIX = "jdbc:derby";
|
||||
/**
|
||||
* Flag that running with directory mode.
|
||||
*/
|
||||
private static final String DIRECTORY_MODE_FLAG = "derby:directory";
|
||||
/**
|
||||
* Flag that running with memory mode.
|
||||
*/
|
||||
private static final String MEMORY_MODE_FLAG = "derby:memory";
|
||||
/**
|
||||
* Flag that running with classpath mode.
|
||||
*/
|
||||
private static final String CLASSPATH_MODE_FLAG = "derby:classpath";
|
||||
/**
|
||||
* Flag that running with jar mode.
|
||||
*/
|
||||
private static final String JAR_MODE_FLAG = "derby:jar";
|
||||
|
||||
public DerbyURLParser(String url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch range index that the database name from connection url if Derby database running in client/server
|
||||
* environment. eg: jdbc:derby://host[:port]/[databaseName][;attribute=value]*
|
||||
*
|
||||
* @return range index that the database name.
|
||||
*/
|
||||
@Override
|
||||
protected URLLocation fetchDatabaseHostsIndexRange() {
|
||||
int hostLabelStartIndex = url.indexOf("//");
|
||||
int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
|
||||
return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URLLocation fetchDatabaseNameIndexRange() {
|
||||
int databaseEndTag = url.indexOf(";");
|
||||
if (databaseEndTag == -1) {
|
||||
databaseEndTag = url.length();
|
||||
}
|
||||
int databaseStartTag = url.lastIndexOf("\\");
|
||||
if (databaseStartTag == -1) {
|
||||
databaseStartTag = url.lastIndexOf("/");
|
||||
}
|
||||
if (url.indexOf(":", databaseStartTag) != -1) {
|
||||
databaseStartTag = url.indexOf(":", databaseStartTag);
|
||||
}
|
||||
return new URLLocation(databaseStartTag + 1, databaseEndTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionInfo parse() {
|
||||
int[] databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(DIRECTORY_MODE_FLAG);
|
||||
if (databaseNameRangeIndex != null) {
|
||||
return defaultConnection(databaseNameRangeIndex);
|
||||
}
|
||||
databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(MEMORY_MODE_FLAG);
|
||||
if (databaseNameRangeIndex != null) {
|
||||
return defaultConnection(databaseNameRangeIndex);
|
||||
}
|
||||
databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(CLASSPATH_MODE_FLAG);
|
||||
if (databaseNameRangeIndex != null) {
|
||||
return defaultConnection(databaseNameRangeIndex);
|
||||
}
|
||||
databaseNameRangeIndex = fetchDatabaseNameRangeIndexForSubProtocol(JAR_MODE_FLAG);
|
||||
if (databaseNameRangeIndex != null) {
|
||||
return defaultConnection(databaseNameRangeIndex);
|
||||
}
|
||||
databaseNameRangeIndex = fetchDatabaseNameRangeIndexWithoutHosts();
|
||||
if (databaseNameRangeIndex != null) {
|
||||
return defaultConnection(databaseNameRangeIndex);
|
||||
}
|
||||
String[] hostAndPort = fetchDatabaseHostsFromURL().split(":");
|
||||
if (hostAndPort.length == 1) {
|
||||
return new ConnectionInfo(
|
||||
ComponentsDefine.DERBY_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL());
|
||||
} else {
|
||||
return new ConnectionInfo(
|
||||
ComponentsDefine.DERBY_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]),
|
||||
fetchDatabaseNameFromURL()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch range index that the database name from connection url if Derby database running in embedded environment.
|
||||
* eg: jdbc:derby:[databaseName][;attribute=value]*
|
||||
*
|
||||
* @return range index that the database name.
|
||||
*/
|
||||
private int[] fetchDatabaseNameRangeIndexWithoutHosts() {
|
||||
if (url.contains("//")) {
|
||||
return null;
|
||||
}
|
||||
int fileLabelIndex = url.indexOf(DERBY_JDBC_URL_PREFIX);
|
||||
int parameterLabelIndex = url.indexOf(";");
|
||||
if (parameterLabelIndex == -1) {
|
||||
parameterLabelIndex = url.length();
|
||||
}
|
||||
|
||||
if (fileLabelIndex != -1) {
|
||||
int pathLabelIndexForLinux = url.lastIndexOf("/");
|
||||
if (pathLabelIndexForLinux != -1 && pathLabelIndexForLinux > fileLabelIndex) {
|
||||
return new int[] {
|
||||
pathLabelIndexForLinux + 1,
|
||||
parameterLabelIndex
|
||||
};
|
||||
}
|
||||
int pathLabelIndexForWin = url.lastIndexOf("\\");
|
||||
if (pathLabelIndexForWin != -1 && pathLabelIndexForWin > fileLabelIndex) {
|
||||
return new int[] {
|
||||
pathLabelIndexForWin + 1,
|
||||
parameterLabelIndex
|
||||
};
|
||||
}
|
||||
return new int[] {
|
||||
fileLabelIndex + DERBY_JDBC_URL_PREFIX.length() + 1,
|
||||
parameterLabelIndex
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch range index that the database name from connection url if Derby database running with subprotocol. eg:
|
||||
* jdbc:derby:subprotocol:[databaseName][;attribute=value]*
|
||||
*
|
||||
* @return range index that the database name.
|
||||
*/
|
||||
private int[] fetchDatabaseNameRangeIndexForSubProtocol(String mode) {
|
||||
int fileLabelIndex = url.indexOf(mode);
|
||||
int parameterLabelIndex = url.indexOf(";", fileLabelIndex);
|
||||
if (parameterLabelIndex == -1) {
|
||||
parameterLabelIndex = url.length();
|
||||
}
|
||||
|
||||
if (fileLabelIndex != -1) {
|
||||
int pathLabelIndexForLinux = url.lastIndexOf("/");
|
||||
if (pathLabelIndexForLinux != -1 && pathLabelIndexForLinux > fileLabelIndex) {
|
||||
return new int[] {
|
||||
pathLabelIndexForLinux + 1,
|
||||
parameterLabelIndex
|
||||
};
|
||||
}
|
||||
int pathLabelIndexForWin = url.lastIndexOf("\\");
|
||||
if (pathLabelIndexForWin != -1 && pathLabelIndexForWin > fileLabelIndex) {
|
||||
return new int[] {
|
||||
pathLabelIndexForWin + 1,
|
||||
parameterLabelIndex
|
||||
};
|
||||
}
|
||||
return new int[] {
|
||||
fileLabelIndex + mode.length() + 1,
|
||||
parameterLabelIndex
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ConnectionInfo defaultConnection(int[] databaseNameRangeIndex) {
|
||||
return new ConnectionInfo(
|
||||
ComponentsDefine.DERBY_JDBC_DRIVER, DB_TYPE, DEFAULT_HOST, -1,
|
||||
fetchDatabaseNameFromURL(databaseNameRangeIndex)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.network.trace.component.ComponentsDefine;
|
||||
|
||||
public class OceanBaseURLParser extends MysqlURLParser {
|
||||
public OceanBaseURLParser(String url) {
|
||||
super(url, "OceanBase", ComponentsDefine.OCEANBASE_JDBC_DRIVER, 2881);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.network.trace.component.ComponentsDefine;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
|
||||
public class SqliteURLParser extends AbstractURLParser {
|
||||
private static final String DEFAULT_HOST = "localhost";
|
||||
private static final int DEFAULT_PORT = -1;
|
||||
private static final String DB_TYPE = "Sqlite";
|
||||
|
||||
public SqliteURLParser(String url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URLLocation fetchDatabaseHostsIndexRange() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URLLocation fetchDatabaseNameIndexRange() {
|
||||
int databaseStartTag = url.lastIndexOf("/");
|
||||
if (databaseStartTag == -1) {
|
||||
databaseStartTag = url.lastIndexOf(":");
|
||||
}
|
||||
int databaseEndTag = url.indexOf("?");
|
||||
if (databaseEndTag == -1) {
|
||||
databaseEndTag = url.length();
|
||||
}
|
||||
|
||||
return new URLLocation(databaseStartTag + 1, databaseEndTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionInfo parse() {
|
||||
return new ConnectionInfo(
|
||||
ComponentsDefine.SQLITE_JDBC_DRIVER, DB_TYPE, DEFAULT_HOST, DEFAULT_PORT, fetchDatabaseNameFromURL());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser;
|
||||
|
||||
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
|
||||
|
||||
public class SybaseURLParser extends AbstractURLParser {
|
||||
private static final int DEFAULT_PORT = 5000;
|
||||
private static final String DB_TYPE = "Sybase";
|
||||
private static final String JDBC_PREFIX = "jdbc:sybase:Tds:";
|
||||
|
||||
public SybaseURLParser(String url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URLLocation fetchDatabaseHostsIndexRange() {
|
||||
int hostLabelStartIndex = JDBC_PREFIX.length();
|
||||
int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex);
|
||||
int hostLabelEndIndexWithParameter = url.indexOf("?", hostLabelStartIndex);
|
||||
if (hostLabelEndIndex == -1) {
|
||||
hostLabelEndIndex = hostLabelEndIndexWithParameter;
|
||||
}
|
||||
if (hostLabelEndIndexWithParameter < hostLabelEndIndex && hostLabelEndIndexWithParameter != -1) {
|
||||
hostLabelEndIndex = hostLabelEndIndexWithParameter;
|
||||
}
|
||||
if (hostLabelEndIndex == -1) {
|
||||
hostLabelEndIndex = url.length();
|
||||
}
|
||||
return new URLLocation(hostLabelStartIndex, 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);
|
||||
int parameterStartTag = url.indexOf("?", startSize);
|
||||
if (parameterStartTag < databaseStartTag && parameterStartTag != -1) {
|
||||
return null;
|
||||
}
|
||||
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() {
|
||||
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(ComponentsDefine.SYBASE_JDBC_DRIVER, DB_TYPE, sb.substring(0, sb.length() - 1), fetchDatabaseNameFromURL());
|
||||
} else {
|
||||
String[] hostAndPort = hostSegment[0].split(":");
|
||||
if (hostAndPort.length != 1) {
|
||||
return new ConnectionInfo(
|
||||
ComponentsDefine.SYBASE_JDBC_DRIVER, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]),
|
||||
fetchDatabaseNameFromURL(location
|
||||
.endIndex())
|
||||
);
|
||||
} else {
|
||||
return new ConnectionInfo(
|
||||
ComponentsDefine.SYBASE_JDBC_DRIVER, DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL(location
|
||||
.endIndex()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,11 @@ public class URLParser {
|
|||
private static final String KYLIN_JDBC_URL_PREFIX = "jdbc:kylin";
|
||||
private static final String IMPALA_JDBC_URL_PREFIX = "jdbc:impala";
|
||||
private static final String CLICKHOUSE_JDBC_URL_PREFIX = "jdbc:clickhouse";
|
||||
private static final String DERBY_JDBC_URL_PREFIX = "jdbc:derby:";
|
||||
private static final String SQLITE_JDBC_URL_PREFIX = "jdbc:sqlite:";
|
||||
private static final String DB2_JDBC_URL_PREFIIX = "jdbc:db2:";
|
||||
private static final String SYBASE_JDBC_URL_PREFIX = "jdbc:sybase:tds:";
|
||||
private static final String OCEANBASE_JDBC_URL_PREFIX = "jdbc:oceanbase:";
|
||||
|
||||
public static ConnectionInfo parser(String url) {
|
||||
ConnectionURLParser parser = null;
|
||||
|
|
@ -60,6 +65,16 @@ public class URLParser {
|
|||
parser = new ImpalaJdbcURLParser(url);
|
||||
} else if (lowerCaseUrl.startsWith(CLICKHOUSE_JDBC_URL_PREFIX)) {
|
||||
parser = new ClickHouseURLParser(url);
|
||||
} else if (lowerCaseUrl.startsWith(DERBY_JDBC_URL_PREFIX)) {
|
||||
parser = new DerbyURLParser(url);
|
||||
} else if (lowerCaseUrl.startsWith(SQLITE_JDBC_URL_PREFIX)) {
|
||||
parser = new SqliteURLParser(url);
|
||||
} else if (lowerCaseUrl.startsWith(DB2_JDBC_URL_PREFIIX)) {
|
||||
parser = new Db2URLParser(url);
|
||||
} else if (lowerCaseUrl.startsWith(SYBASE_JDBC_URL_PREFIX)) {
|
||||
parser = new SybaseURLParser(url);
|
||||
} else if (lowerCaseUrl.startsWith(OCEANBASE_JDBC_URL_PREFIX)) {
|
||||
parser = new OceanBaseURLParser(url);
|
||||
}
|
||||
return parser.parse();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,4 +280,139 @@ public class URLParserTest {
|
|||
assertThat(connectionInfo.getDatabaseName(), is("testdb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("[2001:db8::1234]:5432,[2001:db8::1235]:5432"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseOceanBaseJDBCURL() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:oceanbase://localhost:2881/mydb?user=root@sys&password=pass&pool=false&useBulkStmts=true&rewriteBatchedStatements=false&useServerPrepStmts=true");
|
||||
assertThat(connectionInfo.getDBType(), is("OceanBase"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:2881"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseOceanBaseJDBCURLWithMultiHosts() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:oceanbase://primaryhost:2888,secondaryhost1,secondaryhost2/mydb?user=root@sys&password=pass&pool=false&useBulkStmts=true&rewriteBatchedStatements=false&useServerPrepStmts=true");
|
||||
assertThat(connectionInfo.getDBType(), is("OceanBase"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("primaryhost:2888,secondaryhost1:2881,secondaryhost2:2881"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDerbyJDBCURLWithDirMode() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:derby:directory:mydb");
|
||||
assertThat(connectionInfo.getDBType(), is("Derby"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDerbyJDBCURLWithMemMode() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:derby:memory:mydb;create=true");
|
||||
assertThat(connectionInfo.getDBType(), is("Derby"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDerbyJDBCURLWithClassPathMode() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:derby:classpath:/test/mydb");
|
||||
assertThat(connectionInfo.getDBType(), is("Derby"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDerbyJDBCURLWithJarMode() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:derby:jar:(C:/dbs.jar)test/mydb");
|
||||
assertThat(connectionInfo.getDBType(), is("Derby"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDerbyJDBCURLWithEmbeddedMode() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:derby:test/mydb;create=true");
|
||||
assertThat(connectionInfo.getDBType(), is("Derby"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDerbyJDBCURLWithMemModeAndClientServerMode() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:derby://localhost:1527/memory:/test/mydb;create=true");
|
||||
assertThat(connectionInfo.getDBType(), is("Derby"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:1527"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDerbyJDBCURLWithClientServerMode() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:derby://localhost:1527/mydb;create=true;user=root;password=pass");
|
||||
assertThat(connectionInfo.getDBType(), is("Derby"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:1527"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDB2JDBCURL() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:db2://localhost:50000/mydb:user=root;password=pass");
|
||||
assertThat(connectionInfo.getDBType(), is("DB2"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:50000"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseDB2JDBCURLWithoutHost() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:db2:mydb:user=root;password=pass");
|
||||
assertThat(connectionInfo.getDBType(), is("DB2"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:50000"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseSqliteJDBCURL() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:sqlite:C/test/mydb.db");
|
||||
assertThat(connectionInfo.getDBType(), is("Sqlite"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb.db"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseSqliteJDBCURLWithMem() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:sqlite::memory:?jdbc.explicit_readonly=true");
|
||||
assertThat(connectionInfo.getDBType(), is("Sqlite"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is(""));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseSqliteJDBCURLWithResource() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:sqlite::resource:org/test/mydb.db");
|
||||
assertThat(connectionInfo.getDBType(), is("Sqlite"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb.db"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:-1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseSybaseJDBCURL() {
|
||||
ConnectionInfo connectionInfo = new URLParser().parser(
|
||||
"jdbc:sybase:Tds:localhost:5000/mydb?charset=utf-8");
|
||||
assertThat(connectionInfo.getDBType(), is("Sybase"));
|
||||
assertThat(connectionInfo.getDatabaseName(), is("mydb"));
|
||||
assertThat(connectionInfo.getDatabasePeer(), is("localhost:5000"));
|
||||
}
|
||||
}
|
||||
|
|
@ -168,10 +168,27 @@ The meter plugin provides the advanced metrics collections, which are not a part
|
|||
* [Jetty](https://github.com/eclipse/jetty.project) 9.1.x -> 11.x
|
||||
* [Grizzly](https://github.com/eclipse-ee4j/grizzly) 2.3.x -> 4.x
|
||||
* Connection Pool
|
||||
* [Apache Commons DBCP](https://github.com/apache/commons-dbcp) 2.x
|
||||
* [Alibaba Druid](https://github.com/alibaba/druid) 1.x
|
||||
* [HikariCP](https://github.com/brettwooldridge/HikariCP) 3.x -> 4.x
|
||||
* [C3P0](https://github.com/swaldman/c3p0) 0.9.0 -> 0.10.0
|
||||
* Supported JDBC drviers
|
||||
* [MySQL](https://www.mysql.com/)
|
||||
* [Oracle](https://www.oracle.com/)
|
||||
* [H2](https://h2database.com/html/main.html)
|
||||
* [PostgreSQL](https://www.postgresql.org/)
|
||||
* [MariaDB](https://mariadb.org/)
|
||||
* [SQL Server](https://www.microsoft.com/en-us/sql-server/)
|
||||
* [Apache Kylin](https://kylin.apache.org/)
|
||||
* [Impala](https://impala.apache.org/)
|
||||
* [ClickHouse](https://clickhouse.com/)
|
||||
* [Derby](https://db.apache.org/derby/)
|
||||
* [SQLite](https://www.sqlite.org/index.html)
|
||||
* [DB2](https://www.ibm.com/products/db2/database)
|
||||
* Sybase
|
||||
* [OceanBase](https://www.oceanbase.com/)
|
||||
* Supported Connection Pool Frameworks
|
||||
* [Apache Commons DBCP](https://github.com/apache/commons-dbcp) 2.x
|
||||
* [Alibaba Druid](https://github.com/alibaba/druid) 1.x
|
||||
* [HikariCP](https://github.com/brettwooldridge/HikariCP) 3.x -> 4.x
|
||||
* [C3P0](https://github.com/swaldman/c3p0) 0.9.0 -> 0.10.0
|
||||
|
||||
___
|
||||
¹Due to license incompatibilities/restrictions these plugins are hosted and released in 3rd part repository,
|
||||
go to [SkyAPM java plugin extension repository](https://github.com/SkyAPM/java-plugin-extensions) to get these.
|
||||
|
|
|
|||
Loading…
Reference in New Issue