package org.spotter.ext.measurement.database; import java.io.IOException; import java.io.OutputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; import java.util.concurrent.Future; import org.aim.api.exceptions.MeasurementException; import org.aim.api.measurement.MeasurementData; import org.aim.api.measurement.collector.AbstractDataSource; import org.aim.api.measurement.collector.CollectorFactory; import org.aim.artifacts.measurement.collector.FileDataSource; import org.aim.artifacts.records.DBStatisticsRecrod; import org.aim.description.InstrumentationDescription; import org.aim.description.sampling.SamplingDescription; import org.lpe.common.extension.IExtension; import org.lpe.common.util.system.LpeSystemUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spotter.core.measurement.AbstractMeasurementAdapter; public class HDBMeasurement extends AbstractMeasurementAdapter implements Runnable { private static final Logger LOGGER = LoggerFactory.getLogger(HDBMeasurement.class); public static Integer instanceId = 1; private AbstractDataSource dataSource; private String host; private String port; private String username; private String password; private Long delay; private Connection connection; private PreparedStatement sqlStatement; private boolean running; private boolean samplerActivated = false; private Future<?> measurementTask; private static final String SQL_QUERY = "SELECT * FROM M_LOCK_WAITS_STATISTICS WHERE PORT LIKE '%03' AND LOCK_TYPE='TABLE';"; public HDBMeasurement(IExtension<?> provider) { super(provider); } @Override public void enableMonitoring() throws MeasurementException { if (samplerActivated) { try { sqlStatement = getConnection().prepareStatement(SQL_QUERY); } catch (Exception e) { throw new RuntimeException(e); } measurementTask = LpeSystemUtils.submitTask(this); } } @Override public void disableMonitoring() throws MeasurementException { if (samplerActivated) { try { running = false; measurementTask.get(); if (sqlStatement != null) { sqlStatement.close(); sqlStatement = null; } if (connection != null) { connection.close(); connection = null; } } catch (Exception e) { throw new MeasurementException(e); } } } @Override public MeasurementData getMeasurementData() throws MeasurementException { if (samplerActivated) { return dataSource.read(); } else { return new MeasurementData(); } } @Override public void pipeToOutputStream(OutputStream oStream) throws MeasurementException { if (samplerActivated) { dataSource.pipeToOutputStream(oStream); } else { try { oStream.close(); } catch (IOException e) { throw new MeasurementException(e); } } } @Override public void initialize() throws MeasurementException { host = getProperties().getProperty(HDBMeasurementExtension.HOST_KEY, "localhost"); port = getProperties().getProperty(HDBMeasurementExtension.PORT_KEY, "11111"); username = getProperties().getProperty(HDBMeasurementExtension.USER_NAME_KEY, ""); password = getProperties().getProperty(HDBMeasurementExtension.PASSWORD_KEY, ""); Properties collectorProperties = new Properties(); synchronized (instanceId) { collectorProperties.setProperty(FileDataSource.ADDITIONAL_FILE_PREFIX_KEY, "HDBSampler-" + instanceId); instanceId++; } dataSource = CollectorFactory.createDataSource(FileDataSource.class.getName(), collectorProperties); } @Override public long getCurrentTime() { return System.currentTimeMillis(); } @Override public void storeReport(String path) throws MeasurementException { // TODO Auto-generated method stub } @Override public void run() { running = true; try { dataSource.enable(); long counter = 0; while (running) { sampleLockStatistics(counter); counter++; try { Thread.sleep(delay); } catch (InterruptedException ie) { LOGGER.debug("Sleeptime interrupted."); running = false; } } dataSource.disable(); } catch (MeasurementException e) { throw new RuntimeException(e); } } private void sampleLockStatistics(long ownNumQueries) { try { ResultSet resultSet = sqlStatement.executeQuery(); long numQueueries = -1; long numLockWaits = 0; long lockTime = 0; resultSet.next(); numLockWaits = resultSet.getLong("TOTAL_LOCK_WAITS"); lockTime = resultSet.getLong("TOTAL_LOCK_WAIT_TIME"); resultSet.close(); DBStatisticsRecrod record = new DBStatisticsRecrod(); record.setTimeStamp(System.currentTimeMillis()); record.setNumQueueries(numQueueries); record.setProcessId(host + ":" + port); record.setNumLockWaits(numLockWaits); record.setLockTime(lockTime); dataSource.newRecord(record); } catch (SQLException e) { throw new RuntimeException(e); } } protected Connection getConnection() { if (connection != null) { return connection; } Properties props = new Properties(); props.setProperty("user", username); props.setProperty("password", password); String connectionString = "jdbc:sap://" + host + ":" + port; try { Class.forName("com.sap.db.jdbc.Driver"); } catch (ClassNotFoundException e) { LOGGER.error(e.getMessage()); return null; } try { connection = DriverManager.getConnection(connectionString, props); } catch (SQLException e) { LOGGER.error(e.getMessage()); return null; } return connection; } public boolean testConnection() { return getConnection() != null; } @Override public void prepareMonitoring(InstrumentationDescription monitoringDescription) throws MeasurementException { for (SamplingDescription sDescr : monitoringDescription.getSamplingDescriptions()) { if (sDescr.getResourceName().equals(SamplingDescription.SAMPLER_DATABASE_STATISTICS)) { samplerActivated = true; delay = sDescr.getDelay(); break; } } } @Override public void resetMonitoring() throws MeasurementException { samplerActivated = false; } }