All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.anotheria.moskito.webui.accumulators.api.AccumulatorAPIImpl Maven / Gradle / Ivy

There is a newer version: 4.0.3
Show newest version
package net.anotheria.moskito.webui.accumulators.api;

import net.anotheria.anoplass.api.APIException;
import net.anotheria.moskito.core.accumulation.AccumulatedValue;
import net.anotheria.moskito.core.accumulation.Accumulator;
import net.anotheria.moskito.core.accumulation.AccumulatorDefinition;
import net.anotheria.moskito.core.accumulation.AccumulatorRepository;
import net.anotheria.moskito.core.config.MoskitoConfigurationHolder;
import net.anotheria.moskito.core.stats.TimeUnit;
import net.anotheria.moskito.webui.accumulators.bean.AccumulatedValuesBean;
import net.anotheria.moskito.webui.shared.api.AbstractMoskitoAPIImpl;
import net.anotheria.util.NumberUtils;
import net.anotheria.util.sorter.DummySortType;
import net.anotheria.util.sorter.SortType;
import net.anotheria.util.sorter.StaticQuickSorter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Implementation of the AccumulatorAPI.
 *
 * @author lrosenberg
 * @since 13.02.13 18:13
 */
public class AccumulatorAPIImpl extends AbstractMoskitoAPIImpl implements AccumulatorAPI {

	/**
	 * This constant is used to put different timestamp in context.
	 */
	private static final long MINUTE = 1000L*60;

	/**
	 * Object for caching of the sort types.
	 */
	private static final SortType SORT_TYPE = new DummySortType();

	@Override
	public AccumulatorDefinitionAO createAccumulator(AccumulatorPO po) throws APIException{
		if (po.getName() == null || po.getName().equals(""))
			throw new APIException("Can't create accumulator without a name.");
		AccumulatorDefinition ad = new AccumulatorDefinition();
		ad.setName(po.getName());
		ad.setProducerName(po.getProducerId());
		ad.setStatName(po.getStatName());
		ad.setValueName(po.getValueName());
		ad.setIntervalName(po.getInterval());
		if (po.getUnit()==null || po.getUnit().length()==0)
			ad.setTimeUnit(TimeUnit.MILLISECONDS); //set to default
		else
			ad.setTimeUnit(TimeUnit.fromString(po.getUnit()));
		Accumulator acc = AccumulatorRepository.getInstance().createAccumulator(ad);
		return getAccumulatorDefinition(acc.getId());
	}

	@Override
	public void removeAccumulator(String id) throws APIException {
		AccumulatorRepository.getInstance().removeById(id);
	}

	@Override public AccumulatorAO getAccumulator(String id) throws APIException{
		return new AccumulatorAO(AccumulatorRepository.getInstance().getById(id));
	}

	@Override public AccumulatorAO getAccumulatorByName(String name) throws APIException{
		Accumulator acc = AccumulatorRepository.getInstance().getByName(name);
		if (acc==null)
			throw new IllegalArgumentException("Attempt to access non existing accumulator with name: '" +name+ '\'');
		return new AccumulatorAO(acc);
	}

	public AccumulatorDefinitionAO getAccumulatorDefinition(String accId) throws APIException{
		Accumulator a = AccumulatorRepository.getInstance().getById(accId);
		AccumulatorDefinitionAO bean = new AccumulatorDefinitionAO();

		bean.setName(a.getName());
		bean.setPath(a.getDefinition().describe());
		bean.setId(a.getId());
		List values = a.getValues();
		if (values!=null && values.size()>0){
			bean.setNumberOfValues(values.size());
			bean.setLastValueTimestamp(values.get(values.size()-1).getISO8601Timestamp());
		}else{
			bean.setNumberOfValues(0);
			bean.setLastValueTimestamp("none");
		}
		return bean;
	}

	@Override
	public AccumulatedSingleGraphAO getAccumulatorGraphData(String id) throws APIException {
		Accumulator accumulator = AccumulatorRepository.getInstance().getById(id);
		AccumulatedSingleGraphAO singleGraphDataBean = new AccumulatedSingleGraphAO(accumulator.getName());
		singleGraphDataBean.setData(new AccumulatorAO(accumulator).getValues());
		singleGraphDataBean.setColor(MoskitoConfigurationHolder.getConfiguration().getAccumulatorsConfig().getAccumulatorColor(accumulator.getName()));
		return singleGraphDataBean;
	}

	@Override
	public AccumulatedSingleGraphAO getAccumulatorGraphDataByName(String name) throws APIException {
		return getAccumulatorGraphData(AccumulatorRepository.getInstance().getByName(name).getId());
	}

	@Override
	public List getAccumulatorDefinitions() throws APIException {
		List accumulators = AccumulatorRepository.getInstance().getAccumulators();
		List ret = new ArrayList<>(accumulators.size());

		for (Accumulator a : accumulators){
			AccumulatorDefinitionAO bean = new AccumulatorDefinitionAO();

			bean.setName(a.getName());
			bean.setPath(a.getDefinition().describe());
			bean.setId(a.getId());
			bean.setMaxNumberOfValues(a.getDefinition().getMaxAmountOfAccumulatedItems());
			List values = a.getValues();
			if (values!=null && values.size()>0){
				bean.setNumberOfValues(values.size());
				bean.setLastValueTimestamp(values.get(values.size()-1).getISO8601Timestamp());
			}else{
				bean.setNumberOfValues(0);
				bean.setLastValueTimestamp("none");
			}

			ret.add(bean);
		}

		ret = StaticQuickSorter.sort(ret, SORT_TYPE);
		return ret;

	}

	@Override
	public MultilineChartAO getNormalizedAccumulatorGraphData(List ids) throws APIException {
		return getAccumulatorGraphData(ids, true);
	}

	@Override
	public MultilineChartAO getCombinedAccumulatorGraphData(List ids) throws APIException {
		return getAccumulatorGraphData(ids, false);
	}

	public MultilineChartAO getAccumulatorGraphData(List ids, boolean normalized) throws APIException {

		int normalizeBase = 100;
		//TODO actually this limit is hardcoded, we should make it dynamic.
		int maxValues = 200;

		int numberOfIds = ids.size();
		if (numberOfIds == 0) {
			throw new APIException("No accumulators selected");
		}

		List singleGraphDataBeans = new ArrayList<>(numberOfIds);

		//prepare values
		Map values = new HashMap<>(numberOfIds);
		List accNames = new ArrayList<>(numberOfIds);

		for (String id : ids){
			AccumulatorAO acc = getAccumulator(id);
			AccumulatedSingleGraphAO singleGraphDataBean = getAccumulatorGraphData(id);
			singleGraphDataBeans.add(singleGraphDataBean);

			accNames.add(acc.getName());
			List accValues = acc.getValues();
			for (AccumulatedValueAO v : accValues){
				long timestamp = v.getNumericTimestamp();
				timestamp = timestamp /  MINUTE * MINUTE;
				AccumulatedValuesBean bean = values.get(timestamp);
				if (bean==null){
					bean = new AccumulatedValuesBean(timestamp);
					values.put(timestamp, bean);
				}
				bean.setValue(acc.getName(), v.getFirstValue());

			}
		}
		List valuesList = StaticQuickSorter.sort(values.values(), SORT_TYPE);

		//now check if the data is complete
		//Stores last known values to allow filling in of missing values (combining 1m and 5m values)
		Map lastValue = new HashMap<>(accNames.size());

		//filling last (or first) values.
		for (String accName : accNames){
			//first put 'some' initial value.
			lastValue.put(accName, "0");
			//now search for first non-null value
			for(AccumulatedValuesBean accValueBean : valuesList){
				String aValue = accValueBean.getValue(accName);
				if (aValue!=null){
					lastValue.put(accName, aValue);
					break;
				}
			}
		}

		for(AccumulatedValuesBean accValueBean : valuesList){
			for (String accName : accNames){
				String value = accValueBean.getValue(accName);
				if (value==null){
					accValueBean.setValue(accName, lastValue.get(accName));
				}else{
					lastValue.put(accName, value);
				}
			}
		}

		if (normalized){
			normalize(valuesList, accNames, normalizeBase);
		}

		//now create final data
		List dataBeans = new ArrayList<>(valuesList.size());
		for(AccumulatedValuesBean avb : valuesList){
			AccumulatedValueAO bean = new AccumulatedValueAO(avb.getTime());
			bean.setIsoTimestamp(NumberUtils.makeISO8601TimestampString(avb.getTimestamp()));
			bean.setNumericTimestamp(avb.getTimestamp());

			for (String accName : accNames){
				bean.addValue(avb.getValue(accName));
			}
			dataBeans.add(bean);
		}

		//generally its not always a good idea to use subList, but since that list isn't reused,
		//as in subList or subList of subList, its ok.
		if (dataBeans.size()>maxValues) {
			List shorterList = new ArrayList(dataBeans.subList(dataBeans.size() - maxValues, dataBeans.size()));
			dataBeans = shorterList;
		}

		MultilineChartAO ret = new MultilineChartAO();
		ret.setData(dataBeans);
		ret.setNames(accNames);
		ret.setSingleGraphAOs(singleGraphDataBeans);
		return ret;
	}


	/*test visibility */ static void normalize(List values, List names, int limit){
		for (String name : names){
			//System.out.println("normalizing "+name);
			ArrayList valueCopy = new ArrayList(values.size());
			//step1 transform everything to float
			float min = Float.MAX_VALUE, max = Float.MIN_VALUE;
			for (AccumulatedValuesBean v : values){
				float val = Float.parseFloat(v.getValue(name));
				if (val>max)
					max = val;
				if (val getChartsForMultipleAccumulators(List names) throws APIException {
		LinkedList ret = new LinkedList<>();
		for (String name : names){
			ret.add(getAccumulatorGraphDataByName(name));
		}
		return ret;
	}

	@Override
	public List getAccumulatorIdsTiedToASpecificProducer(String producerId) throws APIException {
		return AccumulatorRepository.getInstance().getIdsByProducerId(producerId);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy