/* * Copyright 2014 NAVER Corp. * * 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. */ package com.navercorp.pinpoint.plugin.jdbc.oracle; import com.navercorp.pinpoint.bootstrap.context.DatabaseInfo; import com.navercorp.pinpoint.bootstrap.logging.PLogger; import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.DefaultDatabaseInfo; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.JdbcUrlParserV2; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.StringMaker; import com.navercorp.pinpoint.bootstrap.plugin.jdbc.UnKnownDatabaseInfo; import com.navercorp.pinpoint.common.trace.ServiceType; import com.navercorp.pinpoint.plugin.jdbc.oracle.parser.Description; import com.navercorp.pinpoint.plugin.jdbc.oracle.parser.KeyValue; import com.navercorp.pinpoint.plugin.jdbc.oracle.parser.OracleNetConnectionDescriptorParser; import java.util.ArrayList; import java.util.List; /** * @author emeroad */ public class OracleJdbcUrlParser implements JdbcUrlParserV2 { private static final String URL_PREFIX = "jdbc:oracle:"; private final PLogger logger = PLoggerFactory.getLogger(this.getClass()); @Override public DatabaseInfo parse(String jdbcUrl) { if (jdbcUrl == null) { logger.info("jdbcUrl may not be null"); return UnKnownDatabaseInfo.INSTANCE; } if (!jdbcUrl.startsWith(URL_PREFIX)) { logger.info("jdbcUrl has invalid prefix.(url:{}, prefix:{})", jdbcUrl, URL_PREFIX); return UnKnownDatabaseInfo.INSTANCE; } DatabaseInfo result = null; try { result = parse0(jdbcUrl); } catch (Exception e) { logger.info("OracleJdbcUrl parse error. url: {}, Caused: {}", jdbcUrl, e.getMessage(), e); result = UnKnownDatabaseInfo.createUnknownDataBase(OracleConstants.ORACLE, OracleConstants.ORACLE_EXECUTE_QUERY, jdbcUrl); } return result; } private DatabaseInfo parse0(String jdbcUrl) { StringMaker maker = new StringMaker(jdbcUrl); maker.after(URL_PREFIX).after(":"); String description = maker.after('@').value().trim(); if (description.startsWith("(")) { return parseNetConnectionUrl(jdbcUrl); } else { return parseSimpleUrl(jdbcUrl, maker); } } // rac url. // jdbc:oracle:thin:@(Description=(LOAD_BALANCE=on)" + // "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521))" + // "(ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521))" + // "(CONNECT_DATA=(SERVICE_NAME=service)))" // // thin driver url // jdbc:oracle:thin:@hostname:port:SID // "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; // With proper indentation and line break, // jdbc:oracle:thin: // @( // Description=(LOAD_BALANCE=on) // ( // ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.4) (PORT=1521) // ) // ( // ADDRESS=(PROTOCOL=TCP)(HOST=1.2.3.5) (PORT=1521) // ) // ( // CONNECT_DATA=(SERVICE_NAME=service) // ) // ) private DatabaseInfo parseNetConnectionUrl(String url) { // oracle new URL : for rac OracleNetConnectionDescriptorParser parser = new OracleNetConnectionDescriptorParser(url); KeyValue keyValue = parser.parse(); // TODO Need to handle oci driver. It's more popular. // parser.getDriverType(); return createOracleDatabaseInfo(keyValue, url); } private DefaultDatabaseInfo parseSimpleUrl(String url, StringMaker maker) { // thin driver // jdbc:oracle:thin:@hostname:port:SID // "jdbc:oracle:thin:MYWORKSPACE/qwerty@localhost:1521:XE"; // jdbc:oracle:thin:@//hostname:port/serviceName String host = maker.before(':').value(); String port = maker.next().after(':').before(':', '/').value(); String databaseId = maker.next().afterLast(':', '/').value(); List<String> hostList = new ArrayList<String>(1); hostList.add(host + ":" + port); return new DefaultDatabaseInfo(OracleConstants.ORACLE, OracleConstants.ORACLE_EXECUTE_QUERY, url, url, hostList, databaseId); } private DatabaseInfo createOracleDatabaseInfo(KeyValue keyValue, String url) { Description description = new Description(keyValue); List<String> jdbcHost = description.getJdbcHost(); return new DefaultDatabaseInfo(OracleConstants.ORACLE, OracleConstants.ORACLE_EXECUTE_QUERY, url, url, jdbcHost, description.getDatabaseId()); } @Override public ServiceType getServiceType() { return OracleConstants.ORACLE; } }