/** * Copyright 2014 SAP AG * * 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 org.spotter.ext.loadrunner.measurement; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.List; import org.aim.api.exceptions.MeasurementException; import org.aim.api.measurement.AbstractRecord; import org.aim.api.measurement.MeasurementData; import org.aim.artifacts.records.ResponseTimeRecord; import org.aim.description.InstrumentationDescription; import org.lpe.common.extension.IExtension; import org.lpe.common.loadgenerator.LoadGeneratorClient; import org.lpe.common.loadgenerator.config.LGMeasurementConfig; import org.lpe.common.loadgenerator.data.LGMeasurementData; import org.lpe.common.loadgenerator.data.TimeSpan; import org.lpe.common.util.LpeStringUtils; import org.spotter.core.instrumentation.InstrumentationBroker; import org.spotter.core.measurement.AbstractMeasurementAdapter; import org.spotter.ext.loadrunner.LRConfigKeys; import org.spotter.ext.loadrunner.instrumentation.LoadRunnerInstrumentationClient; /** * The LoadRunner measurement client which communicates with the LoadRunner * measurement resource. * * @author Le-Huan Stefan Tran */ public class LoadRunnerMeasurementClient extends AbstractMeasurementAdapter { private LGMeasurementConfig lrmConfig; private LoadGeneratorClient lrClient; private LoadRunnerInstrumentationClient instrumentationClient = null; /** * Constructor. * * @param provider * extension provider */ public LoadRunnerMeasurementClient(IExtension<?> provider) { super(provider); } @Override public void initialize() throws MeasurementException { for (LoadRunnerInstrumentationClient instrClient : InstrumentationBroker.getInstance() .getInstrumentationControllers(LoadRunnerInstrumentationClient.class)) { if (instrClient.getHost().equals(getHost()) && instrClient.getPort().equals(getPort())) { instrumentationClient = instrClient; } } if (lrClient == null) { lrClient = new LoadGeneratorClient(getHost(), getPort()); lrmConfig = new LGMeasurementConfig(); lrmConfig.setAnalysisPath(LpeStringUtils .getPropertyOrFail(getProperties(), LRConfigKeys.ANALYSIS_EXE, null)); lrmConfig.setAnalysisTemplate(LpeStringUtils.getPropertyOrFail(getProperties(), LRConfigKeys.ANALYSIS_TEMPLATE_NAME, null)); lrmConfig.setResultDir(LpeStringUtils.getPropertyOrFail(getProperties(), LRConfigKeys.RESULT_DIR, null)); lrmConfig.setSessionName(LpeStringUtils.getPropertyOrFail(getProperties(), LRConfigKeys.ANALYSIS_SESSION_NAME, null)); if (!lrClient.testConnection()) { throw new MeasurementException("Connection to loadrunner could not be established!"); } } } @Override public void enableMonitoring() throws MeasurementException { // Nothing to do here. } @Override public void disableMonitoring() throws MeasurementException { // Nothing to do here. } @Override public MeasurementData getMeasurementData() throws MeasurementException { if (lrmConfig == null) { throw new MeasurementException("LoadRunner Measurement Client has not been initialized yet!"); } if (instrumentationClient != null && instrumentationClient.isInstrumented()) { LGMeasurementData lgData = lrClient.getMeasurementData(lrmConfig); List<AbstractRecord> records = new ArrayList<>(); for (String transactionName : lgData.getTransactionNames()) { for (TimeSpan tSpan : lgData.getTimesForTransaction(transactionName)) { records.add(new ResponseTimeRecord(tSpan.getStart(), transactionName, tSpan.getStop()-tSpan.getStart())); } } MeasurementData data = new MeasurementData(); data.setRecords(records); return data; } else { return new MeasurementData(); } } @Override public long getCurrentTime() { return lrClient.getCurrentTime(); } @Override public void setControllerRelativeTime(long relativeTime) { // Loadrunner Timestamps are alredy relative super.setControllerRelativeTime(0); } @Override public void pipeToOutputStream(OutputStream oStream) throws MeasurementException { if (lrmConfig == null) { throw new MeasurementException("LoadRunner Measurement Client has not been initialized yet!"); } BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(oStream)); try { MeasurementData data = getMeasurementData(); for (AbstractRecord record : data.getRecords()) { String line = record.toString(); bWriter.write(line); bWriter.newLine(); } } catch (IOException e) { throw new MeasurementException(e); } finally { try { bWriter.flush(); oStream.close(); } catch (IOException e) { throw new MeasurementException(e); } } } @Override public void storeReport(String path) throws MeasurementException { String reportPath = path + System.getProperty("file.separator") + "LRReport"; File reportDir = new File(reportPath); reportDir.mkdir(); File reportZip = new File(reportPath + System.getProperty("file.separator") + "report.zip"); try { FileOutputStream fos = new FileOutputStream(reportZip); lrClient.pipeReportToOutputStream(fos, lrmConfig); } catch (IOException e) { throw new MeasurementException(e); } } @Override public void prepareMonitoring(InstrumentationDescription monitoringDescription) throws MeasurementException { // TODO Auto-generated method stub } @Override public void resetMonitoring() throws MeasurementException { // TODO Auto-generated method stub } }