847211ed37d3af16b2df7d53f559e401439f0a50
[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 package org.onosproject.pcepio.protocol.ver1;
17
18 import java.util.LinkedList;
19 import java.util.ListIterator;
20
21 import org.jboss.netty.buffer.ChannelBuffer;
22 import org.onosproject.pcepio.exceptions.PcepParseException;
23 import org.onosproject.pcepio.protocol.PcepError;
24 import org.onosproject.pcepio.protocol.PcepErrorObject;
25 import org.onosproject.pcepio.protocol.PcepRPObject;
26 import org.onosproject.pcepio.protocol.PcepTEObject;
27 import org.onosproject.pcepio.types.PcepObjectHeader;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import com.google.common.base.MoreObjects;
32
33 /**
34  * Provides PcepError list which contains RP or TE objects.
35  * Reference:PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
36  */
37 public class PcepErrorVer1 implements PcepError {
38
39     /*
40            <error>::=[<request-id-list> | <te-id-list>]
41                       <error-obj-list>
42
43            <request-id-list>::=<RP>[<request-id-list>]
44
45            <te-id-list>::=<TE>[<te-id-list>]
46      */
47
48     protected static final Logger log = LoggerFactory.getLogger(PcepErrorVer1.class);
49
50     private boolean isErroInfoSet;
51     //PcepErrorObject list
52     private LinkedList<PcepErrorObject> llErrObjList;
53     //PcepRPObject list
54     private LinkedList<PcepRPObject> llRPObjList;
55     //PcepTEObject list
56     private LinkedList<PcepTEObject> llTEObjList;
57     private boolean isTEObjListSet;
58
59     public static final int OBJECT_HEADER_LENGTH = 4;
60
61     /**
62      * Constructor to initialize variable.
63      */
64     public PcepErrorVer1() {
65         this.llRPObjList = null;
66         this.llTEObjList = null;
67         this.llErrObjList = null;
68     }
69
70     /**
71      * Constructor to initialize variable.
72      *
73      * @param llRPObjList list of PcepRPObject
74      * @param llTEObjList list of PcepTEObject
75      * @param llErrObjListObjList list of PcepErrorObject
76      */
77     public PcepErrorVer1(LinkedList<PcepRPObject> llRPObjList, LinkedList<PcepTEObject> llTEObjList,
78             LinkedList<PcepErrorObject> llErrObjListObjList) {
79         this.llRPObjList = llRPObjList;
80         this.llTEObjList = llTEObjList;
81         this.llErrObjList = llErrObjListObjList;
82     }
83
84     /**
85      * Constructor to initialize PcepError.
86      *
87      * @param llErrObjList list of PcepErrorObject
88      */
89     public PcepErrorVer1(LinkedList<PcepErrorObject> llErrObjList) {
90         this.llRPObjList = null;
91         this.llTEObjList = null;
92         this.llErrObjList = llErrObjList;
93     }
94
95     @Override
96     public LinkedList<PcepRPObject> getRPObjList() {
97         return this.llRPObjList;
98     }
99
100     @Override
101     public LinkedList<PcepTEObject> getTEObjList() {
102         return this.llTEObjList;
103     }
104
105     @Override
106     public LinkedList<PcepErrorObject> getErrorObjList() {
107         return this.llErrObjList;
108     }
109
110     /**
111      * Parse RP List from the channel buffer.
112      *
113      * @throws PcepParseException if mandatory fields are missing
114      * @param cb of type channel buffer
115      */
116     public void parseRPList(ChannelBuffer cb) throws PcepParseException {
117         byte yObjClass;
118         byte yObjType;
119
120         llRPObjList = new LinkedList<>();
121
122         // caller should verify for RP object
123         if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
124             log.debug("Unable to find RP Object");
125             return;
126         }
127
128         cb.markReaderIndex();
129         PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
130         cb.resetReaderIndex();
131         yObjClass = tempObjHeader.getObjClass();
132         yObjType = tempObjHeader.getObjType();
133         PcepRPObject rpObj;
134         while ((yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjType == PcepRPObjectVer1.RP_OBJ_TYPE)) {
135             rpObj = PcepRPObjectVer1.read(cb);
136             llRPObjList.add(rpObj);
137
138             if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
139                 cb.markReaderIndex();
140                 tempObjHeader = PcepObjectHeader.read(cb);
141                 cb.resetReaderIndex();
142                 yObjClass = tempObjHeader.getObjClass();
143                 yObjType = tempObjHeader.getObjType();
144             } else {
145                 break;
146             }
147         }
148     }
149
150     /**
151      * Parse TE List from the channel buffer.
152      *
153      * @param cb of type channel buffer
154      * @throws PcepParseException if mandatory fields are missing
155      */
156     public void parseTEList(ChannelBuffer cb) throws PcepParseException {
157         byte yObjClass;
158         byte yObjType;
159
160         llTEObjList = new LinkedList<>();
161
162         // caller should verify for TE object
163         if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
164             log.debug("Unable to find TE Object");
165             return;
166         }
167
168         cb.markReaderIndex();
169         PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
170         cb.resetReaderIndex();
171         yObjClass = tempObjHeader.getObjClass();
172         yObjType = tempObjHeader.getObjType();
173         PcepTEObject teObj;
174         while ((yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) && ((yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_NODE_VALUE)
175                 || (yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_LINK_VALUE))) {
176             teObj = PcepTEObjectVer1.read(cb);
177             llTEObjList.add(teObj);
178
179             if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
180                 cb.markReaderIndex();
181                 tempObjHeader = PcepObjectHeader.read(cb);
182                 cb.resetReaderIndex();
183                 yObjClass = tempObjHeader.getObjClass();
184                 yObjType = tempObjHeader.getObjType();
185             } else {
186                 break;
187             }
188         }
189     }
190
191     /**
192      * parseErrObjList from the channel buffer.
193      *
194      * @param cb of type channel buffer
195      * @throws PcepParseException if mandatory fields are missing
196      */
197     public void parseErrObjList(ChannelBuffer cb) throws PcepParseException {
198         byte yObjClass;
199         byte yObjType;
200         boolean bIsErrorObjFound = false;
201
202         llErrObjList = new LinkedList<>();
203
204         // caller should verify for RP object
205         if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
206             throw new PcepParseException("Unable to find PCEP-ERROR Object");
207         }
208
209         cb.markReaderIndex();
210         PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
211         cb.resetReaderIndex();
212         yObjClass = tempObjHeader.getObjClass();
213         yObjType = tempObjHeader.getObjType();
214         PcepErrorObject errorObject;
215         while ((yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) && (yObjType == PcepErrorObjectVer1.ERROR_OBJ_TYPE)) {
216             errorObject = PcepErrorObjectVer1.read(cb);
217             llErrObjList.add(errorObject);
218             bIsErrorObjFound = true;
219
220             if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
221                 cb.markReaderIndex();
222                 tempObjHeader = PcepObjectHeader.read(cb);
223                 cb.resetReaderIndex();
224                 yObjClass = tempObjHeader.getObjClass();
225                 yObjType = tempObjHeader.getObjType();
226             } else {
227                 break;
228             }
229         }
230
231         if (!bIsErrorObjFound) {
232             throw new PcepParseException("At least one PCEP-ERROR Object should be present.");
233         }
234     }
235
236     /**
237      * Reads the byte stream of PcepError from channel buffer.
238      *
239      * @param cb of type channel buffer
240      * @return PcepError error part of PCEP-ERROR
241      * @throws PcepParseException if mandatory fields are missing
242      */
243     public static PcepErrorVer1 read(ChannelBuffer cb) throws PcepParseException {
244         if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
245             throw new PcepParseException("Unknown Object");
246         }
247
248         PcepErrorVer1 pcepError = new PcepErrorVer1();
249         // check whether any PCEP Error Info is present
250         cb.markReaderIndex();
251         PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
252         cb.resetReaderIndex();
253         byte yObjClass = tempObjHeader.getObjClass();
254
255         //If RPlist present then store it.RPList and TEList are optional
256         if (yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) {
257             log.debug("RP_LIST");
258             pcepError.parseRPList(cb);
259             yObjClass = checkNextObject(cb);
260         } else if (yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) {
261             log.debug("TE_LIST");
262             pcepError.parseTEList(cb);
263             yObjClass = checkNextObject(cb);
264         }
265
266         if (yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
267             log.debug("PCEP-ERROR obj list");
268             pcepError.parseErrObjList(cb);
269             yObjClass = checkNextObject(cb);
270         }
271
272         return pcepError;
273     }
274
275     /**
276      * Checks Next Object.
277      *
278      * @param cb of type channel buffer.
279      * @return object type class.
280      */
281     private static byte checkNextObject(ChannelBuffer cb) {
282         if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
283             return 0;
284         }
285         cb.markReaderIndex();
286         PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
287         cb.resetReaderIndex();
288         return tempObjHeader.getObjClass();
289     }
290
291     /**
292      * Writes the byte stream of PCEP error to the channel buffer.
293      *
294      * @param cb of type channel buffer
295      * @return object length index
296      * @throws PcepParseException if mandatory fields are missing
297      */
298     @Override
299     public int write(ChannelBuffer cb) throws PcepParseException {
300         int iLenStartIndex = cb.writerIndex();
301
302         // RPlist is optional
303         if (this.isErroInfoSet) {
304             ListIterator<PcepRPObject> rpObjlistIterator = this.llRPObjList.listIterator();
305             while (rpObjlistIterator.hasNext()) {
306                 rpObjlistIterator.next().write(cb);
307             }
308         }
309
310         // TElist is optional
311         if (this.isTEObjListSet) {
312             ListIterator<PcepTEObject> teObjlistIterator = this.llTEObjList.listIterator();
313             while (teObjlistIterator.hasNext()) {
314                 teObjlistIterator.next().write(cb);
315             }
316         }
317         //ErrList is mandatory
318         ListIterator<PcepErrorObject> errlistIterator = this.llErrObjList.listIterator();
319         while (errlistIterator.hasNext()) {
320             errlistIterator.next().write(cb);
321         }
322
323         return cb.writerIndex() - iLenStartIndex;
324     }
325
326     /**
327      * Builder for error part of PCEP-ERROR.
328      */
329     public static class Builder implements PcepError.Builder {
330
331         private LinkedList<PcepRPObject> llRPObjList;
332         private LinkedList<PcepTEObject> llTEObjList;
333         private LinkedList<PcepErrorObject> llErrObjList;
334
335         @Override
336         public PcepError build() {
337             return new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList);
338         }
339
340         @Override
341         public LinkedList<PcepRPObject> getRPObjList() {
342             return this.llRPObjList;
343         }
344
345         @Override
346         public Builder setRPObjList(LinkedList<PcepRPObject> llRPObjList) {
347             this.llRPObjList = llRPObjList;
348             return this;
349         }
350
351         @Override
352         public LinkedList<PcepTEObject> getTEObjList() {
353             return this.llTEObjList;
354         }
355
356         @Override
357         public Builder setTEObjList(LinkedList<PcepTEObject> llTEObjList) {
358             this.llTEObjList = llTEObjList;
359             return this;
360         }
361
362         @Override
363         public LinkedList<PcepErrorObject> getErrorObjList() {
364             return this.llErrObjList;
365         }
366
367         @Override
368         public Builder setErrorObjList(LinkedList<PcepErrorObject> llErrObjList) {
369             this.llErrObjList = llErrObjList;
370             return this;
371         }
372
373     }
374
375     @Override
376     public void setRPObjList(LinkedList<PcepRPObject> llRPObjList) {
377         this.llRPObjList = llRPObjList;
378     }
379
380     @Override
381     public void setTEObjList(LinkedList<PcepTEObject> llTEObjList) {
382         this.llTEObjList = llTEObjList;
383     }
384
385     @Override
386     public void setErrorObjList(LinkedList<PcepErrorObject> llErrObjList) {
387         this.llErrObjList = llErrObjList;
388     }
389
390     @Override
391     public String toString() {
392         return MoreObjects.toStringHelper(getClass())
393                 .omitNullValues()
394                 .add("RpObjectList", llRPObjList)
395                 .add("TeObjectList", llTEObjList)
396                 .add("ErrorObjectList", llErrObjList)
397                 .toString();
398     }
399 }