Package org.wso2.carbon.usage.agent.persist

Source Code of org.wso2.carbon.usage.agent.persist.PersistenceManager$Summarizer

/*
* Copyright (c) 2008, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wso2.carbon.usage.agent.persist;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.usage.agent.beans.BandwidthUsage;
import org.wso2.carbon.usage.agent.exception.UsageException;
import org.wso2.carbon.usage.agent.util.PublisherUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

public class PersistenceManager {

    private static Log log = LogFactory.getLog(PersistenceManager.class);

    // queue to store Bandwidth usage statistics.
    // usage of  LinkedBlockingQueue ensures operations on the queue to wait for the queue to be non
    // empty when retrieving and wait for space when storing element.
    private Queue<BandwidthUsage> jobQueue = new LinkedBlockingQueue<BandwidthUsage>();


    /**
     * this method instantiates and starts a thread to persist  bandwidth usage statistics
     */
    public void startPersisting() {
        new Thread() {
            public void run() {
                // thread runs as long as it is not interrupted and sleeps for 10 seconds
                while (true) {

                    // check whether the jobQueue is  not empty
                    if (!jobQueue.isEmpty()) {
                        try {
                            // if JobQueue is not empty persist usage
                            persistUsage();
                        } catch (UsageException e) {
                            log.error("Error when persisting bandwidth usage statistics", e);
                        }
                    }

                    // return from while loop if the thread is interrupted
                    if (isInterrupted()) {
                        break;
                    }

                    // let the thread sleep for 10 seconds
                    try {
                        sleep(10 * 1000);
                    } catch (InterruptedException e) {

                        if (jobQueue == null || jobQueue.isEmpty()) {
                            break;
                        }
                        // Restoring the interrupted status after catching InterruptedException
                        // instead of Swallowing
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }.start();
    }

    /**
     * this method add bandwidth usage entries to the jobQueue
     *
     * @param usage Bandwidth usage
     */

    public void addToQueue(BandwidthUsage usage) {
        jobQueue.add(usage);
    }


    /**
     * this method create a Summarizer object for each tenant and call accumulate() method to
     * accumulate usage statistics
     *
     * @throws UsageException
     */

    public void persistUsage() throws UsageException {

        // create a map to hold summarizer objects against tenant id
        HashMap<Integer, Summarizer> summarizerMap = new HashMap<Integer, Summarizer>();

        // if the jobQueue is not empty
        while (!jobQueue.isEmpty()) {

            // get the first element from the queue, which is a BandwidthUsage object
            BandwidthUsage usage = jobQueue.poll();
           
            // get the tenant id
            int tenantId = usage.getTenantId();

            //get the Summarizer object corresponds to the tenant id
            Summarizer summarizer = summarizerMap.get(tenantId);

            // when tenant invoke service for the first time, no corresponding summarizer object in
            // the map
            if (summarizer == null) {
                //create a Summarizer object and put to the summarizerMap
                summarizer = new Summarizer();
                summarizerMap.put(tenantId, summarizer);
            }

            //  now accumulate usage
            summarizer.accumulate(usage);
        }

        //Finished accumulating. Now publish the events

        // get the collection view of values in summarizerMap
        Collection<Summarizer> summarizers = summarizerMap.values();

        // for each summarizer object call the publish method
        for (Summarizer summarizer : summarizers) {
            summarizer.publish();
        }
    }

    /**
     * inner class Summarizer
     * this class is used to accumulate and publish usage statistics.
     * for each tenant this keeps a map to store BandwidthUsage values
     */
    private static class Summarizer {
        private HashMap<String, BandwidthUsage> usageMap;

        public Summarizer() {
            usageMap = new HashMap<String, BandwidthUsage>();
        }

        /**
         * the method to accumulate usage data
         *
         * @param usage BandwidthUsage
         */

        public void accumulate(BandwidthUsage usage) {
            // get the measurement name of usage entry
            String key = usage.getMeasurement();

            // get the existing value of measurement
            BandwidthUsage existingUsage = usageMap.get(key);

            // if this measurement is metered earlier add the new value to the existing value
            if (existingUsage != null) {
                existingUsage.setValue(existingUsage.getValue() + usage.getValue());
            } else {
                // if this measurement is not metered previously we need to add it to the usageMap
                usageMap.put(key, usage);
            }
        }

        /**
         * this method reads usage items from the usageMap and call publish method to publish to
         * the BAM
         *
         * @throws UsageException
         */

        public void publish() throws UsageException {

            // get the collection view of values in usageMap
            Collection<BandwidthUsage> usages = usageMap.values();

            for (BandwidthUsage usage : usages) {
                try {
                    // publish the usage entry
                    PublisherUtils.publish(usage);
                } catch (UsageException e) {
                    log.error("Error in publishing bandwidth usage data", e);
                }
            }
        }
    }
}

TOP

Related Classes of org.wso2.carbon.usage.agent.persist.PersistenceManager$Summarizer

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.