/* * RHQ Management Platform * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.plugins.oracle; import static org.rhq.core.domain.measurement.AvailabilityType.DOWN; import static org.rhq.core.domain.measurement.AvailabilityType.UP; import static org.rhq.plugins.database.DatabasePluginUtil.getNumericQueryValueMap; import static org.rhq.plugins.database.DatabasePluginUtil.getSingleNumericQueryValue; import static org.rhq.plugins.oracle.OraclePooledConnectionProvider.CREDENTIALS_PROPERTY; import static org.rhq.plugins.oracle.OraclePooledConnectionProvider.DRIVER_CLASS_PROPERTY; import static org.rhq.plugins.oracle.OraclePooledConnectionProvider.PRINCIPAL_PROPERTY; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.Map; import java.util.Properties; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.measurement.AvailabilityType; import org.rhq.core.domain.measurement.MeasurementDataNumeric; import org.rhq.core.domain.measurement.MeasurementReport; import org.rhq.core.domain.measurement.MeasurementScheduleRequest; import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; import org.rhq.core.pluginapi.inventory.ResourceContext; import org.rhq.core.pluginapi.measurement.MeasurementFacet; import org.rhq.plugins.database.ConnectionPoolingSupport; import org.rhq.plugins.database.DatabaseComponent; import org.rhq.plugins.database.DatabasePluginUtil; import org.rhq.plugins.database.PooledConnectionProvider; /** * @author Greg Hinkle */ public class OracleServerComponent implements DatabaseComponent, ConnectionPoolingSupport, MeasurementFacet { private static final Log LOG = LogFactory.getLog(OracleServerComponent.class); private ResourceContext resourceContext; @Deprecated private Connection connection; private OraclePooledConnectionProvider pooledConnectionProvider; public void start(ResourceContext resourceContext) throws InvalidPluginConfigurationException, Exception { this.resourceContext = resourceContext; buildSharedConnectionIfNeeded(); pooledConnectionProvider = new OraclePooledConnectionProvider(resourceContext.getPluginConfiguration()); } public void stop() { removeConnection(); } @Override public boolean supportsConnectionPooling() { return true; } @Override public PooledConnectionProvider getPooledConnectionProvider() { return pooledConnectionProvider; } private void buildSharedConnectionIfNeeded() { try { if (this.connection == null || connection.isClosed()) { this.connection = buildConnection(this.resourceContext.getPluginConfiguration()); } } catch (SQLException e) { LOG.debug("Unable to create oracle connection", e); } } public AvailabilityType getAvailability() { Connection jdbcConnection = null; try { jdbcConnection = getPooledConnectionProvider().getPooledConnection(); return jdbcConnection.isValid(1) ? UP : DOWN; } catch (SQLException e) { return DOWN; } finally { DatabasePluginUtil.safeClose(jdbcConnection); } } public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception { Map<String, Double> values = getNumericQueryValueMap(this, "SELECT name, value FROM V$SYSSTAT"); for (MeasurementScheduleRequest request : metrics) { if (request.getName().equals("totalSize")) { Double val = getSingleNumericQueryValue(this, "SELECT SUM(bytes) FROM SYS.DBA_DATA_FILES"); report.addData(new MeasurementDataNumeric(request, val)); } else { Double value = values.get(request.getName()); if (value != null) { report.addData(new MeasurementDataNumeric(request, value)); } } } } public Connection getConnection() { buildSharedConnectionIfNeeded(); return this.connection; } public void removeConnection() { DatabasePluginUtil.safeClose(this.connection); this.connection = null; } public static Connection buildConnection(Configuration configuration) throws SQLException { String driverClass = configuration.getSimple(DRIVER_CLASS_PROPERTY).getStringValue(); try { Class.forName(driverClass); } catch (ClassNotFoundException e) { throw new InvalidPluginConfigurationException("Specified JDBC driver class (" + driverClass + ") not found."); } String url = buildUrl(configuration); if (LOG.isDebugEnabled()) { LOG.debug("Attempting JDBC connection to [" + url + "]"); } String principal = configuration.getSimple(PRINCIPAL_PROPERTY).getStringValue(); String credentials = configuration.getSimple(CREDENTIALS_PROPERTY).getStringValue(); Properties props = new Properties(); props.put("user", principal); props.put("password", credentials); if (principal.equalsIgnoreCase("SYS")) { props.put("internal_logon", "sysdba"); } return DriverManager.getConnection(url, props); } static String buildUrl(Configuration configuration) { String connMethod = configuration.getSimpleValue("connectionMethod", "SID"); if (connMethod.equalsIgnoreCase("SID")) { return "jdbc:oracle:thin:@" + configuration.getSimpleValue("host", "localhost") + ":" + configuration.getSimpleValue("port", "1521") + ":" + configuration.getSimpleValue("sid", "XE"); } else { return "jdbc:oracle:thin:@//" + configuration.getSimpleValue("host", "localhost") + ":" + configuration.getSimpleValue("port", "1521") + "/" + configuration.getSimpleValue("sid", "XE"); } } }