/*
* 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);
}
}