blob: 2cf07ba80b5f5f92b67bb389d5e3e3e8fbe22ea1 [file] [log] [blame]
tejeshwer degala3fe1ed52016-04-22 17:04:01 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.isis.controller.impl.lsdb;
17
18import org.onosproject.isis.controller.IsisLsdbAge;
19import org.onosproject.isis.controller.IsisLspBin;
20import org.onosproject.isis.controller.LspWrapper;
21import org.onosproject.isis.io.isispacket.pdu.LsPdu;
22import org.onosproject.isis.io.util.IsisConstants;
23import org.slf4j.Logger;
24import org.slf4j.LoggerFactory;
25
26import java.util.Map;
27import java.util.concurrent.ArrayBlockingQueue;
28import java.util.concurrent.BlockingQueue;
29import java.util.concurrent.ConcurrentHashMap;
30import java.util.concurrent.Executors;
31import java.util.concurrent.ScheduledExecutorService;
32import java.util.concurrent.TimeUnit;
33
34/**
35 * Representation of ISIS link state database ageing process.
36 */
37public class DefaultIsisLsdbAge implements IsisLsdbAge {
38 private static final Logger log = LoggerFactory.getLogger(DefaultIsisLsdbAge.class);
39 protected static int ageCounter = 0;
40 private InternalAgeTimer dbAgeTimer;
41 private ScheduledExecutorService exServiceage;
42 private Integer maxBins = 1200;
43 private Map<Integer, IsisLspBin> ageBins = new ConcurrentHashMap<>(maxBins);
44 private int ageCounterRollOver = 0;
45 private IsisLspQueueConsumer queueConsumer = null;
46 private BlockingQueue<LspWrapper> lsaQueue = new ArrayBlockingQueue<>(1024);
47
48 /**
49 * Creates an instance of LSDB age.
50 */
51 public DefaultIsisLsdbAge() {
52 // create LSBin's in the HashMap.
53 for (int i = 0; i < maxBins; i++) {
54 IsisLspBin lspBin = new DefaultIsisLspBin(i);
55 ageBins.put(i, lspBin);
56 }
57 }
58
59 /**
60 * Returns age counter.
61 *
62 * @return age counter
63 */
64 public int ageCounter() {
65 return ageCounter;
66 }
67
68 /**
69 * Returns age counter roll over.
70 *
71 * @return age counter roll over
72 */
73 public int ageCounterRollOver() {
74
75 return ageCounterRollOver;
76 }
77
78 /**
79 * Adds LSP to LS bin for ageing.
80 *
81 * @param binNumber key to store in bin
82 * @param lspBin LSP bin instance
83 */
84 public void addLspBin(int binNumber, IsisLspBin lspBin) {
85 if (!ageBins.containsKey(binNumber)) {
86 ageBins.put(binNumber, lspBin);
87 }
88 }
89
90 /**
91 * Returns LSP from Bin.
92 *
93 * @param binKey key
94 * @return bin instance
95 */
96 public IsisLspBin getLspBin(int binKey) {
97
98 return ageBins.get(binKey);
99 }
100
101 /**
102 * Removes LSP from Bin.
103 *
104 * @param lspWrapper wrapper instance
105 */
106 public void removeLspFromBin(LspWrapper lspWrapper) {
107 if (ageBins.containsKey(lspWrapper.binNumber())) {
108 IsisLspBin lsaBin = ageBins.get(lspWrapper.binNumber());
109 lsaBin.removeIsisLsp(((LsPdu) lspWrapper.lsPdu()).lspId(), lspWrapper);
110 }
111 }
112
113 /**
114 * Returns the bin number.
115 *
116 * @param age Can be either age or ageCounter
117 * @return bin number.
118 */
119 public int age2Bin(int age) {
120 if (age <= ageCounter) {
121 return (ageCounter - age);
122 } else {
123 return ((IsisConstants.LSPMAXAGE - 1) + (ageCounter - age));
124 }
125 }
126
127 /**
128 * Starts the aging timer and queue consumer.
129 */
130 public void startDbAging() {
131 startDbAgeTimer();
132 queueConsumer = new IsisLspQueueConsumer(lsaQueue);
133 new Thread(queueConsumer).start();
134 }
135
136 /**
137 * Starts DB aging task.
138 */
139 private void startDbAgeTimer() {
140 dbAgeTimer = new InternalAgeTimer();
141 //from 1 sec
142 exServiceage = Executors.newSingleThreadScheduledExecutor();
143 exServiceage.scheduleAtFixedRate(dbAgeTimer, 1, 1, TimeUnit.SECONDS);
144 }
145
146 /**
147 * Gets called every second as part of the aging process.
148 */
149 public void ageLsp() {
150 refreshLsa();
151 maxAgeLsa();
152
153 if (ageCounter == IsisConstants.LSPMAXAGE) {
154 ageCounter = 0;
155 ageCounterRollOver++;
156 } else {
157 ageCounter++;
158 }
159 }
160
161 /**
162 * If the LSP have completed the MaxAge - they are moved called stop aging.
163 */
164 public void maxAgeLsa() {
165 if (ageCounter == 0) {
166 return;
167 }
168 //Get from Age Bins
169 IsisLspBin lspBin = ageBins.get(ageCounter - 1);
170 if (lspBin == null) {
171 return;
172 }
173 Map lspBinMap = lspBin.listOfLsp();
174 for (Object key : lspBinMap.keySet()) {
175 LspWrapper lspWrapper = (LspWrapper) lspBinMap.get((String) key);
176 if (lspWrapper.currentAge() == IsisConstants.LSPMAXAGE) {
177 lspWrapper.setLspProcessing(IsisConstants.MAXAGELSP);
178 log.debug("Lsp picked for maxage removal. Age Counter: {}, AgeCounterRollover: {}, " +
179 "AgeCounterRollover WhenAddedToDb: {}, LSA Type: {}, LSA Key: {}",
180 ageCounter, ageCounterRollOver, lspWrapper.currentAge(),
181 lspWrapper.lsPdu().isisPduType(), key);
182 //add it to lspQueue for processing
183 try {
184 lsaQueue.put(lspWrapper);
185 //remove from bin
186 lspBin.removeIsisLsp((String) key, lspWrapper);
187 } catch (InterruptedException e) {
188 log.debug("Error::LSDBAge::maxAgeLsp::{}", e.getMessage());
189 }
190 }
191 }
192
193 }
194
195 /*
196 * If the LSP is in age bin of 900s- it's pushed into refresh list.
197 */
198 public void refreshLsa() {
199 int binNumber;
200 if (ageCounter < IsisConstants.LSPREFRESH) {
201 binNumber = ageCounter + IsisConstants.LSPREFRESH;
202 } else {
203 binNumber = ageCounter - IsisConstants.LSPREFRESH;
204 }
205 if (binNumber > IsisConstants.LSPMAXAGE) {
206 binNumber = binNumber - IsisConstants.LSPMAXAGE;
207 }
208 IsisLspBin lspBin = ageBins.get(binNumber);
209 if (lspBin == null) {
210 return;
211 }
212 Map lspBinMap = lspBin.listOfLsp();
213 for (Object key : lspBinMap.keySet()) {
214 LspWrapper lsp = (LspWrapper) lspBinMap.get((String) key);
215 try {
216 if (lsp.isSelfOriginated()) {
217 log.debug("Lsp picked for refreshLsp. binNumber: {}, LSA Type: {}, LSA Key: {}",
218 binNumber, lsp.lspType(), key);
219 lsp.setLspProcessing(IsisConstants.REFRESHLSP);
220 lsaQueue.put(lsp);
221 //remove from bin
222 lspBin.removeIsisLsp((String) key, lsp);
223 }
224 } catch (InterruptedException e) {
225 log.debug("Error::LSDBAge::refreshLsp::{}", e.getMessage());
226 }
227 }
228 }
229
230
231 /**
232 * Runnable task which runs every second and calls aging process.
233 */
234 private class InternalAgeTimer implements Runnable {
235
236 /**
237 * Creates an instance of age timer task.
238 */
239 InternalAgeTimer() {
240 log.debug("Starts::IsisLsdbAge::AgeTimer...!!! ");
241 }
242
243 @Override
244 public void run() {
245 ageLsp();
246 }
247 }
248}