[SEBA-593] Splitting aaa app in implementation and api bundles
Change-Id: Ib81650be0695258bdd1f4cd6131f2206760e0da6
diff --git a/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java b/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java
new file mode 100644
index 0000000..2e21ea3
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed 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.opencord.aaa.impl;
+
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.EAP;
+import org.onlab.packet.EAPOL;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+
+import org.onosproject.net.Annotations;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Element;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.DefaultPacketContext;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketServiceAdapter;
+
+import org.opencord.sadis.BandwidthProfileInformation;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+
+import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.onosproject.net.NetTestTools.connectPoint;
+
+/**
+ * Common methods for AAA app testing.
+ */
+public class AaaTestBase {
+
+ MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
+ MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a");
+
+ // Our session id will be the device ID ("of:1") with the port ("1") concatenated
+ static final String SESSION_ID = "of:11";
+
+ List<BasePacket> savedPackets = new LinkedList<>();
+ PacketProcessor packetProcessor;
+
+ /**
+ * Saves the given packet onto the saved packets list.
+ *
+ * @param packet packet to save
+ */
+ void savePacket(BasePacket packet) {
+ savedPackets.add(packet);
+ }
+
+ /**
+ * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
+ */
+ class MockPacketService extends PacketServiceAdapter {
+
+ @Override
+ public void addProcessor(PacketProcessor processor, int priority) {
+ packetProcessor = processor;
+ }
+
+ @Override
+ public void emit(OutboundPacket packet) {
+ try {
+ Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
+ 0, packet.data().array().length);
+ savePacket(eth);
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Mocks the DeviceService.
+ */
+ final class TestDeviceService extends DeviceServiceAdapter {
+ @Override
+ public Port getPort(ConnectPoint cp) {
+ return new MockPort();
+ }
+ }
+ private class MockPort implements Port {
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+ public long portSpeed() {
+ return 1000;
+ }
+ public Element element() {
+ return null;
+ }
+ public PortNumber number() {
+ return null;
+ }
+ public Annotations annotations() {
+ return new MockAnnotations();
+ }
+ public Type type() {
+ return Port.Type.FIBER;
+ }
+
+ private class MockAnnotations implements Annotations {
+
+ @Override
+ public String value(String val) {
+ return "PON 1/1";
+ }
+ public Set<String> keys() {
+ return null;
+ }
+ }
+ }
+
+ private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
+
+ MockSubscriberAndDeviceInformation(String id, VlanId ctag,
+ VlanId stag, String nasPortId,
+ String circuitId, MacAddress hardId,
+ Ip4Address ipAddress) {
+ this.setCTag(ctag);
+ this.setHardwareIdentifier(hardId);
+ this.setId(id);
+ this.setIPAddress(ipAddress);
+ this.setSTag(stag);
+ this.setNasPortId(nasPortId);
+ this.setCircuitId(circuitId);
+ }
+ }
+
+ final class MockSadisService implements SadisService {
+
+ @Override
+ public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
+ return new MockSubService();
+ }
+
+ @Override
+ public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
+ return null;
+ }
+ }
+
+ final class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
+ private final VlanId clientCtag = VlanId.vlanId((short) 999);
+ private final VlanId clientStag = VlanId.vlanId((short) 111);
+ private final String clientNasPortId = "PON 1/1";
+ private final String clientCircuitId = "CIR-PON 1/1";
+
+ MockSubscriberAndDeviceInformation sub =
+ new MockSubscriberAndDeviceInformation(clientNasPortId, clientCtag,
+ clientStag, clientNasPortId, clientCircuitId, null, null);
+ @Override
+ public SubscriberAndDeviceInformation get(String id) {
+
+ return sub;
+
+ }
+
+ @Override
+ public void invalidateAll() {}
+ public void invalidateId(String id) {}
+ public SubscriberAndDeviceInformation getfromCache(String id) {
+ return null;
+ }
+ }
+ /**
+ * Mocks the DefaultPacketContext.
+ */
+ final class TestPacketContext extends DefaultPacketContext {
+
+ private TestPacketContext(long time, InboundPacket inPkt,
+ OutboundPacket outPkt, boolean block) {
+ super(time, inPkt, outPkt, block);
+ }
+
+ @Override
+ public void send() {
+ // We don't send anything out.
+ }
+ }
+
+ /**
+ * Sends an Ethernet packet to the process method of the Packet Processor.
+ *
+ * @param reply Ethernet packet
+ */
+ void sendPacket(Ethernet reply) {
+ final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
+ InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
+ reply,
+ byteBuffer);
+
+ PacketContext context = new TestPacketContext(127L, inPacket, null, false);
+ packetProcessor.process(context);
+ }
+
+ /**
+ * Constructs an Ethernet packet containing identification payload.
+ *
+ * @return Ethernet packet
+ */
+ Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine,
+ byte type,
+ byte id,
+ Ethernet radiusChallenge)
+ throws Exception {
+ Ethernet eth = new Ethernet();
+ eth.setDestinationMACAddress(clientMac.toBytes());
+ eth.setSourceMACAddress(serverMac.toBytes());
+ eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+ eth.setVlanID((short) 2);
+
+ String username = "testuser";
+ byte[] data = username.getBytes();
+
+
+ if (type == EAP.ATTR_MD5) {
+ String password = "testpassword";
+ EAPOL eapol = (EAPOL) radiusChallenge.getPayload();
+ EAP eap = (EAP) eapol.getPayload();
+
+ byte[] identifier = new byte[password.length() + eap.getData().length];
+
+ identifier[0] = stateMachine.challengeIdentifier();
+ System.arraycopy(password.getBytes(), 0, identifier, 1, password.length());
+ System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16);
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ byte[] hash = md.digest(identifier);
+ data = new byte[17];
+ data[0] = (byte) 16;
+ System.arraycopy(hash, 0, data, 1, 16);
+ }
+ EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type,
+ data);
+ eap.setIdentifier(id);
+
+ // eapol header
+ EAPOL eapol = new EAPOL();
+ eapol.setEapolType(EAPOL.EAPOL_PACKET);
+ eapol.setPacketLength(eap.getLength());
+
+ // eap part
+ eapol.setPayload(eap);
+
+ eth.setPayload(eapol);
+ eth.setPad(true);
+ return eth;
+ }
+
+ /**
+ * Constructs an Ethernet packet containing a EAPOL_START Payload.
+ *
+ * @return Ethernet packet
+ */
+ Ethernet constructSupplicantStartPacket() {
+ Ethernet eth = new Ethernet();
+ eth.setDestinationMACAddress(clientMac.toBytes());
+ eth.setSourceMACAddress(serverMac.toBytes());
+ eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+ eth.setVlanID((short) 2);
+
+ EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 2, EAPOL.EAPOL_START, null);
+
+ // eapol header
+ EAPOL eapol = new EAPOL();
+ eapol.setEapolType(EAPOL.EAPOL_START);
+ eapol.setPacketLength(eap.getLength());
+
+ // eap part
+ eapol.setPayload(eap);
+
+ eth.setPayload(eapol);
+ eth.setPad(true);
+ return eth;
+ }
+
+ /**
+ * Checks the contents of a RADIUS packet being sent to the RADIUS server.
+ *
+ * @param radiusPacket packet to check
+ * @param code expected code
+ */
+ void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) {
+
+ assertThat(radiusPacket.getSourceMAC(),
+ is(MacAddress.valueOf(aaaManager.nasMacAddress)));
+ assertThat(radiusPacket.getDestinationMAC(), is(serverMac));
+
+ assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
+ EAPOL eapol = (EAPOL) radiusPacket.getPayload();
+ assertThat(eapol, notNullValue());
+
+ assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
+ assertThat(eapol.getPayload(), instanceOf(EAP.class));
+ EAP eap = (EAP) eapol.getPayload();
+ assertThat(eap, notNullValue());
+
+ assertThat(eap.getCode(), is(code));
+ }
+}