package org.spotter.ext.detection.olb;
import org.aim.api.exceptions.InstrumentationException;
import org.aim.api.exceptions.MeasurementException;
import org.aim.api.measurement.dataset.DatasetCollection;
import org.aim.artifacts.probes.ResponsetimeProbe;
import org.aim.artifacts.probes.SQLQueryProbe;
import org.aim.artifacts.sampler.CPUSampler;
import org.aim.artifacts.sampler.NetworkIOSampler;
import org.aim.artifacts.scopes.EntryPointScope;
import org.aim.artifacts.scopes.JDBCScope;
import org.aim.description.InstrumentationDescription;
import org.aim.description.builder.InstrumentationDescriptionBuilder;
import org.lpe.common.extension.IExtension;
import org.spotter.core.ProgressManager;
import org.spotter.core.detection.AbstractDetectionController;
import org.spotter.core.detection.AbstractDetectionExtension;
import org.spotter.core.detection.IDetectionController;
import org.spotter.core.detection.IExperimentReuser;
import org.spotter.exceptions.WorkloadException;
import org.spotter.ext.detection.olb.strategies.QTStrategy;
import org.spotter.ext.detection.olb.strategies.TTestCpuThresholdStrategy;
import org.spotter.shared.result.model.SpotterResult;
/**
* Detection controller for the One Lane Bridge anti-pattern.
*
* @author Alexander Wert
*
*/
public class OLBDetectionController extends AbstractDetectionController implements IExperimentReuser {
private static final int SAMPLING_DELAY = 100;
private int experimentSteps;
private String analysisStrategy;
private String scope;
private IOLBAnalysisStrategy analysisStrategyImpl;
private boolean reuser = false;
/**
* Constructor.
*
* @param provider
* extension provider
*/
public OLBDetectionController(IExtension<IDetectionController> provider) {
super(provider);
}
@Override
public void loadProperties() {
String experimentStepsStr = getProblemDetectionConfiguration().getProperty(OLBExtension.EXPERIMENT_STEPS_KEY);
experimentSteps = experimentStepsStr != null ? Integer.parseInt(experimentStepsStr)
: OLBExtension.EXPERIMENT_STEPS_DEFAULT;
scope = getProblemDetectionConfiguration().getProperty(OLBExtension.SCOPE_KEY, OLBExtension.ENTRY_SCOPE);
analysisStrategy = getProblemDetectionConfiguration().getProperty(OLBExtension.DETECTION_STRATEGY_KEY,
OLBExtension.QUEUEING_THEORY_STRATEGY);
switch (analysisStrategy) {
case OLBExtension.QUEUEING_THEORY_STRATEGY:
analysisStrategyImpl = new QTStrategy();
break;
case OLBExtension.T_TEST_CPU_THRESHOLD_STRATEGY:
analysisStrategyImpl = new TTestCpuThresholdStrategy();
break;
default:
analysisStrategyImpl = new QTStrategy();
}
analysisStrategyImpl.setMainDetectionController(this);
analysisStrategyImpl.setProblemDetectionConfiguration(getProblemDetectionConfiguration());
reuser = Boolean.parseBoolean(this.getProblemDetectionConfiguration().getProperty(
AbstractDetectionExtension.REUSE_EXPERIMENTS_FROM_PARENT, "false"));
}
@Override
public long getExperimentSeriesDuration() {
if (reuser) {
return 0;
} else {
return ProgressManager.getInstance().calculateDefaultExperimentSeriesDuration(experimentSteps);
}
}
@Override
public void executeExperiments() throws InstrumentationException, MeasurementException, WorkloadException {
if (!reuser) {
// TODO: fix that
if (scope.equals(OLBExtension.DB_SCOPE)) {
instrumentApplication(getInstrumentationDescription(1.0));
runExperiment(this, 1);
uninstrumentApplication();
instrumentApplication(getInstrumentationDescription(1.0));
runExperiment(this, 125);
uninstrumentApplication();
instrumentApplication(getInstrumentationDescription(0.1));
runExperiment(this, 250);
uninstrumentApplication();
instrumentApplication(getInstrumentationDescription(0.1));
runExperiment(this, 375);
uninstrumentApplication();
instrumentApplication(getInstrumentationDescription(0.05));
runExperiment(this, 500);
uninstrumentApplication();
} else {
executeDefaultExperimentSeries(this, experimentSteps, getInstrumentationDescription());
}
}
}
@Override
protected SpotterResult analyze(DatasetCollection data) {
return analysisStrategyImpl.analyze(data);
}
@Override
public InstrumentationDescription getInstrumentationDescription() {
InstrumentationDescriptionBuilder idBuilder = new InstrumentationDescriptionBuilder();
if (!reuser) {
switch (scope) {
case OLBExtension.SYNC_SCOPE:
// idBuilder
// .newMethodScopeEntity("tpcw.TPCW_Database.cartUpdateSynchronized*",
// "tpcw.TPCW_Database.getConnection()",
// "tpcw.TPCW_Database.returnConnection(*",
// "tpcw.TPCW_Database.createEmptyCart(java.sql.Connection*",
// "tpcw.TPCW_Database.createCustomer*",
// "tpcw.TPCW_Database.insertAddress*",
// "tpcw.TPCW_Database.newOrder*")
// .addProbe(ResponsetimeProbe.MODEL_PROBE).entityDone();
// idBuilder.newSynchronizedScopeEntity().addProbe(MonitorWaitingTimeProbe.MODEL_PROBE).entityDone();
idBuilder.newMethodScopeEntity("Nop.Web.Controllers.ShoppingCartController:ProblemMethod")
.addProbe(ResponsetimeProbe.MODEL_PROBE).entityDone();
break;
case OLBExtension.DB_SCOPE:
idBuilder.newAPIScopeEntity(JDBCScope.class.getName()).addProbe(ResponsetimeProbe.MODEL_PROBE)
.addProbe(SQLQueryProbe.MODEL_PROBE).entityDone();
idBuilder.newGlobalRestriction().setGranularity(0.01).restrictionDone();
break;
case OLBExtension.ENTRY_SCOPE:
idBuilder.newAPIScopeEntity(EntryPointScope.class.getName()).addProbe(ResponsetimeProbe.MODEL_PROBE)
.entityDone();
break;
default:
idBuilder.newAPIScopeEntity(EntryPointScope.class.getName()).addProbe(ResponsetimeProbe.MODEL_PROBE)
.entityDone();
break;
}
}
idBuilder.newSampling(CPUSampler.class.getName(), SAMPLING_DELAY);
idBuilder.newSampling(NetworkIOSampler.class.getName(), SAMPLING_DELAY);
return idBuilder.build();
}
public InstrumentationDescription getInstrumentationDescription(double granularity) {
InstrumentationDescriptionBuilder idBuilder = new InstrumentationDescriptionBuilder();
idBuilder.newAPIScopeEntity(JDBCScope.class.getName()).addProbe(ResponsetimeProbe.MODEL_PROBE)
.addProbe(SQLQueryProbe.MODEL_PROBE).entityDone();
idBuilder.newGlobalRestriction().setGranularity(granularity).restrictionDone();
idBuilder.newSampling(CPUSampler.class.getName(), SAMPLING_DELAY);
idBuilder.newSampling(NetworkIOSampler.class.getName(), SAMPLING_DELAY);
return idBuilder.build();
}
}