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