Package org.eurekaj.plugins.riak.dao

Source Code of org.eurekaj.plugins.riak.dao.RiakLiveStatisticsDao

package org.eurekaj.plugins.riak.dao;

import com.basho.riak.client.IRiakClient;
import com.basho.riak.client.RiakException;
import com.basho.riak.client.RiakRetryFailedException;
import com.basho.riak.client.bucket.Bucket;
import com.google.common.cache.Cache;
import org.apache.log4j.Logger;
import org.eurekaj.api.dao.LiveStatisticsDao;
import org.eurekaj.api.datatypes.LiveStatistics;
import org.eurekaj.api.datatypes.LiveStatisticsUtil;
import org.eurekaj.api.datatypes.basic.BasicLiveStatistics;
import org.eurekaj.api.datatypes.basic.BasicMetricHour;
import org.eurekaj.api.enumtypes.UnitType;
import org.eurekaj.api.enumtypes.ValueType;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
* Created with IntelliJ IDEA.
* User: joahaa
* Date: 3/3/13
* Time: 1:43 AM
* To change this template use File | Settings | File Templates.
*/
public class RiakLiveStatisticsDao implements LiveStatisticsDao {
    private static Logger logger = Logger.getLogger(RiakLiveStatisticsDao.class.getName());

    private IRiakClient riakClient;
    private Cache<String, BasicMetricHour> metricHourCache;
    private Hashtable<String, BasicMetricHour> metricHoursToStoreHash;
    private long metricHoursLastPersited = 0;
    private ExecutorService storageThreadPool = Executors.newFixedThreadPool(8);

    public RiakLiveStatisticsDao(IRiakClient riakClient, Cache<String, BasicMetricHour> metricHourCache) {
        this.riakClient = riakClient;
        this.metricHourCache = metricHourCache;
        this.metricHoursToStoreHash  = new Hashtable<String, BasicMetricHour>();
    }

    @Override
    public void storeIncomingStatistics(String guiPath, String accountName, Long timeperiod, String value, ValueType valueType, UnitType unitType, Long count) {
        Double valueDouble = LiveStatisticsUtil.parseDouble(value);
        long hoursSince1970 = timeperiod / 240;

        Bucket myBucket = null;
        try {
            myBucket = riakClient.fetchBucket(accountName + ";" + hoursSince1970).execute();
            BasicMetricHour storedMetricHour = myBucket.fetch("" + guiPath, BasicMetricHour.class).execute();
            if (storedMetricHour == null) {
                storedMetricHour = new BasicMetricHour(guiPath, accountName, hoursSince1970, valueType.toString(), unitType.toString());
            }

            storedMetricHour.addStatistic(new BasicLiveStatistics(guiPath, accountName, timeperiod, valueDouble, valueType.value(), unitType.value(), count));

            myBucket.store("" + guiPath, storedMetricHour).execute();
        } catch (RiakRetryFailedException e) {
            e.printStackTrace()//To change body of catch statement use File | Settings | File Templates.
        }
    }

    private BasicMetricHour getMetricHour(String accountName, String guiPath, long hoursSince1970) {
        //logger.info("getting Metric Hour for account: " + accountName + " guiPath: " + guiPath + " ts: " + hoursSince1970);
        BasicMetricHour metricHour = null;

        Bucket mhBucket = null;
        try {
            mhBucket = riakClient.fetchBucket(accountName + ";" + hoursSince1970).execute();
            metricHour = mhBucket.fetch("" + guiPath, BasicMetricHour.class).execute();
            logger.info("finding: " + accountName + ";" + hoursSince1970 + "/" + guiPath);
            if (metricHour != null) {
                metricHourCache.put(
                        metricHour.getAccountName() + ";" + metricHour.getGuiPath() + ";" + metricHour.getHoursSince1970(),
                        metricHour
                );
            }
        } catch (RiakRetryFailedException rrfe) {
            rrfe.printStackTrace();
        }

        return metricHour;
    }

    private void persistRecentMetricHours() {
        if ((System.currentTimeMillis() - metricHoursLastPersited) > 5000) {
            //Persist metric hours received in the last 10 seconds

            List<BasicMetricHour> listOne = new ArrayList<BasicMetricHour>();
            listOne.addAll(metricHoursToStoreHash.values());

            storageThreadPool.submit(new StoreMetricHourListThread(listOne, riakClient));
            //storageThreadPool.submit(new StoreMetricHourListThread(listTwo, riakClient));
            //storageThreadPool.submit(new StoreMetricHourListThread(listThree, riakClient));
            //storageThreadPool.submit(new StoreMetricHourListThread(listFour, riakClient));

            logger.info("Persisting metric hours received in the last 5 seconds in 4 threads: " + metricHoursToStoreHash.size());

            metricHoursToStoreHash.clear();
            metricHoursLastPersited = System.currentTimeMillis();
        }
    }

    @Override
    public void storeIncomingStatistics(List<LiveStatistics> liveStatisticsList) {
        for (LiveStatistics ls : liveStatisticsList) {
            long hoursSince1970 = ls.getTimeperiod() / 240;
           
            BasicMetricHour mhToStore = metricHoursToStoreHash.get(ls.getAccountName() + ";" + ls.getGuiPath() + ";" + hoursSince1970);
            boolean wasInStoreHash = mhToStore != null;

            if (mhToStore == null) {
                //Not in store-hash chech in metricHourCache
                mhToStore = metricHourCache.getIfPresent(ls.getAccountName() + ";" + ls.getGuiPath() + ";" + hoursSince1970);
            }

            if (mhToStore == null) {
                //Not in metricHourCache, fetch from Riak
                mhToStore = getMetricHour(ls.getAccountName(), ls.getGuiPath(), hoursSince1970);
            }

            if (mhToStore == null) {
                //Not in Riak, create
                mhToStore = new BasicMetricHour(ls.getGuiPath(), ls.getAccountName(), hoursSince1970, ls.getValueType(), ls.getUnitType());
            }

            mhToStore.addStatistic(ls);
           
            if (!wasInStoreHash) {
                metricHoursToStoreHash.put(ls.getAccountName() + ";" + ls.getGuiPath() + ";" + hoursSince1970, mhToStore);
            }
        }

        persistRecentMetricHours();
    }

    @Override
    public List<LiveStatistics> getLiveStatistics(String guiPath, String accountName, Long minTimeperiod, Long maxTimeperiod) {
        Long fromHoursSince1970 = minTimeperiod / 240;
        Long toHoursSince1970 = maxTimeperiod / 240;

        List<LiveStatistics> retList = new ArrayList<LiveStatistics>();

        for (Long index = fromHoursSince1970; index <= toHoursSince1970; index++) {
            BasicMetricHour metricHour = getMetricHour(accountName, guiPath, index);
            if (metricHour == null) {
                metricHour = new BasicMetricHour(guiPath, accountName, index, ValueType.VALUE.value(), UnitType.N.value());
            }

            //If this is the first hour, start from the correct 15-second timeslot within the hour
            Integer minTimeperiodWithinTheHour = 0;
            if (index.longValue() == fromHoursSince1970.longValue()) {
                minTimeperiodWithinTheHour = LiveStatisticsUtil.getFifteensecondTimeperiodsSinceStartOfHour(minTimeperiod * 15);
            }

            //If this is the last hour, end with the correct 15-second timeslot within the hour
            Integer maxTimeperiodWithinTheHour = null;
            if (index.longValue() == toHoursSince1970.longValue()) {
                maxTimeperiodWithinTheHour = LiveStatisticsUtil.getFifteensecondTimeperiodsSinceStartOfHour(maxTimeperiod * 15);
            }

            retList.addAll(createLivestatisticsFromMetricHour(metricHour, minTimeperiodWithinTheHour, maxTimeperiodWithinTheHour, index));
        }

        return retList;
    }

    private List<LiveStatistics> createLivestatisticsFromMetricHour(BasicMetricHour metricHour, Integer minTimeperiodWithinTheHour, Integer maxTimeperiodWithinTheHour, Long hoursSince1970) {
        List<LiveStatistics> retList = new ArrayList<LiveStatistics>();

        if (maxTimeperiodWithinTheHour == null) {
            maxTimeperiodWithinTheHour = 239;
        }

        for (int index = minTimeperiodWithinTheHour; index <= maxTimeperiodWithinTheHour; index++) {
            Long timeperiod = (hoursSince1970 * 240) + index;

            //logger.info("Creating LiveStats for: " + metricHour.getId() + " with value: " + metricHour.getValueAt(index));
            retList.add(new BasicLiveStatistics(metricHour.getGuiPath(), metricHour.getAccountName(), timeperiod, metricHour.getMetrics()[index], metricHour.getValueType(), metricHour.getUnitType(), metricHour.getMeasurementCount()[index]));
        }

        return retList;
    }

    @Override
    public void deleteLiveStatisticsOlderThan(Date date, String accountName) {
        Long fromHoursSince1970 = date.getTime() / (15000 * 240);
        Long toHoursSince1970 = new Date().getTime() / (15000 * 240);
        logger.info("hoursSince1970: " + fromHoursSince1970);
        logger.info("toSince1970: " + toHoursSince1970);

        try {

            for (int index = fromHoursSince1970.intValue(); index <= toHoursSince1970.intValue(); index++) {
                int keys = 0;
                Bucket hourBucket = riakClient.fetchBucket(accountName + ";" + index).execute();
                try {
                    for (String key : hourBucket.keys()) {
                        hourBucket.delete(key);
                        keys++;
                    }
                } catch (RiakException e) {
                    e.printStackTrace()//To change body of catch statement use File | Settings | File Templates.
                }

                logger.info("deleted all keys(" + keys + ") in bucket: " + accountName + ";" + index);
            }

        } catch (RiakRetryFailedException rrfe) {
            rrfe.printStackTrace();
        }


        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void deleteLiveStatisticsBetween(String guiPath, String accountName, Long fromTimeperiod, Long toTimeperiod) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void markLiveStatisticsAsCalculated(String guiPath, String accountName, String timeperiod) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void markLiveStatisticsAsCalculated(String guiPath, String accountName, Long minTimeperiod, Long maxTimeperiod) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void deleteMarkedLiveStatistics() {
        //To change body of implemented methods use File | Settings | File Templates.
    }
}
TOP

Related Classes of org.eurekaj.plugins.riak.dao.RiakLiveStatisticsDao

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.