65a844c25d10d0c8f8f0e58c9479daa222b15164
[onosfw.git] /
1 /*
2  * Copyright 2015 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  */
16
17 package org.onosproject.pcepio.protocol.ver1;
18
19 import java.util.LinkedList;
20 import java.util.ListIterator;
21
22 import org.jboss.netty.buffer.ChannelBuffer;
23 import org.onosproject.pcepio.exceptions.PcepParseException;
24 import org.onosproject.pcepio.protocol.PcepAttribute;
25 import org.onosproject.pcepio.protocol.PcepBandwidthObject;
26 import org.onosproject.pcepio.protocol.PcepIroObject;
27 import org.onosproject.pcepio.protocol.PcepLspaObject;
28 import org.onosproject.pcepio.protocol.PcepMetricObject;
29 import org.onosproject.pcepio.types.PcepObjectHeader;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import com.google.common.base.MoreObjects;
34
35 /**
36  * Provides PCEP Attribute List.
37  */
38 public class PcepAttributeVer1 implements PcepAttribute {
39
40     /* Reference : RFC5440
41      *  where:
42      *      <attribute-list>                  ::=[<LSPA>]
43      *                                           [<BANDWIDTH>]
44      *                                           [<metric-list>]
45      *                                           [<IRO>]
46      *
47      *      <metric-list>                     ::=<METRIC>[<metric-list>]
48      */
49     protected static final Logger log = LoggerFactory.getLogger(PcepAttributeVer1.class);
50
51     public static final int OBJECT_HEADER_LENGTH = 4;
52
53     //PCEP LSPA Object
54     private PcepLspaObject lspaObject;
55     private boolean isLspaObjectSet;
56
57     //PCEP Bandwidth Object
58     private PcepBandwidthObject bandwidthObject;
59     private boolean isBandwidthObjectSet;
60
61     //PCEP Metric list
62     private LinkedList<PcepMetricObject> llMetricList;
63     private boolean isMetricListSet;
64
65     //PCEP IRO object
66     private PcepIroObject iroObject;
67     private boolean isIroObjectSet;
68
69     /**
70      * Default constructor to initialize member variables.
71      */
72     public PcepAttributeVer1() {
73
74         lspaObject = null;
75         bandwidthObject = null;
76         llMetricList = null;
77         iroObject = null;
78         this.isLspaObjectSet = false;
79         this.isBandwidthObjectSet = false;
80         this.isMetricListSet = false;
81         this.isIroObjectSet = false;
82     }
83
84     /**
85      * Constructor to initialize all parameters for PCEP attribute.
86      *
87      * @param lspaObject         PCEP lspa Object.
88      * @param bandwidthObject    PCEP bandwidth object.
89      * @param llMetricList       list of PCEP metric objects.
90      * @param iroObject          PCEP iro object.
91      */
92     public PcepAttributeVer1(PcepLspaObject lspaObject, PcepBandwidthObject bandwidthObject,
93             LinkedList<PcepMetricObject> llMetricList, PcepIroObject iroObject) {
94
95         this.lspaObject = lspaObject;
96         this.bandwidthObject = bandwidthObject;
97         this.llMetricList = llMetricList;
98         this.iroObject = iroObject;
99         if (lspaObject == null) {
100             this.isLspaObjectSet = false;
101         } else {
102             this.isLspaObjectSet = true;
103         }
104         if (bandwidthObject == null) {
105             this.isBandwidthObjectSet = false;
106         } else {
107             this.isBandwidthObjectSet = true;
108         }
109         if (llMetricList == null) {
110             this.isMetricListSet = false;
111         } else {
112             this.isMetricListSet = true;
113         }
114         if (iroObject == null) {
115             this.isIroObjectSet = false;
116         } else {
117             this.isIroObjectSet = true;
118         }
119     }
120
121     /**
122      * constructor to initialize bandwidthObject.
123      *
124      * @param bandwidthObject bandwidth object
125      */
126     public PcepAttributeVer1(PcepBandwidthObject bandwidthObject) {
127         this.isLspaObjectSet = false;
128
129         this.bandwidthObject = bandwidthObject;
130         this.isBandwidthObjectSet = true;
131
132         this.isMetricListSet = false;
133
134         this.isIroObjectSet = false;
135     }
136
137     /**
138      * Parse list for MeticObject.
139      *
140      * @param cb of type channel buffer
141      * @return true if parsing metric list is success
142      * @throws PcepParseException when a non metric object is received
143      */
144     public boolean parseMetricList(ChannelBuffer cb) throws PcepParseException {
145
146         if (llMetricList == null) {
147             llMetricList = new LinkedList<>();
148         }
149
150         PcepMetricObject metriclist;
151
152         //caller should verify for metric object
153         byte yObjClass = PcepMetricObjectVer1.METRIC_OBJ_CLASS;
154         byte yObjType = PcepMetricObjectVer1.METRIC_OBJ_TYPE;
155
156         while ((yObjClass == PcepMetricObjectVer1.METRIC_OBJ_CLASS)
157                 && (yObjType == PcepMetricObjectVer1.METRIC_OBJ_TYPE)) {
158
159             metriclist = PcepMetricObjectVer1.read(cb);
160             llMetricList.add(metriclist);
161             yObjClass = 0;
162             yObjType = 0;
163
164             if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
165                 cb.markReaderIndex();
166                 PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
167                 cb.resetReaderIndex();
168                 yObjClass = tempObjHeader.getObjClass();
169                 yObjType = tempObjHeader.getObjType();
170             }
171         }
172         return true;
173     }
174
175     /**
176      * Reads lspa , bandwidth , Metriclist and Iro objects and sets the objects.
177      *
178      * @param cb of type channel buffer
179      * @return instance of Pcep Attribute
180      * @throws PcepParseException while parsing Pcep Attributes from channel buffer
181      */
182
183     public static PcepAttribute read(ChannelBuffer cb) throws PcepParseException {
184         if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
185             return null;
186         }
187         //check whether any pcep attribute is present
188         cb.markReaderIndex();
189         PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
190         cb.resetReaderIndex();
191         byte yObjClass = tempObjHeader.getObjClass();
192
193         if (PcepLspaObjectVer1.LSPA_OBJ_CLASS != yObjClass && PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS != yObjClass
194                 && PcepMetricObjectVer1.METRIC_OBJ_CLASS != yObjClass && PcepIroObjectVer1.IRO_OBJ_CLASS != yObjClass) {
195             //No PCEP attribute is present
196             return null;
197         }
198
199         PcepAttributeVer1 pcepAttribute = new PcepAttributeVer1();
200
201         //If LSPA present then store it.LSPA is optional
202         if (yObjClass == PcepLspaObjectVer1.LSPA_OBJ_CLASS) {
203             pcepAttribute.setLspaObject(PcepLspaObjectVer1.read(cb));
204             yObjClass = checkNextObject(cb);
205         }
206
207         //If BANDWIDTH present then store it.BANDWIDTH is optional
208         if (yObjClass == PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS) {
209             pcepAttribute.setBandwidthObject(PcepBandwidthObjectVer1.read(cb));
210             yObjClass = checkNextObject(cb);
211         }
212
213         //If Metric list present then store it.MetricList is optional
214         if (yObjClass == PcepMetricObjectVer1.METRIC_OBJ_CLASS) {
215             pcepAttribute.parseMetricList(cb);
216             yObjClass = checkNextObject(cb);
217         }
218
219         //If IRO present then store it.IRO is optional
220         if (yObjClass == PcepIroObjectVer1.IRO_OBJ_CLASS) {
221             pcepAttribute.setIroObject(PcepIroObjectVer1.read(cb));
222         }
223
224         PcepLspaObject lspaObject = pcepAttribute.getLspaObject();
225         PcepBandwidthObject bandwidthObject = pcepAttribute.getBandwidthObject();
226         LinkedList<PcepMetricObject> metriclist = pcepAttribute.llMetricList;
227         PcepIroObject iroObject = pcepAttribute.getIroObject();
228
229         return new PcepAttributeVer1(lspaObject, bandwidthObject, metriclist, iroObject);
230     }
231
232     /**
233      * Checks whether there is a more object or not.
234      *
235      * @param cb of type channel buffer
236      * @return instance of object header
237      */
238     private static byte checkNextObject(ChannelBuffer cb) {
239         if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
240             return 0;
241         }
242         cb.markReaderIndex();
243         PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
244         cb.resetReaderIndex();
245         return tempObjHeader.getObjClass();
246     }
247
248     @Override
249     public int write(ChannelBuffer cb) throws PcepParseException {
250         int iLenStartIndex = cb.writerIndex();
251         //PCEP LSPA object is optional
252         if (this.isLspaObjectSet) {
253             this.lspaObject.write(cb);
254         }
255
256         //PCEP BANDWIDTH object is optional
257         if (this.isBandwidthObjectSet) {
258             this.bandwidthObject.write(cb);
259         }
260
261         //PCEP Metric list is optional
262         if (this.isMetricListSet) {
263             ListIterator<PcepMetricObject> listIterator = this.llMetricList.listIterator();
264             while (listIterator.hasNext()) {
265                 listIterator.next().write(cb);
266             }
267         }
268
269         //PCEP  IRO object is optional
270         if (this.isIroObjectSet) {
271             this.iroObject.write(cb);
272         }
273         return cb.writerIndex() - iLenStartIndex;
274     }
275
276     @Override
277     public PcepLspaObject getLspaObject() {
278         return lspaObject;
279     }
280
281     @Override
282     public PcepBandwidthObject getBandwidthObject() {
283         return bandwidthObject;
284     }
285
286     @Override
287     public LinkedList<PcepMetricObject> getMetricObjectList() {
288         return llMetricList;
289     }
290
291     @Override
292     public PcepIroObject getIroObject() {
293         return iroObject;
294     }
295
296     @Override
297     public void setBandwidthObject(PcepBandwidthObject bandwidthObject) {
298         this.isBandwidthObjectSet = true;
299         this.bandwidthObject = bandwidthObject;
300     }
301
302     @Override
303     public void setMetricObjectList(LinkedList<PcepMetricObject> llMetricList) {
304         this.isMetricListSet = true;
305         this.llMetricList = llMetricList;
306
307     }
308
309     @Override
310     public void setLspaObject(PcepLspaObject lspaObject) {
311         this.isLspaObjectSet = true;
312         this.lspaObject = lspaObject;
313     }
314
315     @Override
316     public void setIroObject(PcepIroObject iroObject) {
317         this.isIroObjectSet = true;
318         this.iroObject = iroObject;
319     }
320
321     /**
322      * Builder class for PCEP attributes.
323      */
324     public static class Builder implements PcepAttribute.Builder {
325
326         //PCEP LSPA Object
327         private PcepLspaObject lspaObject;
328         private boolean isLspaObjectSet;
329
330         //PCEP BANDWIDTH Object
331         private PcepBandwidthObject bandwidthObject;
332         private boolean isBandwidthObjectSet;
333
334         //PCEP Metric list
335         private LinkedList<PcepMetricObject> llMetricList;
336         private boolean isMetricListSet;
337
338         //PCEP IRO object
339         private PcepIroObject iroObject;
340         private boolean isIroObjectSet;
341
342         @Override
343         public PcepAttribute build() {
344
345             //PCEP LSPA Object
346             PcepLspaObject lspaObject = null;
347
348             //PCEP BANDWIDTH Object
349             PcepBandwidthObject bandwidthObject = null;
350
351             //PCEP Metric list
352             LinkedList<PcepMetricObject> llMetricList = null;
353
354             //PCEP IRO object
355             PcepIroObject iroObject = null;
356
357             if (this.isLspaObjectSet) {
358                 lspaObject = this.lspaObject;
359             }
360             if (this.isBandwidthObjectSet) {
361                 bandwidthObject = this.bandwidthObject;
362             }
363             if (this.isMetricListSet) {
364                 llMetricList = this.llMetricList;
365             }
366             if (this.isIroObjectSet) {
367                 iroObject = this.iroObject;
368             }
369             return new PcepAttributeVer1(lspaObject, bandwidthObject, llMetricList, iroObject);
370         }
371
372         @Override
373         public PcepLspaObject getLspaObject() {
374             return this.lspaObject;
375         }
376
377         @Override
378         public PcepBandwidthObject getBandwidthObject() {
379             return this.bandwidthObject;
380         }
381
382         @Override
383         public LinkedList<PcepMetricObject> getMetricObjectList() {
384             return this.llMetricList;
385         }
386
387         @Override
388         public PcepIroObject getIroObject() {
389             return this.iroObject;
390         }
391
392         @Override
393         public Builder setBandwidthObject(PcepBandwidthObject bandwidthObject) {
394             this.isBandwidthObjectSet = true;
395             this.bandwidthObject = bandwidthObject;
396             return this;
397         }
398
399         @Override
400         public Builder setMetricObjectList(LinkedList<PcepMetricObject> llMetricList) {
401             this.isMetricListSet = true;
402             this.llMetricList = llMetricList;
403             return this;
404         }
405
406         @Override
407         public Builder setLspaObject(PcepLspaObject lspaObject) {
408             this.isLspaObjectSet = true;
409             this.lspaObject = lspaObject;
410             return this;
411         }
412
413         @Override
414         public Builder setIroObject(PcepIroObject iroObject) {
415             this.isIroObjectSet = true;
416             this.iroObject = iroObject;
417             return this;
418         }
419     }
420
421     @Override
422     public String toString() {
423         return MoreObjects.toStringHelper(getClass())
424                 .omitNullValues()
425                 .add("lspaObject", lspaObject)
426                 .add("bandwidthObject", bandwidthObject)
427                 .add("MetricObjectList", llMetricList)
428                 .add("IroObject", iroObject)
429                 .toString();
430     }
431 }