Ray Milkey
Committed by Gerrit Code Review

AAA App refactoring

- optimized lookup of state machines
- modified getter/setter method names to match ONOS project standards
- made StateMachine local members private and add accesor methods
- added unit tests for StateMachine lookups

Change-Id: I5704ddc4d8b1b3c887be1262f2edd78965e4a8bf
......@@ -15,8 +15,13 @@
*/
package org.onosproject.aaa;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Dictionary;
import java.util.Optional;
import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
......@@ -61,15 +66,7 @@ import org.onosproject.xosintegration.VoltTenantService;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import com.google.common.base.Strings;
import static org.onosproject.net.packet.PacketPriority.CONTROL;
import static org.slf4j.LoggerFactory.getLogger;
......@@ -80,35 +77,6 @@ import static org.slf4j.LoggerFactory.getLogger;
*/
@Component(immediate = true)
public class AAA {
// a list of our dependencies :
// to register with ONOS as an application - described next
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
// to receive Packet-in events that we'll respond to
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
// end host information
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostService hostService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected VoltTenantService voltTenantService;
// for verbose output
private final Logger log = getLogger(getClass());
// our application-specific event handler
private ReactivePacketProcessor processor = new ReactivePacketProcessor();
// our unique identifier
private ApplicationId appId;
// Map of state machines. Each state machine is represented by an
// unique identifier on the switch: dpid + port number
Map stateMachineMap = null;
// RADIUS server IP address
private static final String DEFAULT_RADIUS_IP = "192.168.1.10";
// NAS IP address
......@@ -125,43 +93,84 @@ public class AAA {
private static final String DEFAULT_RADIUS_SWITCH = "of:90e2ba82f97791e9";
// Radius Port Number
private static final String DEFAULT_RADIUS_PORT = "129";
// for verbose output
private final Logger log = getLogger(getClass());
// a list of our dependencies :
// to register with ONOS as an application - described next
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
// to receive Packet-in events that we'll respond to
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
// end host information
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostService hostService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected VoltTenantService voltTenantService;
// Parsed RADIUS server IP address
protected InetAddress parsedRadiusIpAddress;
// Parsed NAS IP address
protected InetAddress parsedNasIpAddress;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ComponentConfigService cfgService;
// our application-specific event handler
private ReactivePacketProcessor processor = new ReactivePacketProcessor();
// our unique identifier
private ApplicationId appId;
@Property(name = "radiusIpAddress", value = DEFAULT_RADIUS_IP,
label = "RADIUS IP Address")
private String radiusIpAddress = DEFAULT_RADIUS_IP;
@Property(name = "nasIpAddress", value = DEFAULT_NAS_IP,
label = "NAS IP Address")
private String nasIpAddress = DEFAULT_NAS_IP;
@Property(name = "radiusMacAddress", value = RADIUS_MAC_ADDRESS,
label = "RADIUS MAC Address")
private String radiusMacAddress = RADIUS_MAC_ADDRESS;
@Property(name = "nasMacAddress", value = NAS_MAC_ADDRESS,
label = "NAS MAC Address")
private String nasMacAddress = NAS_MAC_ADDRESS;
@Property(name = "radiusSecret", value = DEFAULT_RADIUS_SECRET,
label = "RADIUS shared secret")
private String radiusSecret = DEFAULT_RADIUS_SECRET;
@Property(name = "radiusSwitchId", value = DEFAULT_RADIUS_SWITCH,
label = "Radius switch")
private String radiusSwitch = DEFAULT_RADIUS_SWITCH;
@Property(name = "radiusPortNumber", value = DEFAULT_RADIUS_PORT,
label = "Radius port")
private String radiusPort = DEFAULT_RADIUS_PORT;
// Parsed RADIUS server IP address
protected InetAddress parsedRadiusIpAddress;
/**
* Builds an EAPOL packet based on the given parameters.
*
* @param dstMac destination MAC address
* @param srcMac source MAC address
* @param vlan vlan identifier
* @param eapolType EAPOL type
* @param eap EAP payload
* @return Ethernet frame
*/
private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac,
short vlan, byte eapolType, EAP eap) {
// Parsed NAS IP address
protected InetAddress parsedNasIpAddress;
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(dstMac.toBytes());
eth.setSourceMACAddress(srcMac.toBytes());
eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
if (vlan != Ethernet.VLAN_UNTAGGED) {
eth.setVlanID(vlan);
}
//eapol header
EAPOL eapol = new EAPOL();
eapol.setEapolType(eapolType);
eapol.setPacketLength(eap.getLength());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ComponentConfigService cfgService;
//eap part
eapol.setPayload(eap);
eth.setPayload(eapol);
eth.setPad(true);
return eth;
}
@Modified
public void modified(ComponentContext context) {
......@@ -207,11 +216,10 @@ public class AAA {
// register our event handler
packetService.addProcessor(processor, PacketProcessor.director(2));
requestIntercepts();
// Instantiate the map of the state machines
stateMachineMap = Collections.synchronizedMap(Maps.newHashMap());
hostService.startMonitoringIp(IpAddress.valueOf(radiusIpAddress));
StateMachine.initializeMaps();
hostService.startMonitoringIp(IpAddress.valueOf(radiusIpAddress));
}
@Deactivate
......@@ -223,6 +231,7 @@ public class AAA {
// de-register and null our handler
packetService.removeProcessor(processor);
processor = null;
StateMachine.destroyMaps();
}
/**
......@@ -260,39 +269,6 @@ public class AAA {
packetService.cancelPackets(radSelector, CONTROL, appId);
}
/**
* Builds an EAPOL packet based on the given parameters.
*
* @param dstMac destination MAC address
* @param srcMac source MAC address
* @param vlan vlan identifier
* @param eapolType EAPOL type
* @param eap EAP payload
* @return Ethernet frame
*/
private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac,
short vlan, byte eapolType, EAP eap) {
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(dstMac.toBytes());
eth.setSourceMACAddress(srcMac.toBytes());
eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
if (vlan != Ethernet.VLAN_UNTAGGED) {
eth.setVlanID(vlan);
}
//eapol header
EAPOL eapol = new EAPOL();
eapol.setEapolType(eapolType);
eapol.setPacketLength(eap.getLength());
//eap part
eapol.setPayload(eap);
eth.setPayload(eapol);
eth.setPad(true);
return eth;
}
// our handler defined as a private inner class
/**
......@@ -351,7 +327,11 @@ public class AAA {
DeviceId deviceId = inPacket.receivedFrom().deviceId();
PortNumber portNumber = inPacket.receivedFrom().port();
String sessionId = deviceId.toString() + portNumber.toString();
StateMachine stateMachine = getStateMachine(sessionId);
StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(sessionId);
if (stateMachine == null) {
stateMachine = new StateMachine(sessionId, voltTenantService);
}
EAPOL eapol = (EAPOL) ethPkt.getPayload();
......@@ -359,17 +339,17 @@ public class AAA {
case EAPOL.EAPOL_START:
try {
stateMachine.start();
stateMachine.supplicantConnectpoint = inPacket.receivedFrom();
stateMachine.setSupplicantConnectpoint(inPacket.receivedFrom());
//send an EAP Request/Identify to the supplicant
EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.getIdentifier(), EAP.ATTR_IDENTITY, null);
EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.identifier(), EAP.ATTR_IDENTITY, null);
Ethernet eth = buildEapolResponse(srcMAC, MacAddress.valueOf(1L),
ethPkt.getVlanID(), EAPOL.EAPOL_PACKET,
eapPayload);
stateMachine.supplicantAddress = srcMAC;
stateMachine.vlanId = ethPkt.getVlanID();
stateMachine.setSupplicantAddress(srcMAC);
stateMachine.setVlanId(ethPkt.getVlanID());
this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint);
this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
} catch (StateMachineException e) {
e.printStackTrace();
}
......@@ -386,7 +366,7 @@ public class AAA {
//request id access to RADIUS
RADIUS radiusPayload = new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
eapPacket.getIdentifier());
radiusPayload.setIdentifier(stateMachine.getIdentifier());
radiusPayload.setIdentifier(stateMachine.identifier());
radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
eapPacket.getData());
stateMachine.setUsername(eapPacket.getData());
......@@ -409,20 +389,20 @@ public class AAA {
case EAP.ATTR_MD5:
//verify if the EAP identifier corresponds to the challenge identifier from the client state
//machine.
if (eapPacket.getIdentifier() == stateMachine.getChallengeIdentifier()) {
if (eapPacket.getIdentifier() == stateMachine.challengeIdentifier()) {
//send the RADIUS challenge response
RADIUS radiusPayload = new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
eapPacket.getIdentifier());
radiusPayload.setIdentifier(stateMachine.getChallengeIdentifier());
radiusPayload.setIdentifier(stateMachine.challengeIdentifier());
radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
stateMachine.getUsername());
stateMachine.username());
radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
AAA.this.parsedNasIpAddress.getAddress());
radiusPayload.encapsulateMessage(eapPacket);
radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
stateMachine.getChallengeState());
stateMachine.challengeState());
radiusPayload.addMessageAuthenticator(AAA.this.radiusSecret);
sendRadiusMessage(radiusPayload);
}
......@@ -432,16 +412,16 @@ public class AAA {
//request id access to RADIUS
RADIUS radiusPayload = new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
eapPacket.getIdentifier());
radiusPayload.setIdentifier(stateMachine.getIdentifier());
radiusPayload.setIdentifier(stateMachine.identifier());
radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
stateMachine.getUsername());
stateMachine.username());
radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
AAA.this.parsedNasIpAddress.getAddress());
radiusPayload.encapsulateMessage(eapPacket);
radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
stateMachine.getChallengeState());
stateMachine.challengeState());
stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
radiusPayload.addMessageAuthenticator(AAA.this.radiusSecret);
......@@ -468,7 +448,7 @@ public class AAA {
* @param radiusPacket RADIUS packet coming from the RADIUS server.
*/
private void handleRadiusPacket(RADIUS radiusPacket) {
StateMachine stateMachine = getStateMachineById(radiusPacket.getIdentifier());
StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier());
if (stateMachine == null) {
log.error("Invalid session identifier, exiting...");
return;
......@@ -481,10 +461,10 @@ public class AAA {
byte[] challengeState = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE).getValue();
eapPayload = radiusPacket.decapsulateMessage();
stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState);
eth = buildEapolResponse(stateMachine.supplicantAddress,
MacAddress.valueOf(1L), stateMachine.vlanId, EAPOL.EAPOL_PACKET,
eth = buildEapolResponse(stateMachine.supplicantAddress(),
MacAddress.valueOf(1L), stateMachine.vlanId(), EAPOL.EAPOL_PACKET,
eapPayload);
this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint);
this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
break;
case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
try {
......@@ -493,10 +473,10 @@ public class AAA {
radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
eapPayload = new EAP();
eapPayload = (EAP) eapPayload.deserialize(eapMessage, 0, eapMessage.length);
eth = buildEapolResponse(stateMachine.supplicantAddress,
MacAddress.valueOf(1L), stateMachine.vlanId, EAPOL.EAPOL_PACKET,
eth = buildEapolResponse(stateMachine.supplicantAddress(),
MacAddress.valueOf(1L), stateMachine.vlanId(), EAPOL.EAPOL_PACKET,
eapPayload);
this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint);
this.sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
stateMachine.authorizeAccess();
} catch (StateMachineException e) {
......@@ -515,51 +495,6 @@ public class AAA {
}
}
private StateMachine getStateMachineById(byte identifier) {
StateMachine stateMachine = null;
Set stateMachineSet = stateMachineMap.entrySet();
synchronized (stateMachineMap) {
Iterator itr = stateMachineSet.iterator();
while (itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
stateMachine = (StateMachine) entry.getValue();
if (identifier == stateMachine.getIdentifier()) {
//the state machine has already been created for this session session
stateMachine = (StateMachine) entry.getValue();
break;
}
}
}
return stateMachine;
}
private StateMachine getStateMachine(String sessionId) {
StateMachine stateMachine = null;
Set stateMachineSet = stateMachineMap.entrySet();
synchronized (stateMachineMap) {
Iterator itr = stateMachineSet.iterator();
while (itr.hasNext()) {
Map.Entry entry = (Map.Entry) itr.next();
if (sessionId.equals(entry.getKey())) {
//the state machine has already been created for this session session
stateMachine = (StateMachine) entry.getValue();
break;
}
}
}
if (stateMachine == null) {
stateMachine = new StateMachine(sessionId, voltTenantService);
stateMachineMap.put(sessionId, stateMachine);
}
return stateMachine;
}
private void sendRadiusMessage(RADIUS radiusMessage) {
Set<Host> hosts = hostService.getHostsByIp(IpAddress.valueOf(radiusIpAddress));
Optional<Host> odst = hosts.stream().filter(h -> h.vlan().toShort() == VlanId.UNTAGGED).findFirst();
......
......@@ -18,13 +18,16 @@
package org.onosproject.aaa;
import java.util.BitSet;
import java.util.Map;
import org.onlab.packet.MacAddress;
import org.onosproject.net.ConnectPoint;
import org.onosproject.xosintegration.VoltTenant;
import org.onosproject.xosintegration.VoltTenantService;
import org.slf4j.Logger;
import java.util.BitSet;
import com.google.common.collect.Maps;
import static org.slf4j.LoggerFactory.getLogger;
......@@ -58,9 +61,9 @@ class StateMachine {
private byte[] requestAuthenticator;
// Supplicant connectivity info
protected ConnectPoint supplicantConnectpoint;
protected MacAddress supplicantAddress;
protected short vlanId;
private ConnectPoint supplicantConnectpoint;
private MacAddress supplicantAddress;
private short vlanId;
private String sessionId = null;
......@@ -109,8 +112,28 @@ class StateMachine {
private int currentState = STATE_IDLE;
// Maps of state machines. Each state machine is represented by an
// unique identifier on the switch: dpid + port number
private static Map<String, StateMachine> sessionIdMap;
private static Map<Integer, StateMachine> identifierMap;
/**
public static void initializeMaps() {
sessionIdMap = Maps.newConcurrentMap();
identifierMap = Maps.newConcurrentMap();
}
public static void destroyMaps() {
sessionIdMap = null;
identifierMap = null;
}
public static StateMachine lookupStateMachineById(byte identifier) {
return identifierMap.get((int) identifier);
}
public static StateMachine lookupStateMachineBySessionId(String sessionId) {
return sessionIdMap.get(sessionId);
} /**
* State Machine Constructor.
*
* @param sessionId session Id represented by the switch dpid + port number
......@@ -120,15 +143,69 @@ class StateMachine {
log.info("Creating a new state machine for {}", sessionId);
this.sessionId = sessionId;
this.voltService = voltService;
sessionIdMap.put(sessionId, this);
}
/**
* Gets the connect point for the supplicant side.
*
* @return supplicant connect point
*/
public ConnectPoint supplicantConnectpoint() {
return supplicantConnectpoint;
}
/**
* Sets the supplicant side connect point.
*
* @param supplicantConnectpoint supplicant select point.
*/
public void setSupplicantConnectpoint(ConnectPoint supplicantConnectpoint) {
this.supplicantConnectpoint = supplicantConnectpoint;
}
/**
* Get the client id that is requesting for access.
* Gets the MAC address of the supplicant.
*
* @return supplicant MAC address
*/
public MacAddress supplicantAddress() {
return supplicantAddress;
}
/**
* Sets the supplicant MAC address.
*
* @param supplicantAddress new supplicant MAC address
*/
public void setSupplicantAddress(MacAddress supplicantAddress) {
this.supplicantAddress = supplicantAddress;
}
/**
* Gets the client's Vlan ID.
*
* @return client vlan ID
*/
public short vlanId() {
return vlanId;
}
/**
* Sets the client's vlan ID.
*
* @param vlanId new client vlan ID
*/
public void setVlanId(short vlanId) {
this.vlanId = vlanId;
}
/**
* Gets the client id that is requesting for access.
*
* @return The client id.
*/
public String getSessionId() {
public String sessionId() {
return this.sessionId;
}
......@@ -178,11 +255,11 @@ class StateMachine {
}
/**
* Get the challenge EAP identifier set by the RADIUS.
* Gets the challenge EAP identifier set by the RADIUS.
*
* @return The challenge EAP identifier.
*/
protected byte getChallengeIdentifier() {
protected byte challengeIdentifier() {
return this.challengeIdentifier;
}
......@@ -198,11 +275,11 @@ class StateMachine {
}
/**
* Get the challenge state set by the RADIUS.
* Gets the challenge state set by the RADIUS.
*
* @return The challenge state.
*/
protected byte[] getChallengeState() {
protected byte[] challengeState() {
return this.challengeState;
}
......@@ -217,16 +294,16 @@ class StateMachine {
/**
* Get the username.
* Gets the username.
*
* @return The requestAuthenticator.
*/
protected byte[] getReqeustAuthenticator() {
protected byte[] requestAuthenticator() {
return this.requestAuthenticator;
}
/**
* Set the username.
* Sets the authenticator.
*
* @param authenticator The username sent to the RADIUS upon access request.
*/
......@@ -236,11 +313,11 @@ class StateMachine {
/**
* Get the username.
* Gets the username.
*
* @return The username.
*/
protected byte[] getUsername() {
protected byte[] username() {
return this.username;
}
......@@ -249,7 +326,7 @@ class StateMachine {
*
* @return The state machine identifier.
*/
public byte getIdentifier() {
public byte identifier() {
return (byte) this.identifier;
}
......@@ -284,6 +361,7 @@ class StateMachine {
//move to the next state
next(TRANSITION_START);
createIdentifier();
identifierMap.put(identifier, this);
}
/**
......@@ -349,16 +427,16 @@ class StateMachine {
}
/**
* Get the current state.
* Gets the current state.
*
* @return The current state. Could be STATE_IDLE, STATE_STARTED, STATE_PENDING, STATE_AUTHORIZED,
* STATE_UNAUTHORIZED.
*/
public int getState() {
public int state() {
return currentState;
}
@Override
public String toString() {
return ("sessionId: " + this.sessionId) + "\t" + ("identifier: " + this.identifier) + "\t" +
("state: " + this.currentState);
......
......@@ -21,6 +21,7 @@ import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
public class StateMachineTest {
......@@ -30,6 +31,7 @@ public class StateMachineTest {
public void setUp() {
System.out.println("Set Up.");
StateMachine.bitSet.clear();
StateMachine.initializeMaps();
stateMachine = new StateMachine("session0", null);
}
......@@ -37,6 +39,7 @@ public class StateMachineTest {
public void tearDown() {
System.out.println("Tear Down.");
StateMachine.bitSet.clear();
StateMachine.destroyMaps();
stateMachine = null;
}
......@@ -46,19 +49,19 @@ public class StateMachineTest {
*/
public void basic() throws StateMachineException {
System.out.println("======= BASIC =======.");
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_IDLE);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
stateMachine.start();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_STARTED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
stateMachine.requestAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_PENDING);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
stateMachine.authorizeAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_AUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
stateMachine.logoff();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_IDLE);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
}
@Test
......@@ -68,19 +71,19 @@ public class StateMachineTest {
public void testIdleState() throws StateMachineException {
System.out.println("======= IDLE STATE TEST =======.");
stateMachine.requestAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_IDLE);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
stateMachine.authorizeAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_IDLE);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
stateMachine.denyAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_IDLE);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
stateMachine.logoff();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_IDLE);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
stateMachine.start();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_STARTED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
}
@Test
......@@ -92,19 +95,19 @@ public class StateMachineTest {
stateMachine.start();
stateMachine.authorizeAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_STARTED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
stateMachine.denyAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_STARTED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
stateMachine.logoff();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_STARTED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
stateMachine.start();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_STARTED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
stateMachine.requestAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_PENDING);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
}
@Test
......@@ -118,19 +121,19 @@ public class StateMachineTest {
stateMachine.requestAccess();
stateMachine.logoff();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_PENDING);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
stateMachine.start();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_PENDING);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
stateMachine.requestAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_PENDING);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
stateMachine.authorizeAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_AUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
stateMachine.denyAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_AUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
}
@Test
......@@ -144,19 +147,19 @@ public class StateMachineTest {
stateMachine.requestAccess();
stateMachine.logoff();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_PENDING);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
stateMachine.start();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_PENDING);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
stateMachine.requestAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_PENDING);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
stateMachine.denyAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_UNAUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
stateMachine.authorizeAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_UNAUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
}
@Test
......@@ -170,19 +173,19 @@ public class StateMachineTest {
stateMachine.authorizeAccess();
stateMachine.start();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_AUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
stateMachine.requestAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_AUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
stateMachine.authorizeAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_AUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
stateMachine.denyAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_AUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
stateMachine.logoff();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_IDLE);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
}
@Test
......@@ -196,27 +199,27 @@ public class StateMachineTest {
stateMachine.denyAccess();
stateMachine.start();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_UNAUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
stateMachine.requestAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_UNAUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
stateMachine.authorizeAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_UNAUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
stateMachine.denyAccess();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_UNAUTHORIZED);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
stateMachine.logoff();
Assert.assertEquals(stateMachine.getState(), StateMachine.STATE_IDLE);
Assert.assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
}
@Test
public void testIdentifierAvailability() throws StateMachineException {
System.out.println("======= IDENTIFIER TEST =======.");
byte identifier = stateMachine.getIdentifier();
System.out.println("State: " + stateMachine.getState());
byte identifier = stateMachine.identifier();
System.out.println("State: " + stateMachine.state());
System.out.println("Identifier: " + Byte.toUnsignedInt(identifier));
Assert.assertEquals(-1, identifier);
stateMachine.start();
......@@ -230,7 +233,7 @@ public class StateMachineTest {
for (int i = 1; i <= 255; i++) {
StateMachine sm = new StateMachine("session" + i, null);
sm.start();
byte id = sm.getIdentifier();
byte id = sm.identifier();
Assert.assertEquals(i, Byte.toUnsignedInt(id));
if (i == 3) {
sm3 = sm;
......@@ -244,27 +247,72 @@ public class StateMachineTest {
//simulate the state machine for a specific session and logoff so we can free up a spot for an identifier
//let's choose identifier 247 then we free up 3
Assert.assertNotNull(sm247);
sm247.requestAccess();
sm247.authorizeAccess();
sm247.logoff();
sm247 = null;
Assert.assertNotNull(sm3);
sm3.requestAccess();
sm3.authorizeAccess();
sm3.logoff();
sm3 = null;
StateMachine otherSM3 = new StateMachine("session3b", null);
otherSM3.start();
otherSM3.requestAccess();
byte id3 = otherSM3.getIdentifier();
byte id3 = otherSM3.identifier();
Assert.assertEquals(3, Byte.toUnsignedInt(id3));
StateMachine otherSM247 = new StateMachine("session247b", null);
otherSM247.start();
otherSM247.requestAccess();
byte id247 = otherSM247.getIdentifier();
byte id247 = otherSM247.identifier();
Assert.assertEquals(247, Byte.toUnsignedInt(id247));
}
@Test
public void testSessionIdLookups() {
String sessionId1 = "session1";
String sessionId2 = "session2";
String sessionId3 = "session3";
StateMachine machine1ShouldBeNull =
StateMachine.lookupStateMachineBySessionId(sessionId1);
assertNull(machine1ShouldBeNull);
StateMachine machine2ShouldBeNull =
StateMachine.lookupStateMachineBySessionId(sessionId2);
assertNull(machine2ShouldBeNull);
StateMachine stateMachine1 = new StateMachine(sessionId1, null);
StateMachine stateMachine2 = new StateMachine(sessionId2, null);
assertEquals(stateMachine1,
StateMachine.lookupStateMachineBySessionId(sessionId1));
assertEquals(stateMachine2,
StateMachine.lookupStateMachineBySessionId(sessionId2));
assertNull(StateMachine.lookupStateMachineBySessionId(sessionId3));
}
@Test
public void testIdentifierLookups() throws StateMachineException {
String sessionId1 = "session1";
String sessionId2 = "session2";
StateMachine machine1ShouldBeNull =
StateMachine.lookupStateMachineById((byte) 1);
assertNull(machine1ShouldBeNull);
StateMachine machine2ShouldBeNull =
StateMachine.lookupStateMachineById((byte) 2);
assertNull(machine2ShouldBeNull);
StateMachine stateMachine1 = new StateMachine(sessionId1, null);
stateMachine1.start();
StateMachine stateMachine2 = new StateMachine(sessionId2, null);
stateMachine2.start();
assertEquals(stateMachine1,
StateMachine.lookupStateMachineById(stateMachine1.identifier()));
assertEquals(stateMachine2,
StateMachine.lookupStateMachineById(stateMachine2.identifier()));
}
}
......