/**
* 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.jmeter.workload;
import java.io.IOException;
import org.lpe.common.extension.IExtension;
import org.lpe.common.jmeter.JMeterWrapper;
import org.lpe.common.jmeter.config.JMeterWorkloadConfig;
import org.lpe.common.util.LpeStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spotter.core.workload.AbstractWorkloadAdapter;
import org.spotter.core.workload.LoadConfig;
import org.spotter.exceptions.WorkloadException;
import org.spotter.ext.jmeter.JMeterConfigKeys;
/**
* The client to communicate with the JMeter server.
*/
public class JMeterWorkloadClient extends AbstractWorkloadAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(JMeterWorkloadClient.class);
private static final int POLLING_INTERVAL = 500;
private static final int MILLIS_IN_SECOND = 1000;
private JMeterWrapper jmClient;
private long experimentStartTime;
private long rampUpDuration;
private long experimentDuration;
/**
* Constructor.
*
* @param provider
* extension provider
*/
public JMeterWorkloadClient(IExtension<?> provider) {
super(provider);
}
@Override
public void initialize() throws WorkloadException {
jmClient = JMeterWrapper.getInstance();
}
@Override
public void startLoad(LoadConfig loadConfig) throws WorkloadException {
JMeterWorkloadConfig jMeterConfig = createJMeterConfig(loadConfig);
LOGGER.info("Triggered load with {} users ...", jMeterConfig.getNumUsers());
experimentStartTime = System.currentTimeMillis();
rampUpDuration = calculateActualRampUpDuration(jMeterConfig);
experimentDuration = jMeterConfig.getExperimentDuration() * MILLIS_IN_SECOND;
try {
jmClient.startLoadTest(jMeterConfig);
} catch (IOException e) {
throw new WorkloadException(e);
}
}
/**
* Calculaters the estimated time for the ramp up phase for JMeter.
*
* @param jMeterConfig
* the {@link JMeterWorkloadConfig}
* @return the time
*/
private long calculateActualRampUpDuration(JMeterWorkloadConfig jMeterConfig) {
int rampUpInterval = (int) jMeterConfig.getRampUpInterval();
int rampUpUsersPerInterval = (int) jMeterConfig.getRampUpNumUsersPerInterval();
int numUsers = jMeterConfig.getNumUsers();
return ((numUsers / rampUpUsersPerInterval) - ((numUsers % rampUpUsersPerInterval == 0) ? 1 : 0))
* rampUpInterval;
}
@Override
public void waitForFinishedLoad() throws WorkloadException {
try {
jmClient.waitForLoadTestFinish();
} catch (InterruptedException e) {
throw new WorkloadException(e);
}
LOGGER.info("Load generation finished.");
}
private JMeterWorkloadConfig createJMeterConfig(LoadConfig loadConfig) {
JMeterWorkloadConfig jMeterConfig = new JMeterWorkloadConfig();
// required properties
jMeterConfig.setExperimentDuration(loadConfig.getExperimentDuration());
jMeterConfig.setNumUsers(loadConfig.getNumUsers());
jMeterConfig.setRampUpInterval(loadConfig.getRampUpIntervalLength());
jMeterConfig.setRampUpNumUsersPerInterval(loadConfig.getRampUpUsersPerInterval());
jMeterConfig.setCoolDownInterval(loadConfig.getCoolDownIntervalLength());
jMeterConfig.setCoolDownNumUsersPerInterval(loadConfig.getCoolDownUsersPerInterval());
jMeterConfig.setPathToJMeterBinFolder(LpeStringUtils.getPropertyOrFail(getProperties(),
JMeterConfigKeys.JMETER_HOME, null));
jMeterConfig.setPathToScript(LpeStringUtils.getPropertyOrFail(getProperties(), JMeterConfigKeys.SCENARIO_FILE,
null));
jMeterConfig.setThinkTimeMaximum(Integer.parseInt(LpeStringUtils.getPropertyOrFail(getProperties(),
JMeterConfigKeys.THINK_TIME_MIN, null)));
jMeterConfig.setThinkTimeMinimum(Integer.parseInt(LpeStringUtils.getPropertyOrFail(getProperties(),
JMeterConfigKeys.THINK_TIME_MAX, null)));
// optional properties
boolean sampleInFile = Boolean.parseBoolean(getProperties().getProperty(JMeterConfigKeys.SAMPLING_FLAG));
if (sampleInFile) {
jMeterConfig.setSamplingFileFlag(true);
// fail when there is no property set for the sampling file
jMeterConfig.setPathToSamplingFile(LpeStringUtils.getPropertyOrFail(getProperties(),
JMeterConfigKeys.SAMPLING_FILE, null));
}
boolean createLogFile = Boolean.parseBoolean(getProperties().getProperty(JMeterConfigKeys.LOG_FILE_FLAG));
if (createLogFile) {
jMeterConfig.setCreateLogFlag(true);
jMeterConfig.setLogFilePrefix(getProperties().getProperty(JMeterConfigKeys.LOG_FILE_PREFIX));
}
return jMeterConfig;
}
@Override
public void waitForWarmupPhaseTermination() throws WorkloadException {
while (System.currentTimeMillis() < experimentStartTime + rampUpDuration) {
try {
Thread.sleep(POLLING_INTERVAL);
} catch (InterruptedException e) {
throw new WorkloadException(e);
}
}
}
@Override
public void waitForExperimentPhaseTermination() throws WorkloadException {
while (System.currentTimeMillis() < experimentStartTime + rampUpDuration + experimentDuration) {
try {
Thread.sleep(POLLING_INTERVAL);
} catch (InterruptedException e) {
throw new WorkloadException(e);
}
}
}
}