package com.meidusa.amoeba.mysql.benchmark;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import org.apache.log4j.Logger;
import com.meidusa.amoeba.benchmark.AbstractBenchmarkClient;
import com.meidusa.amoeba.benchmark.AbstractBenchmark.TaskRunnable;
import com.meidusa.amoeba.config.ParameterMapping;
import com.meidusa.amoeba.mysql.handler.session.SessionStatus;
import com.meidusa.amoeba.mysql.net.packet.AbstractPacket;
import com.meidusa.amoeba.mysql.net.packet.CommandPacket;
import com.meidusa.amoeba.mysql.net.packet.EOFPacket;
import com.meidusa.amoeba.mysql.net.packet.ErrorPacket;
import com.meidusa.amoeba.mysql.net.packet.FieldPacket;
import com.meidusa.amoeba.mysql.net.packet.MysqlPacketBuffer;
import com.meidusa.amoeba.mysql.net.packet.OkPacket;
import com.meidusa.amoeba.mysql.net.packet.QueryCommandPacket;
import com.meidusa.amoeba.mysql.net.packet.ResultSetHeaderPacket;
import com.meidusa.amoeba.mysql.net.packet.RowDataPacket;
import com.meidusa.amoeba.net.Connection;
import com.meidusa.amoeba.util.CmdLineParser;
import com.meidusa.amoeba.util.StringUtil;
import com.meidusa.amoeba.util.CmdLineParser.Option;
/**
*
* @author Struct
*
*/
public class MysqlBenchmarkClient extends AbstractBenchmarkClient<AbstractPacket> {
private static Logger logger = Logger.getLogger(MysqlBenchmarkClient.class);
public MysqlBenchmarkClient(Connection connection,CountDownLatch requestLatcher,CountDownLatch responseLatcher,TaskRunnable task) {
super(connection,requestLatcher,responseLatcher,task);
}
final Map<String ,String > parameterMap = new HashMap<String,String>();
final Map<String ,Object > beanParameterMap = new HashMap<String,Object>();
private byte commandType;
private int packetIndex;
private int statusCode;
public AbstractPacket createRequestPacket() {
Properties properties = this.getRequestProperties();
AbstractPacket packet = null;
try {
packet = (AbstractPacket)Class.forName((String)properties.get("class")).newInstance();
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
Map<String,Object> map = this.getNextRequestContextMap();
ParameterMapping.mappingObjectField(packet, beanParameterMap,map,this, AbstractPacket.class);
if(packet instanceof CommandPacket){
commandType = ((CommandPacket)packet).command;
}
packetIndex = 0;
statusCode = 0;
return packet;
}
public void init(){
super.init();
Properties properties = this.getRequestProperties();
for(Map.Entry<Object,Object> entry : properties.entrySet()){
if(entry.getKey().toString().startsWith("parameterMap.")){
parameterMap.put(entry.getKey().toString().substring("parameterMap.".length()), entry.getValue().toString());
}else{
beanParameterMap.put(entry.getKey().toString(), entry.getValue());
}
}
CmdLineParser parser = this.getBenchmark().getCmdLineParser();
Option option = parser.getOption("sql");
String sql = (String)parser.getOptionValue(option);
if(!StringUtil.isEmpty(sql)){
beanParameterMap.put("query", sql);
}
}
public AbstractPacket decodeRecievedPacket(byte[] buffer) {
AbstractPacket packet = null;
if (packetIndex == 0 && MysqlPacketBuffer.isErrorPacket(buffer)){
packet = new ErrorPacket();
} else if (packetIndex == 0 && MysqlPacketBuffer.isOkPacket(buffer)) {
packet = new OkPacket();
} else if (MysqlPacketBuffer.isEofPacket(buffer)) {
packet = new EOFPacket();
}else{
if((statusCode & SessionStatus.EOF_FIELDS) >0){
packet = new RowDataPacket(false);
}else if(packetIndex == 0){
packet = new ResultSetHeaderPacket();
}else{
packet = new FieldPacket();
}
}
packet.init(buffer, this.getConnection());
return packet;
}
protected void afterMessageRecieved(byte[] message){
packetIndex ++ ;
}
protected boolean responseIsCompleted(byte[] buffer){
if (this.commandType == QueryCommandPacket.COM_QUERY) {
boolean isCompleted = false;
if (packetIndex == 0 && MysqlPacketBuffer.isErrorPacket(buffer)) {
statusCode |= SessionStatus.ERROR;
statusCode |= SessionStatus.COMPLETED;
isCompleted = true;
} else if (packetIndex == 0 && MysqlPacketBuffer.isOkPacket(buffer)) {
statusCode |= SessionStatus.OK;
statusCode |= SessionStatus.COMPLETED;
isCompleted = true;
} else if (MysqlPacketBuffer.isEofPacket(buffer)) {
if ((statusCode & SessionStatus.EOF_FIELDS) > 0) {
statusCode |= SessionStatus.EOF_ROWS;
statusCode |= SessionStatus.COMPLETED;
isCompleted = true;
} else {
statusCode |= SessionStatus.EOF_FIELDS;
isCompleted = false;
}
} else {
if (statusCode == SessionStatus.QUERY) {
statusCode |= SessionStatus.RESULT_HEAD;
}
}
return isCompleted;
} else {
if(this.commandType == QueryCommandPacket.COM_INIT_DB){
boolean isCompleted = false;
if(packetIndex == 0 && MysqlPacketBuffer.isErrorPacket(buffer)){
statusCode |= SessionStatus.ERROR;
statusCode |= SessionStatus.COMPLETED;
isCompleted = true;
}else if(packetIndex == 0 && MysqlPacketBuffer.isOkPacket(buffer)){
statusCode |= SessionStatus.OK;
statusCode |= SessionStatus.COMPLETED;
isCompleted = true;
}
return isCompleted;
}else{
return false;
}
}
}
}