com.linuxbox.enkive.statistics.consolidation.AbstractConsolidator.java Source code

Java tutorial

Introduction

Here is the source code for com.linuxbox.enkive.statistics.consolidation.AbstractConsolidator.java

Source

/*******************************************************************************
 * Copyright 2013 The Linux Box Corporation.
 * 
 * This file is part of Enkive CE (Community Edition).
 * Enkive CE is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * 
 * Enkive CE 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 Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public
 * License along with Enkive CE. If not, see
 * <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package com.linuxbox.enkive.statistics.consolidation;

import static com.linuxbox.enkive.statistics.consolidation.ConsolidationConstants.CONSOLIDATION_AVG;
import static com.linuxbox.enkive.statistics.consolidation.ConsolidationConstants.CONSOLIDATION_MAX;
import static com.linuxbox.enkive.statistics.consolidation.ConsolidationConstants.CONSOLIDATION_MIN;
import static com.linuxbox.enkive.statistics.consolidation.ConsolidationConstants.CONSOLIDATION_SUM;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;

import com.linuxbox.enkive.statistics.ConsolidationKeyHandler;
import com.linuxbox.enkive.statistics.services.StatsClient;

@SuppressWarnings("unchecked")
public abstract class AbstractConsolidator implements Consolidator {
    protected final static Log LOGGER = LogFactory
            .getLog("com.linuxbox.enkive.statistics.granularity.AbstractGrain");
    protected StatsClient client;
    protected Date endDate;
    protected Integer filterType;
    protected int consolidationType;
    protected boolean isEmbedded;
    protected Date startDate;

    public AbstractConsolidator(StatsClient client) {
        this.client = client;
        setDates();
        setTypes();
    }

    public void storeConsolidatedData() {
        client.storeData(consolidateData());
    }

    /**
     * Builds a map that cooresponds to the consolidation methods
     * 
     * @param method
     *            - the method to use
     * @param exampleData
     *            - an example data object (for type consistancy after
     *            consolidation)
     * @param statsMaker
     *            - the pre-populated DescriptiveStatstistics object to pull
     *            stats from
     * @param statData
     *            - the map to populate with consolidated data
     */
    public void methodMapBuilder(String method, DescriptiveStatistics statsMaker, Map<String, Object> statData) {
        if (method.equals(CONSOLIDATION_SUM)) {
            statData.put(method, statsMaker.getSum());
        } else if (method.equals(CONSOLIDATION_MAX)) {
            statData.put(method, statsMaker.getMax());
        } else if (method.equals(CONSOLIDATION_MIN)) {
            statData.put(method, statsMaker.getMin());
        } else if (method.equals(CONSOLIDATION_AVG)) {
            statData.put(method, statsMaker.getMean());
        }
    }

    @Override
    public abstract List<Map<String, Object>> consolidateData();

    /**
     * this method recurses through a given template map to add consolidated
     * data to a new map as defined by each key's ConsolidationDefinition
     * 
     * @param templateData
     *            - the map used to trace
     * @param consolidatedMap
     *            - the map being built
     * @param path
     *            - the path to variables being used for trace
     * @param statKeys
     *            - the list of a gatherer's consolidation definitions
     * @param gathererData
     *            - all the data cooresponding to a given gatherer
     * @return returns the built consolidatedMap variable
     */
    protected Map<String, Object> generateConsolidatedMap(Map<String, Object> templateData,
            Map<String, Object> consolidatedMap, LinkedList<String> path, List<ConsolidationKeyHandler> statKeys,
            List<Map<String, Object>> gathererData) {
        for (String key : templateData.keySet()) {
            path.addLast(key);
            ConsolidationKeyHandler matchingDef = findMatchingPath(path, statKeys);
            if (matchingDef != null) {
                consolidateMaps(consolidatedMap, gathererData, matchingDef, path);
            } else {
                if (templateData.get(key) instanceof Map) {
                    generateConsolidatedMap((Map<String, Object>) templateData.get(key), consolidatedMap, path,
                            statKeys, gathererData);
                }
            }
            path.removeLast();

        }
        return consolidatedMap;
    }

    /**
     * this method takes a map and a path and uses the path to trace down the
     * map to a data object it then returns that data
     * 
     * @param dataMap
     *            - the map the data will be extracted from
     * @param path
     *            - the path to traced on
     * @return the found data object or null if path does not work
     */
    protected Object getDataVal(Map<String, Object> dataMap, List<String> path) {
        Object map = dataMap;
        for (String key : path) {
            if (((Map<String, Object>) map).containsKey(key)) {
                if (((Map<String, Object>) map).get(key) instanceof Map) {
                    map = ((Map<String, Object>) map).get(key);
                } else {
                    return ((Map<String, Object>) map).get(key);
                }
            }
        }
        return null;
    }

    /**
     * determines if a path matches any of the ConsolidationDefinitions for a
     * given gatherer it does this by comparing each of the path's strings to
     * each of the definition's strings asterisks are considered 'any' and are
     * skipped
     * 
     * @param path
     *            - the path to be checked
     * @param keys
     *            - the gatherer's consolidation definitions
     * @return if it finds a matching path it returns the corresponding
     *         ConsolidationDefinition if not it returns null
     */
    private ConsolidationKeyHandler findMatchingPath(List<String> path, List<ConsolidationKeyHandler> keys) {
        for (ConsolidationKeyHandler def : keys) {// get one key definition
            if (def.getMethods() == null) {
                continue;
            }
            boolean isMatch = true;
            int pathIndex = 0;
            int defIndex = 0;
            String keyStr;
            String pathStr;
            List<String> keyString = def.getKey();
            if (keyString.size() > path.size()) {
                isMatch = false;
                continue;
            }

            while (pathIndex < path.size()) {
                if (defIndex >= keyString.size()) {
                    isMatch = false;
                    break;
                }

                while (keyString.get(defIndex).equals("*") && defIndex < keyString.size()) {
                    if (defIndex == keyString.size() - 1) {
                        if (keyString.get(defIndex).equals("*")) {
                            if (defIndex == path.size() - 1) {
                                return def;
                            } else {
                                isMatch = false;
                                break;
                            }
                        }
                    } else {
                        defIndex++;
                        pathIndex++;
                        keyStr = keyString.get(defIndex);
                        pathStr = path.get(pathIndex);
                    }
                }
                if (pathIndex >= path.size()) {
                    isMatch = false;
                    break;
                }

                keyStr = keyString.get(defIndex);
                pathStr = path.get(pathIndex);

                if (keyStr.equals(pathStr)) {
                    pathIndex++;
                    defIndex++;
                } else {
                    isMatch = false;
                    break;
                }
            }
            if (isMatch) {
                return def;
            }
        }
        return null;
    }

    /**
     * this method takes a data object and inserts it at the end of a path on a
     * given map
     * 
     * @param path
     *            - the path to traverse
     * @param statsData
     *            - the map to insert data into
     * @param dataToAdd
     *            - the data to insert
     */
    protected void putOnPath(List<String> path, Map<String, Object> statsData, Map<String, Object> dataToAdd) {
        Map<String, Object> cursor = statsData;
        int index = 0;
        for (String key : path) {
            if (index == path.size() - 1) {
                cursor.put(key, dataToAdd);
            } else if (cursor.containsKey(key)) {
                if (cursor.get(key) instanceof Map) {
                    cursor = (Map<String, Object>) cursor.get(key);
                } else {
                    // TODO create the missing intervening maps
                    LOGGER.error("Path does not exist");
                    break;
                }
            }
            index++;
        }
    }

    public abstract List<List<Map<String, Object>>> gathererFilter(String gathererName);

    /**
     * converts a statistic object into a double
     * 
     * @param stat
     *            the statistic object to convert
     * @return a double representing the statistic object
     */
    protected double statToDouble(Object stat) {
        double input = -1;
        if (stat instanceof Integer) {
            input = (double) ((Integer) stat).intValue();
        } else if (stat instanceof Long) {
            input = (double) ((Long) stat).longValue();
        } else if (stat instanceof Double) {
            input = ((Double) stat).doubleValue();
        } else if (stat instanceof Date) {
            input = (double) ((Long) ((Date) stat).getTime()).longValue();
        } else {
            LOGGER.warn("statToDouble(Object stat)-unexpected Object type");
        }
        return input;
    }

    public abstract void setDates();

    public void setDates(Date upperDate, Date lowerDate) {
        this.startDate = lowerDate;
        this.endDate = upperDate;
    }

    public abstract void setTypes();

    public void setTypes(int consolidationType, Integer filterType) {
        this.consolidationType = consolidationType;
        this.filterType = filterType;
    }

    /**
     * This method gets consolidated data from the service data and inserts it
     * into the consolidateData map argument.
     * 
     * @param consolidatedData
     *            map to insert consolidated Data into (must have valid
     *            dataPath) if the path has data at the end it will be
     *            overwritten
     * @param serviceData
     *            - all data relating to a service
     * @param keyDef
     *            - defines the consolidation methods to use on the serviceData
     * @param dataPath
     *            - the path on which to store the data in the consolidatedMap
     */
    protected abstract void consolidateMaps(Map<String, Object> consolidatedData,
            List<Map<String, Object>> serviceData, ConsolidationKeyHandler keyDef, LinkedList<String> dataPath);
}