[SEBA-37] Added 11 Statistics counters for Accounting Server operations
Change-Id: I7dda193129e5dffe62907775aaf8dfdc5b3f1bf1
diff --git a/app/src/main/java/org/opencord/aaa/impl/AaaManager.java b/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
index 3e75f17..bcd4cfa 100755
--- a/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
+++ b/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
@@ -19,12 +19,16 @@
import static org.slf4j.LoggerFactory.getLogger;
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Map;
+import java.util.Dictionary;
+import java.util.HashSet;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
@@ -36,6 +40,8 @@
import org.onlab.packet.MacAddress;
import org.onlab.packet.RADIUS;
import org.onlab.packet.RADIUSAttribute;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.event.AbstractListenerManager;
@@ -62,14 +68,23 @@
import org.opencord.aaa.AuthenticationEvent;
import org.opencord.aaa.AuthenticationEventListener;
import org.opencord.aaa.AuthenticationService;
+import org.opencord.aaa.AuthenticationStatisticsEvent;
+import org.opencord.aaa.AuthenticationStatisticsService;
import org.opencord.aaa.RadiusCommunicator;
import org.opencord.aaa.StateMachineDelegate;
import org.opencord.sadis.BaseInformationService;
import org.opencord.sadis.SadisService;
import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Activate;
import org.slf4j.Logger;
+import com.google.common.base.Strings;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
/**
* AAA application for ONOS.
*/
@@ -101,10 +116,21 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MastershipService mastershipService;
- protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected AuthenticationStatisticsService aaaStatisticsManager;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ComponentConfigService cfgService;
+
+ protected AuthenticationStatisticsEventPublisher authenticationStatisticsPublisher;
+ protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
private final DeviceListener deviceListener = new InternalDeviceListener();
+ private static final int DEFAULT_REPEAT_DELAY = 20;
+ @Property(name = "statisticsGenerationEvent", intValue = DEFAULT_REPEAT_DELAY,
+ label = "statisticsGenerationEvent")
+ private int statisticsGenerationEvent = DEFAULT_REPEAT_DELAY;
+
// NAS IP address
protected InetAddress nasIpAddress;
@@ -146,6 +172,11 @@
// latest configuration
AaaConfig newCfg;
+ ScheduledFuture<?> scheduledFuture;
+
+ ScheduledExecutorService executor;
+ String configuredAaaServerAddress;
+ HashSet<Byte> outPacketSet = new HashSet<Byte>();
// Configuration properties factory
private final ConfigFactory factory =
new ConfigFactory<ApplicationId, AaaConfig>(APP_SUBJECT_FACTORY,
@@ -197,48 +228,58 @@
}
@Activate
- public void activate() {
+ public void activate(ComponentContext context) {
appId = coreService.registerApplication(APP_NAME);
eventDispatcher.addSink(AuthenticationEvent.class, listenerRegistry);
netCfgService.addListener(cfgListener);
netCfgService.registerConfigFactory(factory);
+ cfgService.registerProperties(getClass());
+ modified(context);
subsService = sadisService.getSubscriberInfoService();
customInfo = new CustomizationInfo(subsService, deviceService);
cfgListener.reconfigureNetwork(netCfgService.getConfig(appId, AaaConfig.class));
log.info("Starting with config {} {}", this, newCfg);
-
configureRadiusCommunication();
-
// register our event handler
packetService.addProcessor(processor, PacketProcessor.director(2));
-
-
StateMachine.initializeMaps();
StateMachine.setDelegate(delegate);
-
impl.initializeLocalState(newCfg);
-
impl.requestIntercepts();
-
deviceService.addListener(deviceListener);
+ getConfiguredAaaServerAddress();
+ authenticationStatisticsPublisher =
+ new AuthenticationStatisticsEventPublisher();
+ executor = Executors.newScheduledThreadPool(1);
+ scheduledFuture = executor.scheduleAtFixedRate(authenticationStatisticsPublisher,
+ 0, statisticsGenerationEvent, TimeUnit.SECONDS);
log.info("Started");
}
-
@Deactivate
- public void deactivate() {
+ public void deactivate(ComponentContext context) {
impl.withdrawIntercepts();
packetService.removeProcessor(processor);
netCfgService.removeListener(cfgListener);
+ cfgService.unregisterProperties(getClass(), false);
StateMachine.unsetDelegate(delegate);
StateMachine.destroyMaps();
impl.deactivate();
deviceService.removeListener(deviceListener);
eventDispatcher.removeSink(AuthenticationEvent.class);
+ scheduledFuture.cancel(true);
+ executor.shutdown();
log.info("Stopped");
}
+ @Modified
+ public void modified(ComponentContext context) {
+ Dictionary<?, ?> properties = context.getProperties();
+ String s = Tools.get(properties, "statisticsGenerationEvent");
+ statisticsGenerationEvent = Strings.isNullOrEmpty(s) ? DEFAULT_REPEAT_DELAY : Integer.parseInt(s.trim());
+ }
+
private void configureRadiusCommunication() {
if (radiusConnectionType.toLowerCase().equals("socket")) {
impl = new SocketBasedRadiusCommunicator(appId, packetService, this);
@@ -265,6 +306,32 @@
}
}
+ private void getConfiguredAaaServerAddress() {
+ try {
+ InetAddress address;
+ if (newCfg.radiusHostName() != null) {
+ address = InetAddress.getByName(newCfg.radiusHostName());
+ } else {
+ address = newCfg.radiusIp();
+ }
+
+ configuredAaaServerAddress = address.getHostAddress();
+ } catch (UnknownHostException uhe) {
+ log.warn("Unable to resolve host {}", newCfg.radiusHostName());
+ }
+ }
+
+ private void checkReceivedPacketForValidValidator(RADIUS radiusPacket) {
+ if (!radiusPacket.checkMessageAuthenticator(radiusSecret)) {
+ aaaStatisticsManager.getAaaStats().increaseInvalidValidatorsRx();
+ }
+ }
+ public void checkForPacketFromUnknownServer(String hostAddress) {
+ if (!hostAddress.equals(configuredAaaServerAddress)) {
+ aaaStatisticsManager.getAaaStats().incrementUnknownServerRx();
+ }
+ }
+
/**
* Send RADIUS packet to the RADIUS server.
*
@@ -272,6 +339,9 @@
* @param inPkt Incoming EAPOL packet
*/
protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
+ outPacketSet.add(radiusPacket.getIdentifier());
+ aaaStatisticsManager.getAaaStats().increaseOrDecreasePendingRequests(true);
+ aaaStatisticsManager.getAaaStats().increaseAccessRequestsTx();
impl.sendRadiusPacket(radiusPacket, inPkt);
}
@@ -291,12 +361,17 @@
if (stateMachine == null) {
log.error("Invalid packet identifier {}, could not find corresponding "
+ "state machine ... exiting", radiusPacket.getIdentifier());
+ aaaStatisticsManager.getAaaStats().incrementNumberOfSessionsExpired();
+ aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
return;
}
-
EAP eapPayload;
Ethernet eth;
-
+ checkReceivedPacketForValidValidator(radiusPacket);
+ if (outPacketSet.contains(radiusPacket.getIdentifier())) {
+ aaaStatisticsManager.getAaaStats().increaseOrDecreasePendingRequests(false);
+ outPacketSet.remove(new Byte(radiusPacket.getIdentifier()));
+ }
switch (radiusPacket.getCode()) {
case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE:
log.debug("RADIUS packet: RADIUS_CODE_ACCESS_CHALLENGE");
@@ -314,6 +389,7 @@
eapPayload, stateMachine.priorityCode());
log.debug("Send EAP challenge response to supplicant {}", stateMachine.supplicantAddress().toString());
sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+ aaaStatisticsManager.getAaaStats().increaseChallengeResponsesRx();
break;
case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
log.debug("RADIUS packet: RADIUS_CODE_ACCESS_ACCEPT");
@@ -331,7 +407,7 @@
sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
stateMachine.authorizeAccess();
-
+ aaaStatisticsManager.getAaaStats().increaseAcceptResponsesRx();
break;
case RADIUS.RADIUS_CODE_ACCESS_REJECT:
log.debug("RADIUS packet: RADIUS_CODE_ACCESS_REJECT");
@@ -356,11 +432,13 @@
log.warn("Send EAP failure message to supplicant {}", stateMachine.supplicantAddress().toString());
sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
stateMachine.denyAccess();
-
+ aaaStatisticsManager.getAaaStats().increaseRejectResponsesRx();
break;
default:
log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode());
+ aaaStatisticsManager.getAaaStats().increaseUnknownTypeRx();
}
+ aaaStatisticsManager.getAaaStats().countDroppedResponsesRx();
}
/**
@@ -473,7 +551,6 @@
log.debug("Using existing state-machine for sessionId: {}", sessionId);
}
-
switch (eapol.getEapolType()) {
case EAPOL.EAPOL_START:
log.debug("EAP packet: EAPOL_START");
@@ -523,6 +600,9 @@
sendRadiusPacket(radiusPayload, inPacket);
// change the state to "PENDING"
+ if (stateMachine.state() == StateMachine.STATE_PENDING) {
+ aaaStatisticsManager.getAaaStats().increaseRequestReTx();
+ }
stateMachine.requestAccess();
break;
case EAP.ATTR_MD5:
@@ -686,4 +766,26 @@
}
}
}
+ private class AuthenticationStatisticsEventPublisher implements Runnable {
+ private final Logger log = getLogger(getClass());
+ public void run() {
+ log.info("Notifying AuthenticationStatisticsEvent");
+ aaaStatisticsManager.calculatePacketRoundtripTime();
+ log.debug("AcceptResponsesRx---" + aaaStatisticsManager.getAaaStats().getAcceptResponsesRx());
+ log.debug("AccessRequestsTx---" + aaaStatisticsManager.getAaaStats().getAccessRequestsTx());
+ log.debug("ChallengeResponsesRx---" + aaaStatisticsManager.getAaaStats().getChallengeResponsesRx());
+ log.debug("DroppedResponsesRx---" + aaaStatisticsManager.getAaaStats().getDroppedResponsesRx());
+ log.debug("InvalidValidatorsRx---" + aaaStatisticsManager.getAaaStats().getInvalidValidatorsRx());
+ log.debug("MalformedResponsesRx---" + aaaStatisticsManager.getAaaStats().getMalformedResponsesRx());
+ log.debug("PendingRequests---" + aaaStatisticsManager.getAaaStats().getPendingRequests());
+ log.debug("RejectResponsesRx---" + aaaStatisticsManager.getAaaStats().getRejectResponsesRx());
+ log.debug("RequestReTx---" + aaaStatisticsManager.getAaaStats().getRequestReTx());
+ log.debug("RequestRttMilis---" + aaaStatisticsManager.getAaaStats().getRequestRttMilis());
+ log.debug("UnknownServerRx---" + aaaStatisticsManager.getAaaStats().getUnknownServerRx());
+ log.debug("UnknownTypeRx---" + aaaStatisticsManager.getAaaStats().getUnknownTypeRx());
+ aaaStatisticsManager.getStatsDelegate().
+ notify(new AuthenticationStatisticsEvent(AuthenticationStatisticsEvent.Type.STATS_UPDATE,
+ aaaStatisticsManager.getAaaStats()));
+ }
+ }
}