/**
* Copyright 2011 Intuit Inc. All Rights Reserved
*/
package com.intuit.tank.reporting.db;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.intuit.tank.persistence.databases.DataBaseFactory;
import com.intuit.tank.persistence.databases.DatabaseKeys;
import com.intuit.tank.reporting.api.ResultsReporter;
import com.intuit.tank.reporting.api.TPSInfo;
import com.intuit.tank.reporting.api.TPSInfoContainer;
import com.intuit.tank.reporting.databases.Attribute;
import com.intuit.tank.reporting.databases.IDatabase;
import com.intuit.tank.reporting.databases.Item;
import com.intuit.tank.reporting.databases.TankDatabaseType;
import com.intuit.tank.results.TankResult;
import com.intuit.tank.vm.common.util.ReportUtil;
import com.intuit.tank.vm.settings.TankConfig;
/**
* DatabaseResultsReporter
*
* @author dangleton
*
*/
public class DatabaseResultsReporter implements ResultsReporter {
private static final Logger LOG = LogManager.getLogger(DatabaseResultsReporter.class);
private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(10, 50, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(50), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.DiscardOldestPolicy());
private String tpsTableName;
private String timingTableName;
private IDatabase db;
public DatabaseResultsReporter() {
db = DataBaseFactory.getDatabase();
}
/**
* @{inheritDoc
*/
@Override
public void sendTpsResults(final String jobId, final String instanceId, final TPSInfoContainer container,
boolean async) {
Runnable task = new Runnable() {
public void run() {
try {
List<Item> items = new ArrayList<Item>();
for (TPSInfo info : container.getTpsInfos()) {
Item item = createItem(jobId, instanceId, info);
items.add(item);
}
if (!items.isEmpty()) {
String tableName = getTpsTableName(db);
LOG.info("Sending " + items.size() + " to TPS Table " + tableName);
db.addItems(tableName, items, false);
}
} catch (Exception t) {
LOG.error("Error adding results: " + t.getMessage(), t);
throw new RuntimeException(t);
}
}
};
if (async) {
EXECUTOR.execute(task);
} else {
task.run();
}
}
/**
* @{inheritDoc
*/
@Override
public void sendTimingResults(String jobId, String instanceId, List<TankResult> results, boolean async) {
String tableName = getTimingTableName(db, jobId);
if (results.size() != 0 && tableName != null) {
final List<TankResult> l = new ArrayList<TankResult>();
synchronized (results) {
l.addAll(results);
results.clear();
}
DataBaseFactory.getDatabase().addTimingResults(tableName, l, async);
}
}
private Item createItem(String jobId, String instanceId, TPSInfo info) {
Item item = new Item();
List<Attribute> attributes = new ArrayList<Attribute>();
String ts = ReportUtil.getTimestamp(info.getTimestamp());
addAttribute(attributes, DatabaseKeys.TIMESTAMP_KEY.getShortKey(), ts);
addAttribute(attributes, DatabaseKeys.JOB_ID_KEY.getShortKey(), jobId);
addAttribute(attributes, DatabaseKeys.INSTANCE_ID_KEY.getShortKey(), instanceId);
addAttribute(attributes, DatabaseKeys.LOGGING_KEY_KEY.getShortKey(), info.getKey());
addAttribute(attributes, DatabaseKeys.PERIOD_KEY.getShortKey(), Integer.toString(info.getPeriodInSeconds()));
addAttribute(attributes, DatabaseKeys.TRANSACTIONS_KEY.getShortKey(), Integer.toString(info.getTransactions()));
item.setAttributes(attributes);
String name = instanceId
+ "_" + jobId
+ "_" + info.getKey()
+ "_" + ts;
item.setName(name);
return item;
}
public static void addAttribute(List<Attribute> attributes, String key, String value) {
if (value == null) {
value = "";
}
attributes.add(new Attribute(key, value));
}
@Override
public void config(HierarchicalConfiguration config) {
// nothing to configure
}
private String getTimingTableName(IDatabase db, String jobId) {
if (StringUtils.isBlank(timingTableName)) {
timingTableName = db.getDatabaseName(TankDatabaseType.timing, jobId);
db.createTable(timingTableName);
}
return timingTableName;
}
private String getTpsTableName(IDatabase db) {
if (StringUtils.isBlank(tpsTableName)) {
tpsTableName = new TankConfig().getInstanceName() + "_tps";
db.createTable(tpsTableName);
}
return tpsTableName;
}
}