/** * Copyright 2011 Intuit Inc. All Rights Reserved */ package com.intuit.tank.reporting.db; import java.text.ParseException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.configuration.HierarchicalConfiguration; 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.PagedTimingResults; import com.intuit.tank.reporting.api.ResultsReader; import com.intuit.tank.reporting.api.TPSInfo; 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.PagedDatabaseResult; import com.intuit.tank.reporting.databases.TankDatabaseType; import com.intuit.tank.results.TankResult; import com.intuit.tank.results.TankResultBuilder; import com.intuit.tank.vm.common.util.ReportUtil; import com.intuit.tank.vm.settings.TankConfig; /** * DatabaseResultsReader * * @author dangleton * */ public class DatabaseResultsReader implements ResultsReader { private static final Logger LOG = LogManager.getLogger(DatabaseResultsReader.class); private IDatabase db; public DatabaseResultsReader() { db = DataBaseFactory.getDatabase(); } /** * * @{inheritDoc */ @Override public List<TankResult> getAllTimingResults(String jobId) { Object nextToken = null; List<TankResult> ret = new ArrayList<TankResult>(); do { PagedTimingResults results = getPagedTimingResults(jobId, nextToken); ret.addAll(results.getResults()); nextToken = results.getNextToken(); } while (nextToken != null); return ret; } /** * * @{inheritDoc */ @Override public PagedTimingResults getPagedTimingResults(String jobId, Object nextToken) { String tableName = db.getDatabaseName(TankDatabaseType.timing, jobId); List<TankResult> results = new ArrayList<TankResult>(); try { PagedDatabaseResult pagedItems = db.getPagedItems(tableName, nextToken, null, null, null, jobId); for (Item item : pagedItems.getItems()) { results.add(ItemToTankResult(item)); } nextToken = pagedItems.getNextToken(); } catch (Exception e) { if (e instanceof RuntimeException) { throw (RuntimeException) e; } throw new RuntimeException(e); } return new PagedTimingResults(nextToken, results); } /** * * @{inheritDoc */ @Override public boolean hasTimingData(String jobId) { String tableName = db.getDatabaseName(TankDatabaseType.timing, jobId); return db.hasJobData(tableName, jobId); } private TankResult ItemToTankResult(Item item) { TankResultBuilder builder = TankResultBuilder.tankResult(); for (Attribute attr : item.getAttributes()) { try { if (DatabaseKeys.TIMESTAMP_KEY.getShortKey().equals(attr.getName())) { builder.withTimestamp(ReportUtil.parseTimestamp(attr.getValue())); } else if (DatabaseKeys.JOB_ID_KEY.getShortKey().equals(attr.getName())) { builder.withJobId(attr.getValue()); } else if (DatabaseKeys.INSTANCE_ID_KEY.getShortKey().equals(attr.getName())) { builder.withInstanceId(attr.getValue()); } else if (DatabaseKeys.LOGGING_KEY_KEY.getShortKey().equals(attr.getName())) { builder.withRequestName(attr.getValue()); } else if (DatabaseKeys.STATUS_CODE_KEY.getShortKey().equals(attr.getName())) { builder.withStatusCode(Integer.parseInt(attr.getValue())); } else if (DatabaseKeys.RESPONSE_TIME_KEY.getShortKey().equals(attr.getName())) { builder.withResponseTime(Integer.parseInt(attr.getValue())); } else if (DatabaseKeys.RESPONSE_SIZE_KEY.getShortKey().equals(attr.getName())) { builder.withResponseSize(Integer.parseInt(attr.getValue())); } else if (DatabaseKeys.IS_ERROR_KEY.getShortKey().equals(attr.getName())) { builder.withError(Boolean.valueOf(attr.getValue())); } } catch (Exception e) { LOG.warn("Error processing item: " + e); } } return builder.build(); } @Override public void deleteTimingForJob(String jobId, boolean asynch) { String tableName = db.getDatabaseName(TankDatabaseType.timing, jobId); db.deleteForJob(tableName, jobId, asynch); } @Override public void config(HierarchicalConfiguration config) { // nothing to do } @Override public Map<Date, Map<String, TPSInfo>> getTpsMapForInstance(Date minDate, String jobId, String instanceId) { return getTpsMap(minDate, instanceId, jobId); } @Override public Map<Date, Map<String, TPSInfo>> getTpsMapForJob(Date minDate, String... jobId) { return getTpsMap(minDate, null, jobId); } private Map<Date, Map<String, TPSInfo>> getTpsMap(Date minDate, String instanceId, String... jobIds) { Map<Date, Map<String, TPSInfo>> ret = new HashMap<Date, Map<String, TPSInfo>>(); try { String tpsTableName = new TankConfig().getInstanceName() + "_tps"; if (db.hasTable(tpsTableName)) { if (jobIds != null && jobIds.length > 0) { String dateString = null; if (minDate != null) { dateString = ReportUtil.getTimestamp(minDate); } List<Item> items = db.getItems(tpsTableName, dateString, null, instanceId, jobIds); for (Item item : items) { String loggingKey = null; Date timestamp = null; int transactions = 0; int period = 0; for (Attribute att : item.getAttributes()) { if (DatabaseKeys.LOGGING_KEY_KEY.getShortKey().equals(att.getName())) { loggingKey = att.getValue(); } else if (DatabaseKeys.TIMESTAMP_KEY.getShortKey().equals(att.getName())) { try { timestamp = ReportUtil.parseTimestamp(att.getValue()); } catch (ParseException e) { LOG.error("Error processing timestamp " + att.getValue() + ":" + e); continue; } } else if (DatabaseKeys.TRANSACTIONS_KEY.getShortKey().equals(att.getName())) { transactions = Integer.parseInt(att.getValue()); } else if (DatabaseKeys.PERIOD_KEY.getShortKey().equals(att.getName())) { period = Integer.parseInt(att.getValue()); } } TPSInfo info = new TPSInfo(timestamp, loggingKey, transactions, period); Map<String, TPSInfo> map = ret.get(timestamp); if (map == null) { map = new HashMap<String, TPSInfo>(); ret.put(timestamp, map); } TPSInfo existing = map.get(loggingKey); if (existing != null) { info = existing.add(info); } map.put(loggingKey, info); } } } } catch (Exception e) { LOG.error("Error getting TPS map: " + e, e); } return ret; } }