/** * */ package com.bagri.test.tpox.workload; import static com.bagri.core.Constants.pn_client_fetchSize; import java.sql.Connection; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.Vector; import org.slf4j.Logger; import com.bagri.core.system.Cardinality; import com.bagri.core.system.Parameter; import net.sf.tpox.databaseoperations.DatabaseOperations; import net.sf.tpox.workload.core.WorkloadProcessor; import net.sf.tpox.workload.parameter.ActualParamInfo; import net.sf.tpox.workload.transaction.Transaction; import net.sf.tpox.workload.transaction.javaplugin.GenericJavaClassPlugin; import net.sf.tpox.workload.util.WorkloadEnvironment; /** * @author Denis Sukhoroslov * */ public abstract class BagriTPoXPlugin implements GenericJavaClassPlugin { protected static final int fetchSize = Integer.parseInt(System.getProperty(pn_client_fetchSize, "1")); protected WorkloadProcessor wp; protected WorkloadEnvironment we; protected Random rand; protected static final ThreadLocal<long[]> stats = new ThreadLocal<long[]>() { @Override protected long[] initialValue() { return new long[5]; } }; @Override public void prepare(int transNum, WorkloadProcessor workloadProcessor, WorkloadEnvironment workloadEnvironment, Connection con, int verbosityLevel, Random userRandomNumGenerator) throws SQLException { //logger.debug("prepare.enter; transNum: {}; WP: {}; WE: {}; Connection: {}; Level: {}; Random: {}", // new Object[] {transNum, workloadProcessor, workloadEnvironment, con, verbosityLevel, userRandomNumGenerator}); this.wp = workloadProcessor; this.we = workloadEnvironment; this.rand = userRandomNumGenerator; // TODO: we receive a new Random for each thread/user instance. should we keep them per thread? //logger.trace("prepare; transactions: {}; types: {}", wp.getTransactions(), wp.getTransactionTypes()); //logger.trace("prepare; params: {}; name: {}", wp.getParameterMarkers(), wp.getWorkloadName()); } protected Parameter buildParam(String type, String value) { return new Parameter(value, type, Cardinality.one); } @Override public int execute() throws SQLException { stats.get()[0]++; long stamp = System.currentTimeMillis(); int transNo = wp.getNextTransNumToExecute(rand); Transaction tx = wp.getTransaction(transNo); int result = 0; getLogger().trace("execute.enter; transaction: {}; #: {}; ", tx.getTransName(), transNo); Vector<net.sf.tpox.workload.parameter.Parameter>[] params = wp.getParameterMarkers(); int size = (params[transNo].size() - 2)/3; ActualParamInfo param = wp.getParamMarkerActualValue(transNo, 0, rand); String query = param.getActualValue(); param = wp.getParamMarkerActualValue(transNo, 1, rand); boolean isQuery = Boolean.parseBoolean(param.getActualValue()); Map<String, Parameter> vars = new HashMap<>(size); String value; int err = 0; //logger.debug("execute; size: {}; rand: {}; transNo: {}", size, rand, transNo); try { for (int i=0; i < size; i++) { param = wp.getParamMarkerActualValue(transNo, i*3+2, rand); String name = param.getActualValue(); param = wp.getParamMarkerActualValue(transNo, i*3+3, rand); String type = param.getActualValue(); param = wp.getParamMarkerActualValue(transNo, i*3+4, rand); if (type.equals("document")) { value = new String(param.getDocument()); } else { value = param.getActualValue(); } vars.put(name, buildParam(type, value)); } getLogger().trace("execute; query: {}; params: {}", query, vars); if (isQuery) { result = execQuery(query, vars); } else { result = execCommand(query, vars); } } catch (Throwable ex) { // just swallow it, in order to work further getLogger().error("execute.error", ex); err = 1; } DatabaseOperations.errors.get()[transNo] = err; getLogger().trace("execute.exit; returning: {}", result); stats.get()[1] += System.currentTimeMillis() - stamp; return result; } protected abstract Logger getLogger(); protected abstract int execCommand(String command, Map<String, Parameter> params) throws Exception; protected abstract int execQuery(String query, Map<String, Parameter> params) throws Exception; }