/*************************************************************************
* Copyright 2009-2013 Eucalyptus Systems, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
* Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
* CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
* additional information or have any questions.
************************************************************************/
package com.eucalyptus.cloudwatch.common.internal.domain.metricdata;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.persistence.EntityTransaction;
import com.eucalyptus.cloudwatch.common.internal.domain.AbstractPersistentWithDimensions;
import com.eucalyptus.configurable.ConfigurableClass;
import com.eucalyptus.configurable.ConfigurableField;
import com.eucalyptus.configurable.PropertyChangeListeners;
import com.eucalyptus.entities.TransactionResource;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import org.apache.log4j.Logger;
import org.hibernate.CacheMode;
import org.hibernate.Criteria;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;
import org.hibernate.criterion.Junction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import com.eucalyptus.cloudwatch.common.internal.domain.DimensionEntity;
import com.eucalyptus.cloudwatch.common.internal.domain.metricdata.MetricEntity.MetricType;
import com.eucalyptus.cloudwatch.common.internal.hashing.HashUtils;
import com.eucalyptus.entities.Entities;
import com.eucalyptus.records.Logs;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
public class MetricManager {
public static volatile Integer METRIC_DATA_NUM_DB_OPERATIONS_PER_TRANSACTION = 10000;
public static volatile Integer METRIC_DATA_NUM_DB_OPERATIONS_UNTIL_SESSION_FLUSH = 50;
public static final Logger LOG = Logger.getLogger(MetricManager.class);
public static void addMetric(String accountId,
String metricName, String namespace, Map<String, String> dimensionMap,
MetricType metricType, Units units, Date timestamp, Double sampleSize,
Double sampleMax, Double sampleMin, Double sampleSum) {
SimpleMetricEntity simpleMetricEntity = new SimpleMetricEntity();
simpleMetricEntity.setAccountId(accountId);
simpleMetricEntity.setDimensionMap(dimensionMap);
simpleMetricEntity.setMetricName(metricName);
simpleMetricEntity.setMetricType(metricType);
simpleMetricEntity.setNamespace(namespace);
simpleMetricEntity.setSampleMax(sampleMax);
simpleMetricEntity.setSampleMin(sampleMin);
simpleMetricEntity.setSampleSize(sampleSize);
simpleMetricEntity.setSampleSum(sampleSum);
simpleMetricEntity.setTimestamp(timestamp);
simpleMetricEntity.setUnits(units);
validateMetricQueueItem(simpleMetricEntity);
addManyMetrics(makeMetricMap(hash(simpleMetricEntity)));
}
private static Multimap<Class, MetricEntity> makeMetricMap(Collection<MetricEntity> entities) {
Multimap<Class, MetricEntity> metricMap = ArrayListMultimap
.<Class, MetricEntity> create();
for (MetricEntity entity:entities) {
metricMap
.put(MetricEntityFactory.getClassForEntitiesGet(entity.getMetricType(),
entity.getDimensionHash()), entity);
}
return metricMap;
}
private static List<MetricEntity> hash(SimpleMetricEntity simpleMetricEntity) {
if (simpleMetricEntity == null) return new ArrayList<MetricEntity>();
TreeSet<DimensionEntity> dimensions = new TreeSet<DimensionEntity>();
for (Map.Entry<String, String> entry : simpleMetricEntity.getDimensionMap().entrySet()) {
DimensionEntity d = new DimensionEntity();
d.setName(entry.getKey());
d.setValue(entry.getValue());
dimensions.add(d);
}
ArrayList<MetricEntity> returnValue = new ArrayList<MetricEntity>();
String dimensionHash = hash(dimensions);
MetricEntity metric = MetricEntityFactory.getNewMetricEntity(simpleMetricEntity.getMetricType(),
dimensionHash);
metric.setAccountId(simpleMetricEntity.getAccountId());
metric.setMetricName(simpleMetricEntity.getMetricName());
metric.setNamespace(simpleMetricEntity.getNamespace());
metric.setDimensionHash(dimensionHash);
metric.setMetricType(simpleMetricEntity.getMetricType());
metric.setUnits(simpleMetricEntity.getUnits());
metric.setTimestamp(simpleMetricEntity.getTimestamp());
metric.setSampleMax(simpleMetricEntity.getSampleMax());
metric.setSampleMin(simpleMetricEntity.getSampleMin());
metric.setSampleSum(simpleMetricEntity.getSampleSum());
metric.setSampleSize(simpleMetricEntity.getSampleSize());
returnValue.add(metric);
return returnValue;
}
private static void addManyMetrics(Multimap<Class, MetricEntity> metricMap) {
for (Class c : metricMap.keySet()) {
for (List<MetricEntity> dataBatchPartial : Iterables.partition(metricMap.get(c), METRIC_DATA_NUM_DB_OPERATIONS_PER_TRANSACTION)) {
try (final TransactionResource db = Entities.transactionFor(c)) {
int numOperations = 0;
for (MetricEntity me : dataBatchPartial) {
numOperations++;
if (numOperations % METRIC_DATA_NUM_DB_OPERATIONS_UNTIL_SESSION_FLUSH == 0) {
Entities.flushSession(c);
Entities.clearSession(c);
}
Entities.persist(me);
}
db.commit();
}
}
}
}
public static String hash(Map<String, String> dimensionMap) {
TreeMap<String, String> sortedDimensionMap = Maps.newTreeMap();
if (dimensionMap != null) {
sortedDimensionMap.putAll(dimensionMap);
}
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : sortedDimensionMap.entrySet()) {
sb.append(entry.getKey() + "|" + entry.getValue() + "|");
}
return HashUtils.hash(sb);
}
public static String hash(Collection<DimensionEntity> dimensions) {
StringBuilder sb = new StringBuilder();
for (DimensionEntity dimension : dimensions) {
sb.append(dimension.getName() + "|" + dimension.getValue() + "|");
}
return HashUtils.hash(sb);
}
public static void deleteAllMetrics() {
for (Class c : MetricEntityFactory.getAllClassesForEntitiesGet()) {
try (final TransactionResource db = Entities.transactionFor(c)) {
Entities.deleteAll(c);
db.commit();
}
}
}
/**
* Delete all metrics before a certain date
*
* @param before
* the date to delete before (inclusive)
*/
public static void deleteMetrics(Date before) {
for (Class c : MetricEntityFactory.getAllClassesForEntitiesGet()) {
try (final TransactionResource db = Entities.transactionFor(c)) {
Map<String, Date> criteria = new HashMap<String, Date>();
criteria.put("before", before);
Entities.deleteAllMatching(c, "WHERE timestamp < :before", criteria);
db.commit();
}
}
}
public static class GetMetricStatisticsParams {
String accountId;
String metricName;
String namespace;
Map<String, String> dimensionMap;
MetricType metricType;
Units units;
Date startTime;
Date endTime;
Integer period;
Collection<DimensionEntity> dimensions;
String dimensionHash;
public GetMetricStatisticsParams(String accountId, String metricName, String namespace, Map<String, String> dimensionMap, MetricType metricType, Units units, Date startTime, Date endTime, Integer period) {
this.accountId = accountId;
this.metricName = metricName;
this.namespace = namespace;
this.dimensionMap = dimensionMap;
this.metricType = metricType;
this.units = units;
this.startTime = startTime;
this.endTime = endTime;
this.period = period;
this.dimensions = getDimensionsFromMap(dimensionMap);
this.dimensionHash = hash(dimensionMap);
}
private static Collection<DimensionEntity> getDimensionsFromMap(Map<String, String> dimensionMap) {
TreeSet<DimensionEntity> dimensions = new TreeSet<DimensionEntity>();
for (Map.Entry<String, String> entry : dimensionMap.entrySet()) {
DimensionEntity d = new DimensionEntity();
d.setName(entry.getKey());
d.setValue(entry.getValue());
dimensions.add(d);
}
return dimensions;
}
@Override
public String toString() {
return "GetMetricStatisticsParams{" +
"accountId='" + accountId + '\'' +
", metricName='" + metricName + '\'' +
", namespace='" + namespace + '\'' +
", dimensionMap=" + dimensionMap +
", metricType=" + metricType +
", units=" + units +
", startTime=" + startTime +
", endTime=" + endTime +
", period=" + period +
'}';
}
public String getAccountId() {
return accountId;
}
public String getMetricName() {
return metricName;
}
public String getNamespace() {
return namespace;
}
public Map<String, String> getDimensionMap() {
return dimensionMap;
}
public MetricType getMetricType() {
return metricType;
}
public Units getUnits() {
return units;
}
public Date getStartTime() {
return startTime;
}
public Date getEndTime() {
return endTime;
}
public Integer getPeriod() {
return period;
}
public void validate(Date now) {
if (dimensionMap == null) {
dimensionMap = new HashMap<String, String>();
} else if (dimensionMap.size() > AbstractPersistentWithDimensions.MAX_DIM_NUM) {
throw new IllegalArgumentException("Too many dimensions for metric, "
+ dimensionMap.size());
}
if (endTime == null) endTime = now;
if (startTime == null) startTime = new Date(now.getTime() - 60 * 60 * 1000L);
startTime = MetricUtils.stripSeconds(startTime);
endTime = MetricUtils.stripSeconds(endTime);
if (startTime.after(endTime)) {
throw new IllegalArgumentException("Start time must be after end time");
}
if (period == null) {
period = 60;
}
if (period % 60 != 0) {
throw new IllegalArgumentException("Period must be a multiple of 60");
}
if (period < 0) {
throw new IllegalArgumentException("Period must be greater than 0");
}
if (period == 0) {
throw new IllegalArgumentException("Period must not equal 0");
}
if (metricType == null) {
throw new IllegalArgumentException("metricType must not be null");
}
if (accountId == null) {
throw new IllegalArgumentException("accountId must not be null");
}
if (metricName == null) {
throw new IllegalArgumentException("metricName must not be null");
}
if (namespace == null) {
throw new IllegalArgumentException("namespace must not be null");
}
}
public Collection<DimensionEntity> getDimensions() {
return dimensions;
}
public String getDimensionHash() {
return dimensionHash;
}
public GetMetricStatisticsParams() {
}
}
public static List<Collection<MetricStatistics>> getManyMetricStatistics(List<GetMetricStatisticsParams> getMetricStatisticsParamses) {
if (getMetricStatisticsParamses == null) throw new IllegalArgumentException("getMetricStatisticsParamses can not be null");
Date now = new Date();
Map<GetMetricStatisticsParams, Collection<MetricStatistics>> resultMap = Maps.newHashMap();
Multimap<Class, GetMetricStatisticsParams> hashGroupMap = LinkedListMultimap.create();
for (GetMetricStatisticsParams getMetricStatisticsParams : getMetricStatisticsParamses) {
if (getMetricStatisticsParams == null) throw new IllegalArgumentException("getMetricStatisticsParams can not be null");
getMetricStatisticsParams.validate(now);
Class metricEntityClass = MetricEntityFactory.getClassForEntitiesGet(getMetricStatisticsParams.getMetricType(), getMetricStatisticsParams.getDimensionHash());
hashGroupMap.put(metricEntityClass, getMetricStatisticsParams);
}
for (Class metricEntityClass: hashGroupMap.keySet()) {
try (final TransactionResource db = Entities.transactionFor(metricEntityClass)) {
// set some global criteria to start (for narrowing?)
Date minDate = null;
Date maxDate = null;
Junction disjunction = Restrictions.disjunction();
Map<GetMetricStatisticsParams, TreeMap<GetMetricStatisticsAggregationKey, MetricStatistics>> multiAggregationMap = Maps.newHashMap();
for (GetMetricStatisticsParams getMetricStatisticsParams : hashGroupMap.get(metricEntityClass)) {
multiAggregationMap.put(getMetricStatisticsParams, new TreeMap<GetMetricStatisticsAggregationKey, MetricStatistics>(GetMetricStatisticsAggregationKey.COMPARATOR_WITH_NULLS.INSTANCE));
Junction conjunction = Restrictions.conjunction();
conjunction = conjunction.add(Restrictions.lt("timestamp", getMetricStatisticsParams.getEndTime()));
conjunction = conjunction.add(Restrictions.ge("timestamp", getMetricStatisticsParams.getStartTime()));
conjunction = conjunction.add(Restrictions.eq("accountId", getMetricStatisticsParams.getAccountId()));
conjunction = conjunction.add(Restrictions.eq("metricName", getMetricStatisticsParams.getMetricName()));
conjunction = conjunction.add(Restrictions.eq("namespace", getMetricStatisticsParams.getNamespace()));
conjunction = conjunction.add(Restrictions.eq("dimensionHash", hash(getMetricStatisticsParams.getDimensionMap())));
if (getMetricStatisticsParams.getUnits() != null) {
conjunction = conjunction.add(Restrictions.eq("units", getMetricStatisticsParams.getUnits()));
}
disjunction = disjunction.add(conjunction);
if (minDate == null || getMetricStatisticsParams.getStartTime().before(minDate)) {
minDate = getMetricStatisticsParams.getStartTime();
}
if (maxDate == null || getMetricStatisticsParams.getEndTime().after(maxDate)) {
maxDate = getMetricStatisticsParams.getEndTime();
}
}
Criteria criteria = Entities.createCriteria(metricEntityClass);
criteria = criteria.add(Restrictions.lt("timestamp", maxDate));
criteria = criteria.add(Restrictions.ge("timestamp", minDate));
criteria = criteria.add(disjunction);
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.max("sampleMax"));
projectionList.add(Projections.min("sampleMin"));
projectionList.add(Projections.sum("sampleSize"));
projectionList.add(Projections.sum("sampleSum"));
projectionList.add(Projections.groupProperty("units"));
projectionList.add(Projections.groupProperty("timestamp"));
projectionList.add(Projections.groupProperty("accountId"));
projectionList.add(Projections.groupProperty("metricName"));
projectionList.add(Projections.groupProperty("metricType"));
projectionList.add(Projections.groupProperty("namespace"));
projectionList.add(Projections.groupProperty("dimensionHash"));
criteria.setProjection(projectionList);
criteria.addOrder(Order.asc("timestamp"));
ScrollableResults results = criteria.setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);
while (results.next()) {
MetricEntity me = getMetricEntity(results);
for (GetMetricStatisticsParams getMetricStatisticsParams : hashGroupMap.get(metricEntityClass)) {
if (metricDataMatches(getMetricStatisticsParams, me)) {
Map<GetMetricStatisticsAggregationKey, MetricStatistics> aggregationMap = multiAggregationMap.get(getMetricStatisticsParams);
GetMetricStatisticsAggregationKey key = new GetMetricStatisticsAggregationKey(me, getMetricStatisticsParams.getStartTime(), getMetricStatisticsParams.getPeriod(), getMetricStatisticsParams.getDimensionHash());
MetricStatistics item = new MetricStatistics(me, getMetricStatisticsParams.getStartTime(), getMetricStatisticsParams.getPeriod(), getMetricStatisticsParams.getDimensions());
if (!aggregationMap.containsKey(key)) {
aggregationMap.put(key, item);
} else {
MetricStatistics totalSoFar = aggregationMap.get(key);
totalSoFar.setSampleMax(Math.max(item.getSampleMax(), totalSoFar.getSampleMax()));
totalSoFar.setSampleMin(Math.min(item.getSampleMin(), totalSoFar.getSampleMin()));
totalSoFar.setSampleSize(totalSoFar.getSampleSize() + item.getSampleSize());
totalSoFar.setSampleSum(totalSoFar.getSampleSum() + item.getSampleSum());
}
}
}
}
for (GetMetricStatisticsParams getMetricStatisticsParams : multiAggregationMap.keySet()) {
resultMap.put(getMetricStatisticsParams, multiAggregationMap.get(getMetricStatisticsParams).values());
}
}
}
List<Collection<MetricStatistics>> resultList = Lists.newArrayList();
for (GetMetricStatisticsParams getMetricStatisticsParams : getMetricStatisticsParamses) {
if (resultMap.get(getMetricStatisticsParams) == null) {
resultList.add(new ArrayList<MetricStatistics>());
} else {
resultList.add(resultMap.get(getMetricStatisticsParams));
}
}
return resultList;
}
private static boolean metricDataMatches(GetMetricStatisticsParams getMetricStatisticsParams, MetricEntity metricEntity) {
if (getMetricStatisticsParams == null || metricEntity == null) return false;
if (getMetricStatisticsParams.getStartTime() == null || getMetricStatisticsParams.getStartTime().after(metricEntity.getTimestamp())) return false;
if (metricEntity.getTimestamp() == null || !metricEntity.getTimestamp().before(getMetricStatisticsParams.getEndTime())) return false;
if (getMetricStatisticsParams.getAccountId() == null || !getMetricStatisticsParams.getAccountId().equals(metricEntity.getAccountId())) return false;
if (getMetricStatisticsParams.getMetricName() == null || !getMetricStatisticsParams.getMetricName().equals(metricEntity.getMetricName())) return false;
if (getMetricStatisticsParams.getNamespace() == null || !getMetricStatisticsParams.getNamespace().equals(metricEntity.getNamespace())) return false;
if (getMetricStatisticsParams.getMetricType() == null || !getMetricStatisticsParams.getMetricType().equals(metricEntity.getMetricType())) return false;
if (getMetricStatisticsParams.getDimensionHash() == null || !getMetricStatisticsParams.getDimensionHash().equals(metricEntity.getDimensionHash())) return false;
return true;
}
public static Collection<MetricStatistics> getMetricStatistics(GetMetricStatisticsParams getMetricStatisticsParams) {
if (getMetricStatisticsParams == null) throw new IllegalArgumentException("getMetricStatisticsParams can not be null");
Date now = new Date();
getMetricStatisticsParams.validate(now);
Class metricEntityClass = MetricEntityFactory.getClassForEntitiesGet(getMetricStatisticsParams.getMetricType(), getMetricStatisticsParams.getDimensionHash());
Map<GetMetricStatisticsAggregationKey, MetricStatistics> aggregationMap = new TreeMap<GetMetricStatisticsAggregationKey, MetricStatistics>(GetMetricStatisticsAggregationKey.COMPARATOR_WITH_NULLS.INSTANCE);
try (final TransactionResource db = Entities.transactionFor(metricEntityClass)) {
Criteria criteria = Entities.createCriteria(metricEntityClass);
criteria = criteria.add(Restrictions.eq("accountId", getMetricStatisticsParams.getAccountId()));
criteria = criteria.add(Restrictions.eq("metricName", getMetricStatisticsParams.getMetricName()));
criteria = criteria.add(Restrictions.eq("namespace", getMetricStatisticsParams.getNamespace()));
criteria = criteria.add(Restrictions.lt("timestamp", getMetricStatisticsParams.getEndTime()));
criteria = criteria.add(Restrictions.ge("timestamp", getMetricStatisticsParams.getStartTime()));
criteria = criteria.add(Restrictions.eq("dimensionHash", getMetricStatisticsParams.getDimensionHash()));
if (getMetricStatisticsParams.getUnits() != null) {
criteria = criteria.add(Restrictions.eq("units", getMetricStatisticsParams.getUnits()));
}
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.max("sampleMax"));
projectionList.add(Projections.min("sampleMin"));
projectionList.add(Projections.sum("sampleSize"));
projectionList.add(Projections.sum("sampleSum"));
projectionList.add(Projections.groupProperty("units"));
projectionList.add(Projections.groupProperty("timestamp"));
criteria.setProjection(projectionList);
criteria.addOrder(Order.asc("timestamp"));
ScrollableResults results = criteria.setCacheMode(CacheMode.IGNORE).scroll(ScrollMode.FORWARD_ONLY);
while (results.next()) {
MetricEntity me = getMetricEntity(getMetricStatisticsParams.getAccountId(), getMetricStatisticsParams.getMetricName(), getMetricStatisticsParams.getNamespace(), getMetricStatisticsParams.getMetricType(), getMetricStatisticsParams.getDimensionHash(), results);
GetMetricStatisticsAggregationKey key = new GetMetricStatisticsAggregationKey(me, getMetricStatisticsParams.getStartTime(), getMetricStatisticsParams.getPeriod(), getMetricStatisticsParams.getDimensionHash());
MetricStatistics item = new MetricStatistics(me, getMetricStatisticsParams.getStartTime(), getMetricStatisticsParams.getPeriod(), getMetricStatisticsParams.getDimensions());
if (!aggregationMap.containsKey(key)) {
aggregationMap.put(key, item);
} else {
MetricStatistics totalSoFar = aggregationMap.get(key);
totalSoFar.setSampleMax(Math.max(item.getSampleMax(), totalSoFar.getSampleMax()));
totalSoFar.setSampleMin(Math.min(item.getSampleMin(), totalSoFar.getSampleMin()));
totalSoFar.setSampleSize(totalSoFar.getSampleSize() + item.getSampleSize());
totalSoFar.setSampleSum(totalSoFar.getSampleSum() + item.getSampleSum());
}
}
}
return Lists.newArrayList(aggregationMap.values());
}
private static MetricEntity getMetricEntity(ScrollableResults results) {
Double sampleMax = (Double) results.get(0);
Double sampleMin = (Double) results.get(1);
Double sampleSize = (Double) results.get(2);
Double sampleSum = (Double) results.get(3);
Units resultUnits = (Units) results.get(4);
Date timestamp = (Date) results.get(5);
String accountId = (String) results.get(6);
String metricName = (String) results.get(7);
MetricType metricType = (MetricType) results.get(8);
String namespace = (String) results.get(9);
String hash = (String) results.get(10);
MetricEntity me = MetricEntityFactory.getNewMetricEntity(metricType, hash);
me.setAccountId(accountId);
me.setNamespace(namespace);
me.setMetricName(metricName);
me.setMetricType(metricType);
me.setDimensionHash(hash);
me.setSampleMax(sampleMax);
me.setSampleMin(sampleMin);
me.setSampleSize(sampleSize);
me.setSampleSum(sampleSum);
me.setTimestamp(timestamp);
me.setUnits(resultUnits);
return me;
}
private static MetricEntity getMetricEntity(String accountId, String metricName, String namespace, MetricType metricType, String hash, ScrollableResults results) {
Double sampleMax = (Double) results.get(0);
Double sampleMin = (Double) results.get(1);
Double sampleSize = (Double) results.get(2);
Double sampleSum = (Double) results.get(3);
Units resultUnits = (Units) results.get(4);
Date timestamp = (Date) results.get(5);
MetricEntity me = MetricEntityFactory.getNewMetricEntity(metricType, hash);
me.setAccountId(accountId);
me.setNamespace(namespace);
me.setMetricName(metricName);
me.setMetricType(metricType);
me.setDimensionHash(hash);
me.setSampleMax(sampleMax);
me.setSampleMin(sampleMin);
me.setSampleSize(sampleSize);
me.setSampleSum(sampleSum);
me.setTimestamp(timestamp);
me.setUnits(resultUnits);
return me;
}
public static Collection<MetricEntity> getAllMetrics() {
ArrayList<MetricEntity> allResults = new ArrayList<MetricEntity>();
for (Class c : MetricEntityFactory.getAllClassesForEntitiesGet()) {
try (final TransactionResource db = Entities.transactionFor(c)) {
Criteria criteria = Entities.createCriteria(c);
criteria = criteria.addOrder( Order.asc("timestamp") );
criteria = criteria.addOrder( Order.asc("id") );
Collection dbResults = criteria.list();
for (Object result : dbResults) {
allResults.add((MetricEntity) result);
}
db.commit();
}
}
return allResults;
}
public static void addMetricBatch(List<SimpleMetricEntity> dataBatch) {
ArrayList<MetricEntity> metricEntities = new ArrayList<MetricEntity>();
for (SimpleMetricEntity simpleMetricEntity: dataBatch) {
validateMetricQueueItem(simpleMetricEntity);
metricEntities.addAll(hash(simpleMetricEntity));
}
addManyMetrics(makeMetricMap(metricEntities));
}
private static void validateMetricQueueItem(SimpleMetricEntity simpleMetricEntity) {
LOG.trace("metricName="+simpleMetricEntity.getMetricName());
LOG.trace("namespace="+simpleMetricEntity.getNamespace());
LOG.trace("dimensionMap="+simpleMetricEntity.getDimensionMap());
LOG.trace("metricType="+simpleMetricEntity.getMetricType());
LOG.trace("units="+simpleMetricEntity.getUnits());
LOG.trace("timestamp="+simpleMetricEntity.getTimestamp());
LOG.trace("sampleSize="+simpleMetricEntity.getSampleSize());
LOG.trace("sampleMax="+simpleMetricEntity.getSampleMax());
LOG.trace("sampleMin="+simpleMetricEntity.getSampleMin());
LOG.trace("sampleSum="+simpleMetricEntity.getSampleSum());
if (simpleMetricEntity.getDimensionMap() == null) {
simpleMetricEntity.setDimensionMap(new HashMap<String, String>());
} else if (simpleMetricEntity.getDimensionMap().size() > AbstractPersistentWithDimensions.MAX_DIM_NUM) {
throw new IllegalArgumentException("Too many dimensions for metric, "
+ simpleMetricEntity.getDimensionMap().size());
}
simpleMetricEntity.setTimestamp(MetricUtils.stripSeconds(simpleMetricEntity.getTimestamp()));
}
}