Skip to content

Commit

Permalink
Merge pull request #647 from ascrutae/feature/support-oracle-tns-url
Browse files Browse the repository at this point in the history
support TNS URL of oracle plugin
  • Loading branch information
wu-sheng authored Dec 6, 2017
2 parents 730c43d + 02877d4 commit 03824c2
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,23 @@ public AbstractURLParser(String url) {
*
* @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.
*
* @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());
}

/**
Expand All @@ -56,8 +56,8 @@ protected String fetchDatabaseHostsFromURL() {
* @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());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,20 @@ public H2URLParser(String url) {
}

@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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,26 @@ public MysqlURLParser(String url) {
}

@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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -38,36 +41,102 @@ public class OracleURLParser extends AbstractURLParser {

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 {
return new ConnectionInfo(ComponentsDefine.ORACLE, DB_TYPE, hostSegment[0], Integer.valueOf(hostSegment[1]), databaseName);
}
}

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,26 @@ public PostgreSQLURLParser(String url) {
}

@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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,30 @@ public void testParseOracleJDBCURLWithHostAndPort() {
assertThat(connectionInfo.getDatabasePeer(), is("localhost:1522"));
}

@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");
Expand Down

0 comments on commit 03824c2

Please sign in to comment.