ONOS-4086 to ONOS-4091, ONOS-4098 to ONOS-4100:ISIS controller implementation

Change-Id: I7be52805652fe762baf808515401d6b5042b2aa5
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisNeighbor.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisNeighbor.java
new file mode 100755
index 0000000..3180c5d
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/DefaultIsisNeighbor.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.onosproject.isis.controller.impl;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisInterfaceState;
+import org.onosproject.isis.controller.IsisNeighbor;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.controller.IsisRouterType;
+import org.onosproject.isis.io.isispacket.pdu.HelloPdu;
+import org.onosproject.isis.io.isispacket.pdu.L1L2HelloPdu;
+import org.onosproject.isis.io.isispacket.pdu.P2PHelloPdu;
+import org.onosproject.isis.io.util.IsisConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Representation of an ISIS neighbor.
+ * The first thing an ISIS router must do is find its neighbors and form adjacency.
+ * Each neighbor that the router finds will be represented by this class.
+ */
+public class DefaultIsisNeighbor implements IsisNeighbor {
+    private static final Logger log = LoggerFactory.getLogger(DefaultIsisNeighbor.class);
+    private String neighborAreaId;
+    private String neighborSystemId;
+    private Ip4Address interfaceIp;
+    private MacAddress neighborMacAddress;
+    private int holdingTime;
+    private IsisRouterType routerType;
+    private String l1LanId;
+    private String l2LanId;
+    private byte localCircuitId;
+    private int localExtendedCircuitId;
+    private IsisInterfaceState neighborState = IsisInterfaceState.INITIAL;
+    private InternalInactivityTimeCheck inActivityTimeCheckTask;
+    private ScheduledExecutorService exServiceInActivity;
+    private boolean inActivityTimerScheduled = false;
+    private IsisInterface isisInterface;
+
+    /**
+     * Creates an instance of ISIS neighbor.
+     *
+     * @param helloMessage  hello message instance
+     * @param isisInterface ISIS interface instance
+     */
+    public DefaultIsisNeighbor(HelloPdu helloMessage, IsisInterface isisInterface) {
+        this.neighborMacAddress = helloMessage.sourceMac();
+        List<String> areaAddresses = helloMessage.areaAddress();
+        this.neighborAreaId = (areaAddresses != null) ? areaAddresses.get(0) : "";
+        this.neighborSystemId = helloMessage.sourceId();
+        List<Ip4Address> interfaceIpAddresses = helloMessage.interfaceIpAddresses();
+        this.interfaceIp = (helloMessage.interfaceIpAddresses() != null) ?
+                interfaceIpAddresses.get(0) : IsisConstants.DEFAULTIP;
+        this.holdingTime = helloMessage.holdingTime();
+        this.routerType = IsisRouterType.get(helloMessage.circuitType());
+        if (helloMessage instanceof L1L2HelloPdu) {
+            if (IsisPduType.L1HELLOPDU == helloMessage.isisPduType()) {
+                l1LanId = ((L1L2HelloPdu) helloMessage).lanId();
+            } else if (IsisPduType.L2HELLOPDU == helloMessage.isisPduType()) {
+                l2LanId = ((L1L2HelloPdu) helloMessage).lanId();
+            }
+        } else if (helloMessage instanceof P2PHelloPdu) {
+            this.localCircuitId = ((P2PHelloPdu) helloMessage).localCircuitId();
+        }
+        this.isisInterface = isisInterface;
+    }
+
+    /**
+     * Returns local extended circuit ID.
+     *
+     * @return local extended circuit ID
+     */
+    public int localExtendedCircuitId() {
+        return localExtendedCircuitId;
+    }
+
+    /**
+     * Sets local extended circuit ID.
+     *
+     * @param localExtendedCircuitId neighbor extended circuit ID
+     */
+    public void setLocalExtendedCircuitId(int localExtendedCircuitId) {
+        this.localExtendedCircuitId = localExtendedCircuitId;
+    }
+
+    /**
+     * Returns neighbor area ID.
+     *
+     * @return neighbor area ID
+     */
+    public String neighborAreaId() {
+        return neighborAreaId;
+    }
+
+    /**
+     * Sets neighbor area ID.
+     *
+     * @param neighborAreaId neighbor area ID
+     */
+    public void setNeighborAreaId(String neighborAreaId) {
+        this.neighborAreaId = neighborAreaId;
+    }
+
+    /**
+     * Returns neighbor system ID.
+     *
+     * @return neighbor system ID
+     */
+    public String neighborSystemId() {
+        return neighborSystemId;
+    }
+
+    /**
+     * Sets neighbor system ID.
+     *
+     * @param neighborSystemId neighbor system ID
+     */
+    public void setNeighborSystemId(String neighborSystemId) {
+        this.neighborSystemId = neighborSystemId;
+    }
+
+    /**
+     * Returns interface IP.
+     *
+     * @return interface IP
+     */
+    public Ip4Address interfaceIp() {
+        return interfaceIp;
+    }
+
+    /**
+     * Sets interface IP.
+     *
+     * @param interfaceIp IP
+     */
+    public void setInterfaceIp(Ip4Address interfaceIp) {
+        this.interfaceIp = interfaceIp;
+    }
+
+    /**
+     * Returns neighbor mac address.
+     *
+     * @return neighborMacAddress neighbor mac address
+     */
+    public MacAddress neighborMacAddress() {
+        return neighborMacAddress;
+    }
+
+    /**
+     * Sets neighbor mac address.
+     *
+     * @param neighborMacAddress mac address
+     */
+    public void setNeighborMacAddress(MacAddress neighborMacAddress) {
+        this.neighborMacAddress = neighborMacAddress;
+    }
+
+    /**
+     * Returns holding time.
+     *
+     * @return holding time
+     */
+    public int holdingTime() {
+        return holdingTime;
+    }
+
+    /**
+     * Sets holding time.
+     *
+     * @param holdingTime holding time
+     */
+    public void setHoldingTime(int holdingTime) {
+        this.holdingTime = holdingTime;
+    }
+
+    /**
+     * Returns router type.
+     *
+     * @return router type
+     */
+    public IsisRouterType routerType() {
+        return routerType;
+    }
+
+    /**
+     * Sets router type.
+     *
+     * @param routerType router type
+     */
+    public void setRouterType(IsisRouterType routerType) {
+        this.routerType = routerType;
+    }
+
+    /**
+     * Returns L1 lan ID.
+     *
+     * @return L1 lan ID
+     */
+    public String l1LanId() {
+        return l1LanId;
+    }
+
+    /**
+     * Sets L1 lan ID.
+     *
+     * @param l1LanId L1 lan ID
+     */
+    public void setL1LanId(String l1LanId) {
+        this.l1LanId = l1LanId;
+    }
+
+    /**
+     * Returns L2 lan ID.
+     *
+     * @return L2 lan ID
+     */
+    public String l2LanId() {
+        return l2LanId;
+    }
+
+    /**
+     * Sets L2 lan ID.
+     *
+     * @param l2LanId L2 lan ID
+     */
+    public void setL2LanId(String l2LanId) {
+        this.l1LanId = l1LanId;
+    }
+
+    /**
+     * Gets the neighbor interface state.
+     *
+     * @return neighbor interface state
+     */
+    public IsisInterfaceState interfaceState() {
+        return neighborState;
+    }
+
+    /**
+     * Sets the neighbor interface state.
+     *
+     * @param neighborState the neighbor interface state
+     */
+    public void setNeighborState(IsisInterfaceState neighborState) {
+        this.neighborState = neighborState;
+    }
+
+    /**
+     * Returns local circuit ID.
+     *
+     * @return local circuit ID
+     */
+    public byte localCircuitId() {
+        return localCircuitId;
+    }
+
+    /**
+     * Sets local circuit ID.
+     *
+     * @param localCircuitId local circuit ID
+     */
+    public void setLocalCircuitId(byte localCircuitId) {
+        this.localCircuitId = localCircuitId;
+    }
+
+    /**
+     * Returns neighbor state.
+     *
+     * @return neighbor state
+     */
+    public IsisInterfaceState neighborState() {
+        return neighborState;
+    }
+
+    /**
+     * Starts the inactivity timer.
+     */
+    public void startInactivityTimeCheck() {
+        if (!inActivityTimerScheduled) {
+            log.debug("IsisNeighbor::startInactivityTimeCheck");
+            inActivityTimeCheckTask = new InternalInactivityTimeCheck();
+            exServiceInActivity = Executors.newSingleThreadScheduledExecutor();
+            exServiceInActivity.scheduleAtFixedRate(inActivityTimeCheckTask, holdingTime,
+                                                    holdingTime, TimeUnit.SECONDS);
+            inActivityTimerScheduled = true;
+        }
+    }
+
+    /**
+     * Stops the inactivity timer.
+     */
+    public void stopInactivityTimeCheck() {
+        if (inActivityTimerScheduled) {
+            log.debug("IsisNeighbor::stopInactivityTimeCheck ");
+            exServiceInActivity.shutdown();
+            inActivityTimerScheduled = false;
+        }
+    }
+
+    /**
+     * Called when neighbor is down.
+     */
+    public void neighborDown() {
+        log.debug("Neighbor Down {} and NeighborSystemId {}", neighborMacAddress,
+                  neighborSystemId);
+        stopInactivityTimeCheck();
+        isisInterface.setL1LanId(IsisConstants.DEFAULTLANID);
+        isisInterface.setL2LanId(IsisConstants.DEFAULTLANID);
+
+        neighborState = IsisInterfaceState.DOWN;
+        isisInterface.removeNeighbor(this);
+    }
+
+    /**
+     * Represents a Task which will do an inactivity time check.
+     */
+    private class InternalInactivityTimeCheck implements Runnable {
+        /**
+         * Creates an instance.
+         */
+        InternalInactivityTimeCheck() {
+        }
+
+        @Override
+        public void run() {
+            log.debug("Neighbor Not Heard till the past router dead interval .");
+            neighborDown();
+        }
+    }
+}
\ No newline at end of file