Merge pull request #647 from ascrutae/feature/support-oracle-tns-url
support TNS URL of oracle plugin
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/AbstractURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/AbstractURLParser.java
index 74a897d..2d5d694 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/AbstractURLParser.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/AbstractURLParser.java
@@ -31,14 +31,14 @@
*
* @return index range that database hosts.
*/
- protected abstract int[] fetchDatabaseHostsIndexRange();
+ protected abstract URLLocation fetchDatabaseHostsIndexRange();
/**
* Fetch the index range that database name from connection url.
*
* @return index range that database name.
*/
- protected abstract int[] fetchDatabaseNameIndexRange();
+ protected abstract URLLocation fetchDatabaseNameIndexRange();
/**
* Fetch database host(s) from connection url.
@@ -46,8 +46,8 @@
* @return database host(s).
*/
protected String fetchDatabaseHostsFromURL() {
- int[] indexRange = fetchDatabaseHostsIndexRange();
- return url.substring(indexRange[0], indexRange[1]);
+ URLLocation hostsLocation = fetchDatabaseHostsIndexRange();
+ return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
}
/**
@@ -56,8 +56,8 @@
* @return database name.
*/
protected String fetchDatabaseNameFromURL() {
- int[] indexRange = fetchDatabaseNameIndexRange();
- return url.substring(indexRange[0], indexRange[1]);
+ URLLocation hostsLocation = fetchDatabaseNameIndexRange();
+ return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex());
}
/**
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/H2URLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/H2URLParser.java
index 416b486..1e79d8e 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/H2URLParser.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/H2URLParser.java
@@ -55,20 +55,20 @@
}
@Override
- protected int[] fetchDatabaseHostsIndexRange() {
+ protected URLLocation fetchDatabaseHostsIndexRange() {
int hostLabelStartIndex = url.indexOf("//");
int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
- return new int[] {hostLabelStartIndex + 2, hostLabelEndIndex};
+ return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
}
@Override
- protected int[] fetchDatabaseNameIndexRange() {
+ protected URLLocation fetchDatabaseNameIndexRange() {
int databaseStartTag = url.lastIndexOf("/");
int databaseEndTag = url.indexOf(";");
if (databaseEndTag == -1) {
databaseEndTag = url.length();
}
- return new int[] {databaseStartTag + 1, databaseEndTag};
+ return new URLLocation(databaseStartTag + 1, databaseEndTag);
}
@Override
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/MysqlURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/MysqlURLParser.java
index 0f71dd8..d463c05 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/MysqlURLParser.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/MysqlURLParser.java
@@ -41,26 +41,26 @@
}
@Override
- protected int[] fetchDatabaseHostsIndexRange() {
+ protected URLLocation fetchDatabaseHostsIndexRange() {
int hostLabelStartIndex = url.indexOf("//");
int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
- return new int[] {hostLabelStartIndex + 2, hostLabelEndIndex};
+ return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
}
@Override
- protected int[] fetchDatabaseNameIndexRange() {
+ protected URLLocation fetchDatabaseNameIndexRange() {
int databaseStartTag = url.lastIndexOf("/");
int databaseEndTag = url.indexOf("?", databaseStartTag);
if (databaseEndTag == -1) {
databaseEndTag = url.length();
}
- return new int[] {databaseStartTag + 1, databaseEndTag};
+ return new URLLocation(databaseStartTag + 1, databaseEndTag);
}
@Override
public ConnectionInfo parse() {
- int[] hostRangeIndex = fetchDatabaseHostsIndexRange();
- String hosts = url.substring(hostRangeIndex[0], hostRangeIndex[1]);
+ URLLocation location = fetchDatabaseHostsIndexRange();
+ String hosts = url.substring(location.startIndex(), location.endIndex());
String[] hostSegment = hosts.split(",");
if (hostSegment.length > 1) {
StringBuilder sb = new StringBuilder();
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/OracleURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/OracleURLParser.java
index 78523da..bf3c91e 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/OracleURLParser.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/OracleURLParser.java
@@ -18,8 +18,11 @@
package org.skywalking.apm.plugin.jdbc.connectionurl.parser;
+import java.util.ArrayList;
+import java.util.List;
import org.skywalking.apm.network.trace.component.ComponentsDefine;
import org.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.skywalking.apm.util.StringUtil;
/**
* {@link OracleURLParser} presents that how to parse oracle connection url.
@@ -38,29 +41,61 @@
private static final String DB_TYPE = "Oracle";
private static final int DEFAULT_PORT = 1521;
+ public static final String SERVICE_NAME_FLAG = "@//";
+ public static final String TNSNAME_URL_FLAG = "DESCRIPTION";
public OracleURLParser(String url) {
super(url);
}
@Override
- protected int[] fetchDatabaseHostsIndexRange() {
- int hostLabelStartIndex = url.indexOf("@");
+ protected URLLocation fetchDatabaseHostsIndexRange() {
+ int hostLabelStartIndex;
+ if (isServiceNameURL()) {
+ hostLabelStartIndex = url.indexOf(SERVICE_NAME_FLAG) + 3;
+ } else {
+ hostLabelStartIndex = url.indexOf("@") + 1;
+ }
int hostLabelEndIndex = url.lastIndexOf(":");
- return new int[] {hostLabelStartIndex + 1, hostLabelEndIndex};
+ return new URLLocation(hostLabelStartIndex, hostLabelEndIndex);
}
@Override
- protected int[] fetchDatabaseNameIndexRange() {
- return new int[0];
+ protected URLLocation fetchDatabaseNameIndexRange() {
+ int hostLabelStartIndex;
+ int hostLabelEndIndex = url.length();
+ if (isServiceNameURL()) {
+ hostLabelStartIndex = url.lastIndexOf("/") + 1;
+ } else if (isTNSNameURL()) {
+ hostLabelStartIndex = url.indexOf("=", url.indexOf("SERVICE_NAME")) + 1;
+ hostLabelEndIndex = url.indexOf(")", hostLabelStartIndex);
+ } else {
+ hostLabelStartIndex = url.lastIndexOf(":") + 1;
+ }
+ return new URLLocation(hostLabelStartIndex, hostLabelEndIndex);
+ }
+
+ private boolean isServiceNameURL() {
+ return url.contains(SERVICE_NAME_FLAG);
+ }
+
+ private boolean isTNSNameURL() {
+ return url.contains(TNSNAME_URL_FLAG);
}
@Override
public ConnectionInfo parse() {
- int[] hostRangeIndex = fetchDatabaseHostsIndexRange();
+ if (isTNSNameURL()) {
+ return tnsNameURLParse();
+ } else {
+ return commonsURLParse();
+ }
+ }
+
+ private ConnectionInfo commonsURLParse() {
String host = fetchDatabaseHostsFromURL();
String[] hostSegment = splitDatabaseAddress(host);
- String databaseName = url.substring(hostRangeIndex[1] + 1);
+ String databaseName = fetchDatabaseNameFromURL();
if (hostSegment.length == 1) {
return new ConnectionInfo(ComponentsDefine.ORACLE, DB_TYPE, host, DEFAULT_PORT, databaseName);
} else {
@@ -68,6 +103,40 @@
}
}
+ private ConnectionInfo tnsNameURLParse() {
+ String host = parseDatabaseHostsFromURL();
+ String databaseName = fetchDatabaseNameFromURL();
+ return new ConnectionInfo(ComponentsDefine.ORACLE, DB_TYPE, host, databaseName);
+ }
+
+ private String parseDatabaseHostsFromURL() {
+ int beginIndex = url.indexOf("DESCRIPTION");
+ List<String> hosts = new ArrayList<String>();
+ do {
+ int hostStartIndex = url.indexOf("HOST", beginIndex);
+ if (hostStartIndex == -1) {
+ break;
+ }
+ int equalStartIndex = url.indexOf("=", hostStartIndex);
+ int hostEndIndex = url.indexOf(")", hostStartIndex);
+ String host = url.substring(equalStartIndex + 1, hostEndIndex);
+
+ int port = DEFAULT_PORT;
+ int portStartIndex = url.indexOf("PORT", hostEndIndex);
+ int portEndIndex = url.length();
+ if (portStartIndex != -1) {
+ int portEqualStartIndex = url.indexOf("=", portStartIndex);
+ portEndIndex = url.indexOf(")", portEqualStartIndex);
+ port = Integer.parseInt(url.substring(portEqualStartIndex + 1, portEndIndex).trim());
+ }
+ hosts.add(host.trim() + ":" + port);
+ beginIndex = portEndIndex;
+ }
+ while (true);
+
+ return StringUtil.join(',', hosts.toArray(new String[0]));
+ }
+
private String[] splitDatabaseAddress(String address) {
String[] hostSegment = address.split(":");
return hostSegment;
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/PostgreSQLURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/PostgreSQLURLParser.java
index 2b2451a..4509d73 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/PostgreSQLURLParser.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/PostgreSQLURLParser.java
@@ -41,26 +41,26 @@
}
@Override
- protected int[] fetchDatabaseHostsIndexRange() {
+ protected URLLocation fetchDatabaseHostsIndexRange() {
int hostLabelStartIndex = url.indexOf("//");
int hostLabelEndIndex = url.indexOf("/", hostLabelStartIndex + 2);
- return new int[] {hostLabelStartIndex + 2, hostLabelEndIndex};
+ return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex);
}
@Override
- protected int[] fetchDatabaseNameIndexRange() {
+ protected URLLocation fetchDatabaseNameIndexRange() {
int databaseStartTag = url.lastIndexOf("/");
int databaseEndTag = url.indexOf("?", databaseStartTag);
if (databaseEndTag == -1) {
databaseEndTag = url.length();
}
- return new int[] {databaseStartTag + 1, databaseEndTag};
+ return new URLLocation(databaseStartTag + 1, databaseEndTag);
}
@Override
public ConnectionInfo parse() {
- int[] hostRangeIndex = fetchDatabaseHostsIndexRange();
- String hosts = url.substring(hostRangeIndex[0], hostRangeIndex[1]);
+ URLLocation location = fetchDatabaseHostsIndexRange();
+ String hosts = url.substring(location.startIndex(), location.endIndex());
String[] hostSegment = hosts.split(",");
if (hostSegment.length > 1) {
StringBuilder sb = new StringBuilder();
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/URLLocation.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/URLLocation.java
new file mode 100644
index 0000000..6890879
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/URLLocation.java
@@ -0,0 +1,37 @@
+/*
+ * 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.connectionurl.parser;
+
+public class URLLocation {
+ private final int startIndex;
+ private final int endIndex;
+
+ public URLLocation(int startIndex, int endIndex) {
+ this.startIndex = startIndex;
+ this.endIndex = endIndex;
+ }
+
+ public int startIndex() {
+ return startIndex;
+ }
+
+ public int endIndex() {
+ return endIndex;
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java
index 7f15d33..2f75988 100644
--- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java
+++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/test/java/org/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParserTest.java
@@ -74,6 +74,30 @@
}
@Test
+ public void testParseOracleServiceName() {
+ ConnectionInfo connectionInfo = new URLParser().parser("jdbc:oracle:thin:@//localhost:1521/orcl");
+ assertThat(connectionInfo.getDBType(), is("Oracle"));
+ assertThat(connectionInfo.getDatabaseName(), is("orcl"));
+ assertThat(connectionInfo.getDatabasePeer(), is("localhost:1521"));
+ }
+
+ @Test
+ public void testParseOracleTNSName() {
+ ConnectionInfo connectionInfo = new URLParser().parser("jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST= localhost )(PORT= 1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)))");
+ assertThat(connectionInfo.getDBType(), is("Oracle"));
+ assertThat(connectionInfo.getDatabaseName(), is("orcl"));
+ assertThat(connectionInfo.getDatabasePeer(), is("localhost:1521"));
+ }
+
+ @Test
+ public void testParseOracleTNSNameWithMultiAddress() {
+ ConnectionInfo connectionInfo = new URLParser().parser("jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL= TCP)(HOST=hostA)(PORT= 1523 ))(ADDRESS=(PROTOCOL=TCP)(HOST=hostB)(PORT= 1521 )))(SOURCE_ROUTE=yes)(CONNECT_DATA=(SERVICE_NAME=orcl)))");
+ assertThat(connectionInfo.getDBType(), is("Oracle"));
+ assertThat(connectionInfo.getDatabaseName(), is("orcl"));
+ assertThat(connectionInfo.getDatabasePeer(), is("hostA:1523,hostB:1521"));
+ }
+
+ @Test
public void testParseOracleJDBCURLWithUserNameAndPassword() {
ConnectionInfo connectionInfo = new URLParser().parser("jdbc:oracle:thin:scott/tiger@myhost:1521:orcl");
assertThat(connectionInfo.getDBType(), is("Oracle"));