/* * Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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.apache.synapse.commons.throttle.module.utils; import org.apache.synapse.commons.throttle.module.utils.impl.DummyHandler; import org.apache.synapse.commons.throttle.core.AccessInformation; import org.apache.synapse.commons.throttle.core.ThrottleConstants; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; public class StatCollector { private Map statsPerUser = new ConcurrentHashMap(); private Map statsPerDomain = new ConcurrentHashMap(); private Map statsPerIP = new ConcurrentHashMap(); private AtomicLong stTime_User = new AtomicLong(-1); private AtomicLong stTime_IP = new AtomicLong(-1); private AtomicLong stTime_DOMAIN = new AtomicLong(-1); private long startTime = 0; public static long statCollectionPeriod = 0; public static long statDisplayWindow = 0; private static volatile StatCollector instance = null; public static boolean enableStatCollection = false; private StatCollector() { startTime = System.nanoTime(); } private void storeStats(AccessInformation accessInfo, String callerID, int throttleType) { long timeStamp = System.nanoTime(); System.out.println(timeStamp); if (ThrottleConstants.DOMAIN_BASE == throttleType) { stTime_DOMAIN.compareAndSet(-1, timeStamp); statsPerDomain.put(new Long(timeStamp), new StatDO(accessInfo.isAccessAllowed(), callerID, new Long(timeStamp))); } else if (ThrottleConstants.IP_BASE == throttleType) { stTime_IP.compareAndSet(-1, timeStamp); statsPerIP.put(new Long(timeStamp), new StatDO(accessInfo.isAccessAllowed(), callerID, new Long(timeStamp))); } else if (ThrottleConstants.ROLE_BASE == throttleType) { stTime_User.compareAndSet(-1, timeStamp); statsPerUser.put(new Long(timeStamp), new StatDO(accessInfo.isAccessAllowed(), callerID, new Long(timeStamp))); } } public static StatCollector getInstance() { if (instance == null) { synchronized (StatCollector.class) { if (instance == null) { instance = new StatCollector(); } } } return instance; } public static void setStatCollectionPeriod(long period) { statCollectionPeriod = period; } public static void setStatDisplayWindow(long period) { statDisplayWindow = period; } public static void collect(AccessInformation accessInfo, String callerID, int type) { if(!enableStatCollection){ return; } getInstance().storeStats(accessInfo, callerID, type); } private void flushAll() { statsPerDomain.clear(); statsPerUser.clear(); statsPerIP.clear(); stTime_User = new AtomicLong(-1); stTime_IP = new AtomicLong(-1); stTime_DOMAIN = new AtomicLong(-1); statCollectionPeriod = 0; statDisplayWindow = 0; startTime = 0; } public static void flushStats(){ getInstance().flushAll(); } public static void displayStats(int throttleType) { StatCollector collector = getInstance(); Map sortedMap = null; if (ThrottleConstants.DOMAIN_BASE == throttleType) { System.out.println("Start Time : Domain Base Throttling ::" + collector.stTime_DOMAIN); sortedMap = sortByComparator(collector.statsPerDomain); } else if (ThrottleConstants.IP_BASE == throttleType) { System.out.println("Start Time : IP Base Throttling ::" + collector.stTime_IP); sortedMap = sortByComparator(collector.statsPerIP); } else if (ThrottleConstants.ROLE_BASE == throttleType) { System.out.println("Start Time : Role Base Throttling ::" + collector.stTime_User); sortedMap = sortByComparator(collector.statsPerUser); } Set set = sortedMap.entrySet(); Iterator iterator = set.iterator(); String prevCallerID = null; boolean prevAccessState = false; Long phaseStartTimestamp = null; Long phaseEndTimestamp = null; Long prevTimestamp = null; String callerID = null; while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); Long timestamp = (Long) entry.getKey(); callerID = ((StatDO) entry.getValue()).getCallerID(); boolean currAccessState = ((StatDO) entry.getValue()).isAccessAllowed(); if (prevCallerID == null || callerID.equals(prevCallerID)) { if (prevCallerID != null && prevAccessState != currAccessState) { //a phase changes phaseEndTimestamp = prevTimestamp; System.out.println("Access Phase change for :" + callerID + " duration of this phase :" + (phaseEndTimestamp - phaseStartTimestamp) / 1000.0 + " ms"); phaseStartTimestamp = timestamp; } else { //same access phase if (phaseStartTimestamp == null) { phaseStartTimestamp = timestamp; } } } else { //caller changes phaseStartTimestamp = timestamp; } prevCallerID = callerID; prevAccessState = currAccessState; prevTimestamp = timestamp; } iterator = set.iterator(); while (iterator.hasNext()) { Map.Entry entry = (Map.Entry) iterator.next(); System.out.println("Timestamp : " + entry.getKey() + " CallerID : " + ((StatDO) entry.getValue()).getCallerID() + " Role : " + DummyHandler.apiKey2roleMap. get(((StatDO) entry.getValue()).getCallerID()) + (((StatDO) entry.getValue()).isAccessAllowed() ? " --> Allowed" : "--> Denied")); } } private static Map sortByComparator(Map unsortMap) { List list = new LinkedList(unsortMap.entrySet()); //sort list based on comparator Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { return ((Comparable) ((Map.Entry) (o1)).getValue()) .compareTo(((Map.Entry) (o2)).getValue()); } }); //put sorted list into map again Map sortedMap = new LinkedHashMap(); for (Iterator it = list.iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); sortedMap.put(entry.getKey(), entry.getValue()); } return sortedMap; } private class StatDO implements Comparable { private boolean accessAllowed = false; private String callerID = ""; private Long timestamp; public StatDO(boolean accessAllowed, String callerID, Long timestamp) { this.accessAllowed = accessAllowed; this.callerID = callerID; this.timestamp = timestamp; } public boolean isAccessAllowed() { return accessAllowed; } public String getCallerID() { return callerID; } public Long getTimestamp() { return timestamp; } public int compareTo(Object o) { int result = 0; result = callerID.compareTo(((StatDO) o).getCallerID()); if (result != 0) { return result; } return timestamp.compareTo(((StatDO) o).getTimestamp()); } } public static void main(String[] args) { AccessInformation acAllwd = new AccessInformation(); acAllwd.setAccessAllowed(true); AccessInformation acDenied = new AccessInformation(); acDenied.setAccessAllowed(false); StatCollector.collect(acAllwd, "nq21LN39VlKe6OezcOndBx", ThrottleConstants.ROLE_BASE); StatCollector.collect(acAllwd, "nq21LN39VlKe6OezcOndBx", ThrottleConstants.ROLE_BASE); StatCollector.collect(acAllwd, "nq21LN39VlKe6OezcOndBx", ThrottleConstants.ROLE_BASE); StatCollector.collect(acAllwd, "nq21LN39VlKe6OezcOndBx", ThrottleConstants.ROLE_BASE); StatCollector.collect(acAllwd, "asdadsadg33332424Gasdad", ThrottleConstants.ROLE_BASE); StatCollector.collect(acAllwd, "asdadsadg33332424Gasdad", ThrottleConstants.ROLE_BASE); StatCollector.collect(acAllwd, "asdadsadg33332424Gasdad", ThrottleConstants.ROLE_BASE); StatCollector.collect(acAllwd, "asdadsadg33332424Gasdad", ThrottleConstants.ROLE_BASE); StatCollector.collect(acDenied, "nq21LN39VlKe6OezcOndBx", ThrottleConstants.ROLE_BASE); StatCollector.collect(acDenied, "nq21LN39VlKe6OezcOndBx", ThrottleConstants.ROLE_BASE); StatCollector.collect(acDenied, "asdadsadg33332424Gasdad", ThrottleConstants.ROLE_BASE); StatCollector.collect(acDenied, "asdadsadg33332424Gasdad", ThrottleConstants.ROLE_BASE); StatCollector.collect(acAllwd, "asdadsadg33332424Gasdad", ThrottleConstants.ROLE_BASE); StatCollector.displayStats(ThrottleConstants.ROLE_BASE); } }