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

Alachisoft.NCache.Sessions.CounterSession Maven / Gradle / Ivy

The newest version!
package Alachisoft.NCache.Sessions;

import Alachisoft.NCache.Common.DataStructures.SlidingIndex;
import Alachisoft.NCache.Common.Logger.ILogger;
import Alachisoft.NCache.DataModel.Counter;
import Alachisoft.NCache.DataModel.CounterData;
import Alachisoft.NCache.DataModel.MetricsDBSession;
import Alachisoft.NCache.DataModel.PublisherVersion;
import Alachisoft.NCache.MetricsAgents.MetricsAgentManager;
import com.alachisoft.ncache.common.caching.statistics.monitoring.CounterIDMap;
import com.alachisoft.ncache.common.monitoring.*;
import tangible.RefObject;

import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
import java.util.function.Function;

public abstract class CounterSession {
    // Private attributes
    private MetricsDBSession metric;
    protected long refTime = 0;
    private int inMemoryInterval;
    protected ILogger logger;
    protected MetricsAgentManager metricsAgentManager;

    // Protected attributes
    protected boolean countersMetaPersisted;
    protected SlidingIndex> countersIndex = null;
    protected Map countersIDMap = new HashMap<>();
    protected PublisherVersion publisherVersion = null;
    protected long counterRefTime;
    protected List counters = new ArrayList<>();

    // Public properties
    public MetricsDBSession getMetric() {
        return metric;
    }

    public CounterIDMap getCounterIDMapCommon() {
        return counterIDMapCommon;
    }

    public void setCounterIDMapCommon(CounterIDMap counterIDMapCommon) {
        this.counterIDMapCommon = counterIDMapCommon;
    }

    private CounterIDMap counterIDMapCommon = new CounterIDMap();
    public List countersMetadata = new ArrayList<>();

    // Initialization
    public CounterSession(String cacheConfigId) {
        if (cacheConfigId == null || cacheConfigId.isEmpty())
            sessionGuid = UUID.randomUUID().toString();
        else
            sessionGuid = cacheConfigId;
    }

    public void initializeCounters(int inMemoryInterval, ILogger logger, MetricsAgentManager metricsAgentManager) {
        this.inMemoryInterval = inMemoryInterval;
        countersIndex = new SlidingIndex<>(inMemoryInterval);
        this.logger = logger;
        this.metricsAgentManager = metricsAgentManager;
    }

    // Persistence
    public void persistCounters() {
        try {
            synchronized (countersIndex) {
                Iterator> iterator = countersIndex.GetCurrentData(new RefObject(new Long(0)), false);
                while (iterator.hasNext()) {
                    MutableKeyValuePair entry = iterator.next();
                    if (entry.getValue()) {
                        CounterData counter = entry.getKey();
                        if (counterIDMapCommon != null && counter.getCounterMetadata() != null) {
                            String name = counterIDMapCommon.getCounterName(counter.getCounterId());
                            String counterName = getCounterNameWithLiteral(name, counter.getCounterMetadata().getCategory());
                            if (countersMetaPersisted) {
                                String counterInstanceName = getCounterInstanceName(counterName);
                                publishMetric(counterInstanceName, counter);
                            }
                        }
                        entry.setValue(false);
                    }
                }
            }
        } catch (Exception e) {
            logger.Error("MetricServer", e.toString());
        }
    }
    public void createCounters() {
        try {
            synchronized (countersMetadata) {
                if (!countersMetaPersisted) {
                    Iterator iterator = countersMetadata.iterator();
                    while (iterator.hasNext()) {
                        Counter current = iterator.next();
                        String counterName = getCounterNameWithLiteral(current.getName(), current.getCategory());
                        String counterInstanceName = getCounterInstanceName(counterName);
                        metricsAgentManager.initializeCounterInstance(counterInstanceName, counterName, current);
                        counters.add(counterInstanceName);
                    }
                    countersMetaPersisted = true;
                }
            }
        } catch (Exception e) {
            logger.Error("MetricServer", e.toString());
        }
    }
    public void publishMetric(String instanceName, CounterData counterData) {
        // Your implementation goes here
    }
    protected abstract List getParamsList();
    /**
     * This method receives counters metadata from the cache, client, or bridge and stores it in the session.
     * Later, persistence is invoked to persist data to the database.
     *
     * @param counterMeta The CounterMetadataCollection to store.
     */
    public void storeCountersMetadata(CounterMetadataCollection counterMeta) {
        if (countersMetadata.isEmpty()) {
            try {
                synchronized (countersMetadata) {
                    getCounterIDMapCommon().assignAndAddCounters(counterMeta.getCounters());

                    if (counterMeta.getCategory() == Publisher.NCache) {
                        populateCacheCounters(counterMeta);
                    }

                    Iterator iterator = counterMeta.getCounters().iterator();
                    while (iterator.hasNext()) {
                        CounterMetadata current = iterator.next();
                        Counter counter = new Counter();
                        counter.setCategory(counterMeta.getCategory());
                        counter.setDescription(current.getDescription());
                        counter.setName(current.getName());
                        counter.setType(current.getType());

                        countersMetadata.add(counter);
                    }
                }
            } catch (Exception e) {
                logger.Error("MetricServer", e.toString());
            }
        }
    }
    /**
     * This method receives counters data from the cache, client, or bridge and stores it in the session.
     * Later, persistence is invoked to persist data to the database.
     *
     * @param sessionId The session ID.
     * @param counterData The CounterDataCollection to store.
     */
    public void storeCountersData(String sessionId, CounterDataCollection counterData) {
        List counterDatas = new ArrayList<>();

        for (int iterator = 0; iterator < counterData.getValues().size(); iterator++) {
            IntervalCounterDataCollection intervalData = counterData.getValues().get(iterator);
            Date interval = intervalData.getTimestamp();

            Iterator> iteratorMap = intervalData.getValues().entrySet().iterator();
            while (iteratorMap.hasNext()) {
                Map.Entry entry = iteratorMap.next();
                short id = entry.getKey();
                double value = entry.getValue();

                CounterData data = new CounterData();
                data.setData(value);
                data.setCounterId(id);
                data.setTimestamp(interval);

                populateCounterMeta(data);
                counterDatas.add(data);
            }

            // counterDatas contains the new counters data for the interval received
            // Now accumulate these counters
            addCountersDataToIndex(counterDatas, true);
            counterDatas.clear();
        }
    }
    public void populateCounterMeta(CounterData counterData) {
        for (Counter item : countersMetadata) {
            if (item.getName().equals(getCounterIDMapCommon().getCounterName(counterData.getCounterId()))) {
                counterData.setCounterMetadata(item);
                break;
            }
        }
    }
    public Map>> getInMemoryData(Collection counterIds, Date start, int limit) {
        List inMemory = new ArrayList<>();
        if (isInMemoryDataRequired(start, counterIds, inMemory)) {
            List result = new ArrayList<>(inMemory);
            List counters = getCountersMetadata();

            Function groupByKeySelector = CounterData::getTimestamp;
            Function> toDictionaryCriteria =
                    counterData -> {
                        String counterName = counters.stream()
                                .filter(meta -> meta.getId() == counterData.getCounterId())
                                .map(Counter::getName)
                                .findFirst()
                                .orElse(null);
                        return new AbstractMap.SimpleEntry<>(counterName, counterData.getData());
                    };

            Map>> res =
                    result.stream()
                            .collect(Collectors.groupingBy(groupByKeySelector,
                                    Collectors.mapping(toDictionaryCriteria, Collectors.toList())));

            return res;
        }
        return null;
    }
    public List getCountersMetadata() {
        if (countersMetadata == null || countersMetadata.isEmpty()) {
            initializeCounterMetadata(publisherVersion.getVersion());
        }
        return countersMetadata;
    }
    protected void initializeCounterMetadata(String version) {
        // Your implementation goes here
    }
    protected void initializeCounterMetadata(Collection countersMeta, Publisher publisher, String version) {
        synchronized (countersMetadata) {
            countersMetadata.clear();
            countersIDMap.clear();
            getCounterIDMapCommon().Clear();

            countersMetadata.addAll(countersMeta);

            List metadata = countersMetadata.stream()
                    .map(s -> {
                        CounterMetadata counter = new CounterMetadata();
                        counter.setCategory(s.getCategory());
                        counter.setDescription(s.getDescription());
                        counter.setName(s.getName());
                        counter.setType(s.getType());
                        return counter;
                    }).collect(Collectors.toList());

            getCounterIDMapCommon().assignAndAddCounters(metadata);

            Iterator enumerator = countersMeta.iterator();
            while (enumerator.hasNext()) {
                Counter current = enumerator.next();
                short key = getCounterIDMapCommon().getCounterID(current.getName());
                short value = current.getId();
                if (!countersIDMap.containsKey(key)) {
                    countersIDMap.put(key, value);
                }
            }
        }
    }

    protected void addCountersDataToIndex(List counterDatas, boolean persist) {
        synchronized (countersIndex) {
            for (int iterator = 0; iterator < counterDatas.size(); iterator++) {
                MutableKeyValuePair entry = new MutableKeyValuePair<>();
                entry.setKey(counterDatas.get(iterator));
                entry.setValue(persist);
                countersIndex.AddToIndex(entry);
            }
        }
    }
    private boolean isInMemoryDataRequired(Date start, Collection counterIds, List result) {
        result = null;
        synchronized (countersIndex) {
            Instant currentTime = Instant.now();
            Instant thresholdTime = currentTime.minusSeconds(inMemoryInterval);

            if (thresholdTime.isAfter(Instant.now())) {
                Iterator> counters = countersIndex.GetCurrentData();
                result = new ArrayList<>();

                while (counters.hasNext()) {
                    MutableKeyValuePair entry = counters.next();
                    if (entry.getValue()) {
                        CounterData data = entry.getKey();

                        if (start != null) {
                            if (data.getTimestamp().compareTo(start) >= 0 && counterIds.contains(data.getCounterId())) {
                                result.add(entry.getKey());
                            }
                        } else {
                            if (counterIds.contains(data.getCounterId())) {
                                result.add(entry.getKey());
                            }
                        }
                    }
                }

                if (result != null && result.size() > 0) {
                    return true;
                }
            }
        }
        return false;
    }

    private CounterMetadataCollection populateCacheCounters(CounterMetadataCollection counterMeta) {
        counterMeta.getCounters().add(createCounter("configured_servers_count", "Total number of configured servers", CounterType.NumberOfItemCounter, Publisher.NCache));
        counterMeta.getCounters().add(createCounter("total_cache_size", "Total size of the cache", CounterType.NumberOfItemCounter, Publisher.NCache));
        return counterMeta;
    }

    private CounterMetadata createCounter(String counterName, String description, CounterType type, Publisher publisher) {
        CounterMetadata counter = new CounterMetadata();
        counter.setName(counterName);
        counter.setDescription(description);
        counter.setType(type);
        counter.setCategory(publisher);
        return counter;
    }



    private String getCounterLiteral(Publisher category, String name) {
        String literal = "ncache_";
        switch (category) {
            case Bridge:
                if (!name.toLowerCase().startsWith("bridge"))
                    literal += "bridge_";
                break;
            case BridgedCache:
                literal += "bridgedcache_";
                break;
            case NCacheClient:
                literal += "client_";
                break;
            case NCachePersistence:
                literal = "persistence_";
                break;
            case NCacheLucene:
                literal = "lucene_";
                break;
            case NCache:
                if (name.toLowerCase().startsWith("bridge"))
                    literal += "caching_";
                break;
        }

        return literal;
    }
    public String getCounterNameWithLiteral(String name, Publisher category) {
        if (!name.contains(" ")) {
            name = String.join(" ", name.chars().mapToObj(c -> Character.isUpperCase(c) ? " " + (char) c : String.valueOf((char) c)).toArray(String[]::new)).trim();
        }

        String literal = getCounterLiteral(category, name);

        String counterName = literal + name
                .replace(" ", "_")
                .replace("#", "")
                .replace("/", "_per_")
                .replace("(", "")
                .replace(")", "")
                .replace("-", "_")
                .replace("%", "percent")
                .toLowerCase();

        counterName = counterName.contains("__") ? counterName.replace("__", "_") : counterName;

        return counterName;
    }
    protected String getCounterInstanceName(String counterName) {
        return String.format("%s:%s", sessionGuid, counterName);
    }
    protected String sessionGuid = "";

    // Dispose
    public void dispose() {
        synchronized (counters) {
            for (String counterInstance : counters) {
                metricsAgentManager.disposeCounterInstance(counterInstance, getParamsList());
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy