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/lsdb/DefaultIsisLsdb.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdb.java
new file mode 100755
index 0000000..33a0a17
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdb.java
@@ -0,0 +1,315 @@
+/*
+ * 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.lsdb;
+
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisLsdb;
+import org.onosproject.isis.controller.IsisLsdbAge;
+import org.onosproject.isis.controller.IsisLspBin;
+import org.onosproject.isis.controller.IsisMessage;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.controller.LspWrapper;
+import org.onosproject.isis.io.isispacket.pdu.LsPdu;
+import org.onosproject.isis.io.util.IsisConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Representation of ISIS link state database.
+ */
+public class DefaultIsisLsdb implements IsisLsdb {
+    private static final Logger log = LoggerFactory.getLogger(DefaultIsisLsdb.class);
+    private Map<String, LspWrapper> isisL1Db = new ConcurrentHashMap<>();
+    private Map<String, LspWrapper> isisL2Db = new ConcurrentHashMap<>();
+    private IsisLsdbAge lsdbAge = null;
+    private int l1LspSeqNo = IsisConstants.STARTLSSEQUENCENUM;
+    private int l2LspSeqNo = IsisConstants.STARTLSSEQUENCENUM;
+
+    /**
+     * Creates an instance of ISIS LSDB.
+     */
+    public DefaultIsisLsdb() {
+        lsdbAge = new DefaultIsisLsdbAge();
+    }
+
+    /**
+     * Initializes the link state database.
+     */
+    public void initializeDb() {
+        lsdbAge.startDbAging();
+    }
+
+    /**
+     * Returns the LSDB LSP key.
+     *
+     * @param systemId system ID
+     * @return key
+     */
+    public String lspKey(String systemId) {
+        StringBuilder lspKey = new StringBuilder();
+        lspKey.append(systemId);
+        lspKey.append(".00");
+        lspKey.append("-");
+        lspKey.append("00");
+
+        return lspKey.toString();
+    }
+
+    /**
+     * Returns the neighbor L1 database information.
+     *
+     * @return neighbor L1 database information
+     */
+    public Map<String, LspWrapper> getL1Db() {
+        return isisL1Db;
+    }
+
+    /**
+     * Returns the neighbor L2 database information.
+     *
+     * @return neighbor L2 database information
+     */
+    public Map<String, LspWrapper> getL2Db() {
+        return isisL2Db;
+    }
+
+    /**
+     * Returns the LSDB instance.
+     *
+     * @return LSDB instance
+     */
+    public IsisLsdb isisLsdb() {
+        return this;
+    }
+
+    /**
+     * Returns all LSPs (L1 and L2).
+     *
+     * @param excludeMaxAgeLsp exclude the max age LSPs
+     * @return List of LSPs
+     */
+    public List<LspWrapper> allLspHeaders(boolean excludeMaxAgeLsp) {
+        List<LspWrapper> summaryList = new CopyOnWriteArrayList();
+        addLspToHeaderList(summaryList, excludeMaxAgeLsp, isisL1Db);
+        addLspToHeaderList(summaryList, excludeMaxAgeLsp, isisL2Db);
+
+        return summaryList;
+    }
+
+    /**
+     * Adds the LSPs to summary list.
+     *
+     * @param summaryList      summary list
+     * @param excludeMaxAgeLsp exclude max age LSP
+     * @param lspMap           map of LSP
+     */
+    private void addLspToHeaderList(List summaryList, boolean excludeMaxAgeLsp, Map lspMap) {
+        Iterator slotVals = lspMap.values().iterator();
+        while (slotVals.hasNext()) {
+            LspWrapper wrapper = (LspWrapper) slotVals.next();
+            if (excludeMaxAgeLsp) {
+                //if current age of lsa is max age or lsa present in Max Age bin
+                if (wrapper.remainingLifetime() != 0) {
+                    addToList(wrapper, summaryList);
+                }
+            } else {
+                addToList(wrapper, summaryList);
+            }
+        }
+    }
+
+    /**
+     * Adds the LSPWrapper to summary list.
+     *
+     * @param wrapper  LSP wrapper instance
+     * @param summList LSP summary list
+     */
+    private void addToList(LspWrapper wrapper, List summList) {
+        //set the current age
+        ((LsPdu) wrapper.lsPdu()).setRemainingLifeTime(wrapper.remainingLifetime());
+        summList.add(wrapper);
+    }
+
+    /**
+     * Finds the LSP from appropriate maps L1 or L2 based on type.
+     *
+     * @param pduType L1 or L2 LSP
+     * @param lspId   LSP ID
+     * @return LSP wrapper object
+     */
+    public LspWrapper findLsp(IsisPduType pduType, String lspId) {
+        LspWrapper lspWrapper = null;
+
+        switch (pduType) {
+            case L1LSPDU:
+                lspWrapper = isisL1Db.get(lspId);
+                break;
+            case L2LSPDU:
+                lspWrapper = isisL2Db.get(lspId);
+                break;
+            default:
+                log.debug("Unknown LSP type..!!!");
+                break;
+        }
+
+        //set the current age
+        if (lspWrapper != null) {
+            //set the current age
+            ((DefaultLspWrapper) lspWrapper).lsPdu().setRemainingLifeTime(lspWrapper.remainingLifetime());
+        }
+
+        return lspWrapper;
+    }
+
+    /**
+     * Installs a new self-originated LSP.
+     *
+     * @return true if successfully added
+     */
+    public boolean addLsp(IsisMessage isisMessage, boolean isSelfOriginated, IsisInterface isisInterface) {
+        LsPdu lspdu = (LsPdu) isisMessage;
+        DefaultLspWrapper lspWrapper = new DefaultLspWrapper();
+        lspWrapper.setLspAgeReceived(IsisConstants.LSPMAXAGE - lspdu.remainingLifeTime());
+        lspWrapper.setRemainingLifetime(IsisConstants.LSPMAXAGE - lsdbAge.ageCounter());
+        lspWrapper.setLspType(IsisPduType.get(lspdu.pduType()));
+        lspWrapper.setLsPdu(lspdu);
+        lspWrapper.setAgeCounterWhenReceived(lsdbAge.ageCounter());
+        lspWrapper.setAgeCounterRollOverWhenAdded(lsdbAge.ageCounterRollOver());
+        lspWrapper.setSelfOriginated(isSelfOriginated);
+        lspWrapper.setIsisInterface(isisInterface);
+        lspWrapper.setLsdbAge(lsdbAge);
+        addLsp(lspWrapper, lspdu.lspId());
+
+        log.debug("Added LSp In LSDB: {}", lspWrapper);
+
+        return true;
+    }
+
+    /**
+     * Adds the LSP to L1 or L2 database.
+     *
+     * @param lspWrapper LSA wrapper instance
+     * @param key        key
+     * @return True if added else false
+     */
+    private boolean addLsp(LspWrapper lspWrapper, String key) {
+        //Remove the lsa from bin if exist.
+        removeLspFromBin(lspWrapper);
+
+        switch (lspWrapper.lsPdu().isisPduType()) {
+            case L1LSPDU:
+                isisL1Db.put(key, lspWrapper);
+                break;
+            case L2LSPDU:
+                isisL2Db.put(key, lspWrapper);
+                break;
+            default:
+                log.debug("Unknown LSP type to add..!!!");
+                break;
+        }
+
+        //add it to bin
+        Integer binNumber = lsdbAge.age2Bin(IsisConstants.LSPMAXAGE - lspWrapper.remainingLifetime());
+        IsisLspBin lspBin = lsdbAge.getLspBin(binNumber);
+        if (lspBin != null) {
+            //remove from existing
+            lspWrapper.setBinNumber(binNumber);
+            lspBin.addIsisLsp(key, lspWrapper);
+            lsdbAge.addLspBin(binNumber, lspBin);
+            log.debug("Added Type {} LSP to LSDB and LSABin[{}], Remaining life time of LSA {}",
+                      lspWrapper.lsPdu().isisPduType(),
+                      binNumber, lspWrapper.remainingLifetime());
+        }
+
+        return false;
+    }
+
+    /**
+     * Removes LSP from Bin.
+     *
+     * @param lsaWrapper LSP wrapper instance
+     */
+    public void removeLspFromBin(LspWrapper lsaWrapper) {
+        if (lsaWrapper != null) {
+            lsdbAge.removeLspFromBin(lsaWrapper);
+        }
+    }
+
+    /**
+     * Returns new ,latest or old according to the type of ISIS message received.
+     *
+     * @param lsp1 LSP instance
+     * @param lsp2 LSP instance
+     * @return string status
+     */
+    public String isNewerOrSameLsp(IsisMessage lsp1, IsisMessage lsp2) {
+        LsPdu receivedLsp = (LsPdu) lsp1;
+        LsPdu lspFromDb = (LsPdu) lsp2;
+        if (receivedLsp.sequenceNumber() > lspFromDb.sequenceNumber()) {
+            return "latest";
+        } else if (receivedLsp.sequenceNumber() < lspFromDb.sequenceNumber()) {
+            return "old";
+        } else if (receivedLsp.sequenceNumber() == lspFromDb.sequenceNumber()) {
+            return "same";
+        }
+
+        return "";
+    }
+
+    /**
+     * Returns the sequence number.
+     *
+     * @param lspType type of LSP
+     * @return sequence number
+     */
+    public int lsSequenceNumber(IsisPduType lspType) {
+        switch (lspType) {
+            case L1LSPDU:
+                return l1LspSeqNo++;
+            case L2LSPDU:
+                return l2LspSeqNo++;
+            default:
+                return IsisConstants.STARTLSSEQUENCENUM;
+        }
+    }
+
+    /**
+     * Deletes the given LSP.
+     *
+     * @param lspMessage LSP instance
+     */
+    public void deleteLsp(IsisMessage lspMessage) {
+        LsPdu lsp = (LsPdu) lspMessage;
+        String lspKey = lsp.lspId();
+        switch (lsp.isisPduType()) {
+            case L1LSPDU:
+                isisL1Db.remove(lspKey);
+                break;
+            case L2LSPDU:
+                isisL2Db.remove(lspKey);
+                break;
+            default:
+                log.debug("Unknown LSP type to remove..!!!");
+                break;
+        }
+    }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdbAge.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdbAge.java
new file mode 100755
index 0000000..2cf07ba
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLsdbAge.java
@@ -0,0 +1,248 @@
+/*
+ * 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.lsdb;
+
+import org.onosproject.isis.controller.IsisLsdbAge;
+import org.onosproject.isis.controller.IsisLspBin;
+import org.onosproject.isis.controller.LspWrapper;
+import org.onosproject.isis.io.isispacket.pdu.LsPdu;
+import org.onosproject.isis.io.util.IsisConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Representation of ISIS link state database ageing process.
+ */
+public class DefaultIsisLsdbAge implements IsisLsdbAge {
+    private static final Logger log = LoggerFactory.getLogger(DefaultIsisLsdbAge.class);
+    protected static int ageCounter = 0;
+    private InternalAgeTimer dbAgeTimer;
+    private ScheduledExecutorService exServiceage;
+    private Integer maxBins = 1200;
+    private Map<Integer, IsisLspBin> ageBins = new ConcurrentHashMap<>(maxBins);
+    private int ageCounterRollOver = 0;
+    private IsisLspQueueConsumer queueConsumer = null;
+    private BlockingQueue<LspWrapper> lsaQueue = new ArrayBlockingQueue<>(1024);
+
+    /**
+     * Creates an instance of LSDB age.
+     */
+    public DefaultIsisLsdbAge() {
+        // create LSBin's in the HashMap.
+        for (int i = 0; i < maxBins; i++) {
+            IsisLspBin lspBin = new DefaultIsisLspBin(i);
+            ageBins.put(i, lspBin);
+        }
+    }
+
+    /**
+     * Returns age counter.
+     *
+     * @return age counter
+     */
+    public int ageCounter() {
+        return ageCounter;
+    }
+
+    /**
+     * Returns age counter roll over.
+     *
+     * @return age counter roll over
+     */
+    public int ageCounterRollOver() {
+
+        return ageCounterRollOver;
+    }
+
+    /**
+     * Adds LSP to LS bin for ageing.
+     *
+     * @param binNumber key to store in bin
+     * @param lspBin    LSP bin instance
+     */
+    public void addLspBin(int binNumber, IsisLspBin lspBin) {
+        if (!ageBins.containsKey(binNumber)) {
+            ageBins.put(binNumber, lspBin);
+        }
+    }
+
+    /**
+     * Returns LSP from Bin.
+     *
+     * @param binKey key
+     * @return bin instance
+     */
+    public IsisLspBin getLspBin(int binKey) {
+
+        return ageBins.get(binKey);
+    }
+
+    /**
+     * Removes LSP from Bin.
+     *
+     * @param lspWrapper wrapper instance
+     */
+    public void removeLspFromBin(LspWrapper lspWrapper) {
+        if (ageBins.containsKey(lspWrapper.binNumber())) {
+            IsisLspBin lsaBin = ageBins.get(lspWrapper.binNumber());
+            lsaBin.removeIsisLsp(((LsPdu) lspWrapper.lsPdu()).lspId(), lspWrapper);
+        }
+    }
+
+    /**
+     * Returns the bin number.
+     *
+     * @param age Can be either age or ageCounter
+     * @return bin number.
+     */
+    public int age2Bin(int age) {
+        if (age <= ageCounter) {
+            return (ageCounter - age);
+        } else {
+            return ((IsisConstants.LSPMAXAGE - 1) + (ageCounter - age));
+        }
+    }
+
+    /**
+     * Starts the aging timer and queue consumer.
+     */
+    public void startDbAging() {
+        startDbAgeTimer();
+        queueConsumer = new IsisLspQueueConsumer(lsaQueue);
+        new Thread(queueConsumer).start();
+    }
+
+    /**
+     * Starts DB aging task.
+     */
+    private void startDbAgeTimer() {
+        dbAgeTimer = new InternalAgeTimer();
+        //from 1 sec
+        exServiceage = Executors.newSingleThreadScheduledExecutor();
+        exServiceage.scheduleAtFixedRate(dbAgeTimer, 1, 1, TimeUnit.SECONDS);
+    }
+
+    /**
+     * Gets called every second as part of the aging process.
+     */
+    public void ageLsp() {
+        refreshLsa();
+        maxAgeLsa();
+
+        if (ageCounter == IsisConstants.LSPMAXAGE) {
+            ageCounter = 0;
+            ageCounterRollOver++;
+        } else {
+            ageCounter++;
+        }
+    }
+
+    /**
+     * If the LSP have completed the MaxAge - they are moved called stop aging.
+     */
+    public void maxAgeLsa() {
+        if (ageCounter == 0) {
+            return;
+        }
+        //Get from Age Bins
+        IsisLspBin lspBin = ageBins.get(ageCounter - 1);
+        if (lspBin == null) {
+            return;
+        }
+        Map lspBinMap = lspBin.listOfLsp();
+        for (Object key : lspBinMap.keySet()) {
+            LspWrapper lspWrapper = (LspWrapper) lspBinMap.get((String) key);
+            if (lspWrapper.currentAge() == IsisConstants.LSPMAXAGE) {
+                lspWrapper.setLspProcessing(IsisConstants.MAXAGELSP);
+                log.debug("Lsp picked for maxage removal. Age Counter: {}, AgeCounterRollover: {}, " +
+                                  "AgeCounterRollover WhenAddedToDb: {}, LSA Type: {}, LSA Key: {}",
+                          ageCounter, ageCounterRollOver, lspWrapper.currentAge(),
+                          lspWrapper.lsPdu().isisPduType(), key);
+                //add it to lspQueue for processing
+                try {
+                    lsaQueue.put(lspWrapper);
+                    //remove from bin
+                    lspBin.removeIsisLsp((String) key, lspWrapper);
+                } catch (InterruptedException e) {
+                    log.debug("Error::LSDBAge::maxAgeLsp::{}", e.getMessage());
+                }
+            }
+        }
+
+    }
+
+    /*
+     * If the LSP is in age bin of 900s- it's pushed into refresh list.
+     */
+    public void refreshLsa() {
+        int binNumber;
+        if (ageCounter < IsisConstants.LSPREFRESH) {
+            binNumber = ageCounter + IsisConstants.LSPREFRESH;
+        } else {
+            binNumber = ageCounter - IsisConstants.LSPREFRESH;
+        }
+        if (binNumber > IsisConstants.LSPMAXAGE) {
+            binNumber = binNumber - IsisConstants.LSPMAXAGE;
+        }
+        IsisLspBin lspBin = ageBins.get(binNumber);
+        if (lspBin == null) {
+            return;
+        }
+        Map lspBinMap = lspBin.listOfLsp();
+        for (Object key : lspBinMap.keySet()) {
+            LspWrapper lsp = (LspWrapper) lspBinMap.get((String) key);
+            try {
+                if (lsp.isSelfOriginated()) {
+                    log.debug("Lsp picked for refreshLsp. binNumber: {}, LSA Type: {}, LSA Key: {}",
+                              binNumber, lsp.lspType(), key);
+                    lsp.setLspProcessing(IsisConstants.REFRESHLSP);
+                    lsaQueue.put(lsp);
+                    //remove from bin
+                    lspBin.removeIsisLsp((String) key, lsp);
+                }
+            } catch (InterruptedException e) {
+                log.debug("Error::LSDBAge::refreshLsp::{}", e.getMessage());
+            }
+        }
+    }
+
+
+    /**
+     * Runnable task which runs every second and calls aging process.
+     */
+    private class InternalAgeTimer implements Runnable {
+
+        /**
+         * Creates an instance of age timer task.
+         */
+        InternalAgeTimer() {
+            log.debug("Starts::IsisLsdbAge::AgeTimer...!!! ");
+        }
+
+        @Override
+        public void run() {
+            ageLsp();
+        }
+    }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLspBin.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLspBin.java
new file mode 100755
index 0000000..2505c90
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultIsisLspBin.java
@@ -0,0 +1,104 @@
+/*
+ * 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.lsdb;
+
+import com.google.common.base.MoreObjects;
+import org.onosproject.isis.controller.IsisLspBin;
+import org.onosproject.isis.controller.LspWrapper;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Representation of LSP bin, where an LSP is stored for Aging.
+ * A bin is identified by a bin number and can have one or more LSPs
+ * store in a particular bin location
+ */
+public class DefaultIsisLspBin implements IsisLspBin {
+    private int binNumber;
+    private Map<String, LspWrapper> listOfLsp = new ConcurrentHashMap<>();
+
+    /**
+     * Creates ISIS LSP bin instance.
+     *
+     * @param binNumber bin number
+     */
+    public DefaultIsisLspBin(int binNumber) {
+        this.binNumber = binNumber;
+    }
+
+    /**
+     * Adds the LSP to wrapper.
+     *
+     * @param lspKey     key to add the LSP
+     * @param lspWrapper LSP wrapper instance
+     */
+    public void addIsisLsp(String lspKey, LspWrapper lspWrapper) {
+        if (!listOfLsp.containsKey(lspKey)) {
+            listOfLsp.put(lspKey, lspWrapper);
+            lspWrapper.setBinNumber(this.binNumber);
+        }
+    }
+
+    /**
+     * Returns the LSP wrapper.
+     *
+     * @param lspKey LSP key
+     * @return LSP wrapper
+     */
+    public LspWrapper isisLsp(String lspKey) {
+        return listOfLsp.get(lspKey);
+    }
+
+    /**
+     * Removes ISIS LSP from database.
+     *
+     * @param lspKey     LSP key
+     * @param lspWrapper LSP wrapper instance
+     */
+    public void removeIsisLsp(String lspKey, LspWrapper lspWrapper) {
+        if (listOfLsp.containsKey(lspKey)) {
+            listOfLsp.remove(lspKey);
+        }
+    }
+
+    /**
+     * Returns all LSP wrappers.
+     *
+     * @return all LSP wrappers
+     */
+    public Map<String, LspWrapper> listOfLsp() {
+        return listOfLsp;
+    }
+
+    /**
+     * Returns the bin number.
+     *
+     * @return the bin number
+     */
+    public int binNumber() {
+        return binNumber;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .omitNullValues()
+                .add("binNumber", binNumber)
+                .add("listOfLsp", listOfLsp)
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultLspWrapper.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultLspWrapper.java
new file mode 100755
index 0000000..b89e88f
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/DefaultLspWrapper.java
@@ -0,0 +1,267 @@
+/*
+ * 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.lsdb;
+
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisLsdbAge;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.controller.LspWrapper;
+import org.onosproject.isis.io.isispacket.pdu.LsPdu;
+import org.onosproject.isis.io.util.IsisConstants;
+
+/**
+ * Representation of LSP wrapper where the LSPs are stored with metadata.
+ */
+public class DefaultLspWrapper implements LspWrapper {
+    private int binNumber = -1;
+    private boolean selfOriginated = false;
+    private IsisPduType lspType;
+    private int lspAgeReceived;
+    private int ageCounterWhenReceived;
+    private LsPdu lsPdu;
+    private IsisLsdbAge lsdbAge;
+    private int ageCounterRollOverWhenAdded;
+    private int remainingLifetime;
+    private IsisInterface isisInterface;
+    private String lspProcessing;
+
+    /**
+     * Returns "refreshLsp" or "maxageLsp" based on LSP to process.
+     *
+     * @return LSP processing string
+     */
+    public String lspProcessing() {
+        return lspProcessing;
+    }
+
+    /**
+     * Sets LSP processing "refreshLsp" or "maxageLsp" based on LSP to process.
+     *
+     * @param lspProcessing "refreshLsp" or "maxageLsp" based on LSP to process
+     */
+    public void setLspProcessing(String lspProcessing) {
+        this.lspProcessing = lspProcessing;
+    }
+
+    /**
+     * Returns LSP age received.
+     *
+     * @return LSP age received
+     */
+    public int lspAgeReceived() {
+        return lspAgeReceived;
+    }
+
+    /**
+     * Sets LSP age received.
+     *
+     * @param lspAgeReceived LSP age received.
+     */
+    public void setLspAgeReceived(int lspAgeReceived) {
+        this.lspAgeReceived = lspAgeReceived;
+    }
+
+    /**
+     * Returns ISIS interface instance.
+     *
+     * @return ISIS interface instance
+     */
+    public IsisInterface isisInterface() {
+        return isisInterface;
+    }
+
+    /**
+     * Sets ISIS interface.
+     *
+     * @param isisInterface ISIS interface instance
+     */
+    public void setIsisInterface(IsisInterface isisInterface) {
+        this.isisInterface = isisInterface;
+    }
+
+    /**
+     * Returns age counter when received.
+     *
+     * @return age counter when received
+     */
+    public int ageCounterWhenReceived() {
+
+        return ageCounterWhenReceived;
+    }
+
+    /**
+     * Sets age counter when received.
+     *
+     * @param ageCounterWhenReceived age counter when received
+     */
+    public void setAgeCounterWhenReceived(int ageCounterWhenReceived) {
+        this.ageCounterWhenReceived = ageCounterWhenReceived;
+    }
+
+    /**
+     * Returns age counter roll over.
+     *
+     * @return age counter roll over
+     */
+    public int ageCounterRollOverWhenAdded() {
+        return ageCounterRollOverWhenAdded;
+    }
+
+    /**
+     * Sets age counter roll over when added.
+     *
+     * @param ageCounterRollOverWhenAdded age counter roll over when added
+     */
+    public void setAgeCounterRollOverWhenAdded(int ageCounterRollOverWhenAdded) {
+        this.ageCounterRollOverWhenAdded = ageCounterRollOverWhenAdded;
+    }
+
+    /**
+     * Returns bin number.
+     *
+     * @return bin number
+     */
+    public int binNumber() {
+        return binNumber;
+    }
+
+    /**
+     * Sets bin number.
+     *
+     * @param binNumber bin number
+     */
+    public void setBinNumber(int binNumber) {
+        this.binNumber = binNumber;
+    }
+
+    /**
+     * Returns true if self originated.
+     *
+     * @return true if self originated.
+     */
+    public boolean isSelfOriginated() {
+        return selfOriginated;
+    }
+
+    /**
+     * Sets true if self originated.
+     *
+     * @param selfOriginated true if self originated else false
+     */
+    public void setSelfOriginated(boolean selfOriginated) {
+        this.selfOriginated = selfOriginated;
+    }
+
+    /**
+     * Returns ISIS PDU type.
+     *
+     * @return ISIS PDU type
+     */
+    public IsisPduType lspType() {
+        return lspType;
+    }
+
+    /**
+     * Sets ISIS PDU type.
+     *
+     * @param lspType ISIS PDU type
+     */
+    public void setLspType(IsisPduType lspType) {
+        this.lspType = lspType;
+    }
+
+    /**
+     * Returns LSPDU which the wrapper contains.
+     *
+     * @return LSPDU which the wrapper contains
+     */
+    public LsPdu lsPdu() {
+        return lsPdu;
+    }
+
+    /**
+     * Sets LSPDU which the wrapper contains.
+     *
+     * @param lsPdu LSPDU which the wrapper contains
+     */
+    public void setLsPdu(LsPdu lsPdu) {
+        this.lsPdu = lsPdu;
+    }
+
+    /**
+     * Returns ISIS LSDB age.
+     *
+     * @return ISIS LSDB age
+     */
+    public IsisLsdbAge lsdbAge() {
+        return lsdbAge;
+    }
+
+    /**
+     * Sets LSDB age.
+     *
+     * @param lsdbAge LSDB age
+     */
+    public void setLsdbAge(IsisLsdbAge lsdbAge) {
+        this.lsdbAge = lsdbAge;
+    }
+
+    /**
+     * Returns the current LSP Age.
+     *
+     * @return LSP age
+     */
+    public int currentAge() {
+
+        int currentAge = 0;
+        //ls age received
+        if (lsdbAge.ageCounter() >= ageCounterWhenReceived) {
+            currentAge = lspAgeReceived + (lsdbAge.ageCounter() - ageCounterWhenReceived);
+        } else {
+            currentAge = lspAgeReceived + ((IsisConstants.LSPMAXAGE + lsdbAge.ageCounter())
+                    - ageCounterWhenReceived);
+        }
+
+        if (currentAge >= IsisConstants.LSPMAXAGE) {
+            return IsisConstants.LSPMAXAGE;
+        } else if ((currentAge == lspAgeReceived) && ageCounterRollOverWhenAdded
+                != lsdbAge.ageCounterRollOver()) {
+            return IsisConstants.LSPMAXAGE;
+        }
+
+        return currentAge;
+    }
+
+    /**
+     * Returns remaining time.
+     *
+     * @return remaining time
+     */
+    public int remainingLifetime() {
+        //Calculate the remaining lifetime
+        remainingLifetime = IsisConstants.LSPMAXAGE - lsdbAge.ageCounter();
+        return remainingLifetime;
+    }
+
+    /**
+     * Sets remaining life time.
+     *
+     * @param remainingLifetime LSPs remaining life time
+     */
+    public void setRemainingLifetime(int remainingLifetime) {
+        this.remainingLifetime = remainingLifetime;
+    }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/IsisLspQueueConsumer.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/IsisLspQueueConsumer.java
new file mode 100755
index 0000000..9007093
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/IsisLspQueueConsumer.java
@@ -0,0 +1,128 @@
+/*
+ * 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.lsdb;
+
+import org.jboss.netty.channel.Channel;
+import org.onosproject.isis.controller.IsisLsdb;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.controller.LspWrapper;
+import org.onosproject.isis.controller.impl.DefaultIsisInterface;
+import org.onosproject.isis.io.isispacket.pdu.LsPdu;
+import org.onosproject.isis.io.util.IsisConstants;
+import org.onosproject.isis.io.util.IsisUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.BlockingQueue;
+
+/**
+ * Representation of LSP queue consumer.
+ */
+public class IsisLspQueueConsumer implements Runnable {
+    private static final Logger log = LoggerFactory.getLogger(IsisLspQueueConsumer.class);
+    private BlockingQueue queue = null;
+
+    /**
+     * Creates an instance of LSP queue consumer.
+     *
+     * @param queue queue instance
+     */
+    public IsisLspQueueConsumer(BlockingQueue queue) {
+        this.queue = queue;
+    }
+
+    /**
+     * Gets the LSP wrapper instance from queue and process it.
+     */
+    @Override
+    public void run() {
+        log.debug("LSPQueueConsumer:run...!!!");
+        try {
+            while (true) {
+                if (!queue.isEmpty()) {
+                    LspWrapper wrapper = (LspWrapper) queue.take();
+                    String lspProcessing = wrapper.lspProcessing();
+                    switch (lspProcessing) {
+                        case IsisConstants.REFRESHLSP:
+                            log.debug("LSPQueueConsumer: Message - " + IsisConstants.REFRESHLSP +
+                                              " consumed.");
+                            processRefreshLsp(wrapper);
+                            break;
+                        case IsisConstants.MAXAGELSP:
+                            log.debug("LSPQueueConsumer: Message - " + IsisConstants.MAXAGELSP +
+                                              " consumed.");
+                            processMaxAgeLsa(wrapper);
+                            break;
+                        default:
+                            log.debug("Unknown command to process the LSP in queue ...!!!");
+                            break;
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            log.debug("Error::LSPQueueConsumer::{}", e.getMessage());
+        }
+    }
+
+    /**
+     * Process refresh LSP.
+     *
+     * @param wrapper LSP wrapper instance
+     */
+    private void processRefreshLsp(LspWrapper wrapper) throws Exception {
+        if (wrapper.isSelfOriginated()) { //self originated
+            DefaultIsisInterface isisInterface = (DefaultIsisInterface) wrapper.isisInterface();
+            Channel channel = isisInterface.channel();
+            if (channel != null && channel.isConnected()) {
+                LsPdu lsPdu = (LsPdu) wrapper.lsPdu();
+                lsPdu.setSequenceNumber(isisInterface.isisLsdb().lsSequenceNumber(
+                        IsisPduType.get(lsPdu.pduType())));
+                lsPdu.setRemainingLifeTime(IsisConstants.LSPMAXAGE);
+                byte[] lspBytes = lsPdu.asBytes();
+                lspBytes = IsisUtil.addLengthAndMarkItInReserved(lspBytes, IsisConstants.LENGTHPOSITION,
+                                                                 IsisConstants.LENGTHPOSITION + 1,
+                                                                 IsisConstants.RESERVEDPOSITION);
+                lspBytes = IsisUtil.addChecksum(lspBytes, IsisConstants.CHECKSUMPOSITION,
+                                                IsisConstants.CHECKSUMPOSITION + 1);
+                //write to the channel
+                channel.write(IsisUtil.framePacket(lspBytes, isisInterface.interfaceIndex()));
+
+                log.debug("LSPQueueConsumer: processRefreshLsp - Flooded SelfOriginated LSP {}",
+                          wrapper.lsPdu());
+            }
+
+        }
+    }
+
+    /**
+     * Process max age LSP.
+     *
+     * @param wrapper LSP wrapper instance
+     */
+    private void processMaxAgeLsa(LspWrapper wrapper) {
+        //set the destination
+        DefaultIsisInterface isisInterface = (DefaultIsisInterface) wrapper.isisInterface();
+        if (isisInterface != null) {
+            //delete from db
+            LsPdu lsPdu = (LsPdu) wrapper.lsPdu();
+            IsisLsdb isisDb = isisInterface.isisLsdb();
+            isisDb.deleteLsp(lsPdu);
+            log.debug("LSPQueueConsumer: processMaxAgeLsp - Removed-Max Age LSP {}",
+                      wrapper.lsPdu());
+        }
+    }
+}
\ No newline at end of file
diff --git a/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/package-info.java b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/package-info.java
new file mode 100755
index 0000000..cbab4b4
--- /dev/null
+++ b/protocols/isis/ctl/src/main/java/org/onosproject/isis/controller/impl/lsdb/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Implementation of the ISIS controller LSDB and related functionality.
+ */
+package org.onosproject.isis.controller.impl.lsdb;
\ No newline at end of file