blob: 036f1f45f7d56f53ccbf6c676722836336c5321e [file] [log] [blame]
Thomas Vachuska58de4162015-09-10 16:15:33 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuska58de4162015-09-10 16:15:33 -07003 *
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 */
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070016package org.onosproject.pcepio.protocol.ver1;
17
18import java.util.LinkedList;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053019import java.util.List;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070020
21import org.jboss.netty.buffer.ChannelBuffer;
22import org.onosproject.pcepio.exceptions.PcepParseException;
23import org.onosproject.pcepio.protocol.PcepErrorInfo;
24import org.onosproject.pcepio.protocol.PcepErrorMsg;
25import org.onosproject.pcepio.protocol.PcepErrorObject;
26import org.onosproject.pcepio.protocol.PcepMessageReader;
27import org.onosproject.pcepio.protocol.PcepMessageWriter;
28import org.onosproject.pcepio.protocol.PcepOpenObject;
29import org.onosproject.pcepio.protocol.PcepType;
30import org.onosproject.pcepio.protocol.PcepVersion;
31import org.onosproject.pcepio.types.ErrorObjListWithOpen;
32import org.onosproject.pcepio.types.PcepObjectHeader;
33import org.slf4j.Logger;
34import org.slf4j.LoggerFactory;
35
36import com.google.common.base.MoreObjects;
37import com.google.common.base.MoreObjects.ToStringHelper;
38
39/**
40 * Provides PCEP Error Message.
41 */
42public class PcepErrorMsgVer1 implements PcepErrorMsg {
43
44 /*
45 * PCE Error message format.
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053046 Reference: draft-dhodylee-pce-pcep-ls-01, section 8.2.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070047
48 <PCErr Message> ::= <Common Header>
49 ( <error-obj-list> [<Open>] ) | <error>
50 [<error-list>]
51
52 <error-obj-list> ::=<PCEP-ERROR>[<error-obj-list>]
53
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053054 <error> ::=[<request-id-list> | <ls-id-list>]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070055 <error-obj-list>
56
57 <request-id-list> ::=<RP>[<request-id-list>]
58
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053059 <ls-id-list> ::=<LS>[<ls-id-list>]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070060
61 <error-list> ::=<error>[<error-list>]
62 */
63
Ray Milkey9c9cde42018-01-12 14:22:06 -080064 private static final Logger log = LoggerFactory.getLogger(PcepOpenMsgVer1.class);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070065 public static final byte PACKET_VERSION = 1;
66 public static final int PACKET_MINIMUM_LENGTH = 12;
67 public static final PcepType MSG_TYPE = PcepType.ERROR;
68
69 //Below either one should be present.
70 private ErrorObjListWithOpen errObjListWithOpen; //optional ( <error-obj-list> [<Open>] )
71 private PcepErrorInfo errInfo; //optional <error> [<error-list>]
72
73 public static final PcepErrorMsgVer1.Reader READER = new Reader();
74
75 /**
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +053076 * Constructor to initialize variables.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070077 */
78 public PcepErrorMsgVer1() {
79 errObjListWithOpen = null;
80 errInfo = null;
81 }
82
83 /**
84 * Constructor to initialize variables.
85 *
86 * @param errObjListWithOpen error-object-list with open object
87 * @param errInfo error information
88 */
89 public PcepErrorMsgVer1(ErrorObjListWithOpen errObjListWithOpen, PcepErrorInfo errInfo) {
90 this.errObjListWithOpen = errObjListWithOpen;
91 this.errInfo = errInfo;
92 }
93
94 /**
95 * Reader class for reading PCEP error Message from channel buffer.
96 */
97 public static class Reader implements PcepMessageReader<PcepErrorMsg> {
98
99 ErrorObjListWithOpen errObjListWithOpen;
100 PcepErrorInfo errInfo;
101 PcepObjectHeader tempObjHeader;
102
103 @Override
104 public PcepErrorMsg readFrom(ChannelBuffer cb) throws PcepParseException {
105
106 errObjListWithOpen = null;
107 errInfo = null;
108 tempObjHeader = null;
109
110 if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
111 throw new PcepParseException("Packet size is less than the minimum length.");
112 }
113
114 byte version = cb.readByte();
115 version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
116 if (version != PACKET_VERSION) {
117 throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version);
118 }
119 // fixed value property type == 1
120 byte type = cb.readByte();
121 if (type != MSG_TYPE.getType()) {
122 throw new PcepParseException("Wrong type: Expected=PcepType.ERROR(6), got=" + type);
123 }
124 int length = cb.readShort();
125 if (length < PACKET_MINIMUM_LENGTH) {
126 throw new PcepParseException(
127 "Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + length);
128 }
129
130 //parse <PCErr Message>
131 parsePCErrMsg(cb);
132
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530133 // If other than RP or LS or PCEP-ERROR present then it is error.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700134 if (0 < cb.readableBytes()) {
135 PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
136 throw new PcepParseException("Unexpected Object found. Object Class : " + tempObjHeader.getObjClass());
137 }
138
139 return new PcepErrorMsgVer1(errObjListWithOpen, errInfo);
140 }
141
142 /**
143 * Parsing PCErr Message.
144 *
145 * @param cb channel buffer.
146 * @throws PcepParseException if mandatory fields are missing
147 * output: this.errObjListWithOpen, this.errInfo
148 */
149 public void parsePCErrMsg(ChannelBuffer cb) throws PcepParseException {
150 //If PCEP-ERROR list is followed by OPEN Object then store into ErrorObjListWithOpen.
151 // ( <error-obj-list> [<Open>]
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530152 //If PCEP-ERROR list is followed by RP or LS Object then store into errInfo. <error> [<error-list>]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700153 //If only PCEP-ERROR list is present then store into ErrorObjListWithOpen.
154 PcepObjectHeader tempObjHeader;
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530155 List<PcepErrorObject> llErrObjList;
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700156
157 if (0 >= cb.readableBytes()) {
158 throw new PcepParseException("PCEP-ERROR message came with empty objects.");
159 }
160
161 //parse PCEP-ERROR list
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700162 llErrObjList = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700163 tempObjHeader = parseErrorObjectList(llErrObjList, cb);
164
165 //check whether OPEN-OBJECT is present.
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700166 if ((tempObjHeader != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700167 && (tempObjHeader.getObjClass() == PcepOpenObjectVer1.OPEN_OBJ_CLASS)) {
168
169 if (llErrObjList.isEmpty()) {
170 throw new PcepParseException("<error-obj-list> should be present if OPEN-OBJECT exists");
171 }
172
173 PcepOpenObject pcepOpenObj = PcepOpenObjectVer1.read(cb);
174 this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList, pcepOpenObj);
175
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530176 } else if ((tempObjHeader != null) //check whether RP or LS Object is present.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700177 && ((tempObjHeader.getObjClass() == PcepRPObjectVer1.RP_OBJ_CLASS)
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530178 || (tempObjHeader.getObjClass() == PcepLSObjectVer1.LS_OBJ_CLASS))) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700179
180 this.errInfo = new PcepErrorInfoVer1(null, null, llErrObjList);
181 this.errInfo.read(cb);
182
Sho SHIMIZU2cb7e802015-09-03 11:41:12 -0700183 } else if (!llErrObjList.isEmpty()) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700184 //If only PCEP-ERROR list is present then store it in errObjListWithOpen.
185 this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList);
186 } else {
187 throw new PcepParseException("Empty PCEP-ERROR message.");
188 }
189 }
190
191 /**
192 * Parse error-obj-list.
193 *
194 * @param llErrObjList error object list output
195 * @param cb channel buffer input
196 * @throws PcepParseException if mandatory fields are missing
197 * @return error object header
198 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530199 public PcepObjectHeader parseErrorObjectList(List<PcepErrorObject> llErrObjList, ChannelBuffer cb)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700200 throws PcepParseException {
201 PcepObjectHeader tempObjHeader = null;
202
203 while (0 < cb.readableBytes()) {
204 cb.markReaderIndex();
205 tempObjHeader = PcepObjectHeader.read(cb);
206 cb.resetReaderIndex();
207 if (tempObjHeader.getObjClass() == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
208 llErrObjList.add(PcepErrorObjectVer1.read(cb));
209 } else {
210 break;
211 }
212 }
213 return tempObjHeader;
214 }
215 }
216
217 /**
218 * Builder class for PCEP error message.
219 */
220 public static class Builder implements PcepErrorMsg.Builder {
221 // Pcep error message fields
222
223 private ErrorObjListWithOpen errObjListWithOpen = null; //optional ( <error-obj-list> [<Open>] )
224 private PcepErrorInfo errInfo = null; //optional <error> [<error-list>]
225
226 @Override
227 public PcepVersion getVersion() {
228 return PcepVersion.PCEP_1;
229 }
230
231 @Override
232 public PcepType getType() {
233 return PcepType.ERROR;
234 }
235
236 @Override
237 public PcepErrorMsg build() {
238 return new PcepErrorMsgVer1(this.errObjListWithOpen, this.errInfo);
239 }
240
241 @Override
242 public ErrorObjListWithOpen getErrorObjListWithOpen() {
243 return this.errObjListWithOpen;
244 }
245
246 @Override
247 public Builder setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
248 this.errObjListWithOpen = errObjListWithOpen;
249 return this;
250 }
251
252 @Override
253 public PcepErrorInfo getPcepErrorInfo() {
254 return this.errInfo;
255 }
256
257 @Override
258 public Builder setPcepErrorInfo(PcepErrorInfo errInfo) {
259 this.errInfo = errInfo;
260 return this;
261 }
262 }
263
264 @Override
265 public void writeTo(ChannelBuffer cb) throws PcepParseException {
266 WRITER.write(cb, this);
267 }
268
269 public static final Writer WRITER = new Writer();
270
271 /**
272 * Writer class for writing PCEP error Message to channel buffer.
273 */
274 static class Writer implements PcepMessageWriter<PcepErrorMsgVer1> {
275 @Override
276 public void write(ChannelBuffer cb, PcepErrorMsgVer1 message) throws PcepParseException {
277 int startIndex = cb.writerIndex();
278 // first 3 bits set to version
279 cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
280 // message type 0xC
281 cb.writeByte(MSG_TYPE.getType());
282 // length is length of variable message, will be updated at the end
283 // Store the position of message
284 // length in buffer
285 int msgLenIndex = cb.writerIndex();
286 cb.writeShort(0);
287 ErrorObjListWithOpen errObjListWithOpen = message.getErrorObjListWithOpen();
288 PcepErrorInfo errInfo = message.getPcepErrorInfo();
289
290 // write ( <error-obj-list> [<Open>] ) if exists.
291 // otherwise write <error> [<error-list>]
292
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700293 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700294 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
295 errObjListWithOpen.write(cb);
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700296 } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700297 errInfo.write(cb);
298 } else {
299 throw new PcepParseException("Empty PCEP-ERROR message.");
300 }
301 // PcepErrorMessage message length field
302 int length = cb.writerIndex() - startIndex;
303 cb.setShort(msgLenIndex, (short) length);
304 }
305 }
306
307 @Override
308 public PcepVersion getVersion() {
309 return PcepVersion.PCEP_1;
310 }
311
312 @Override
313 public PcepType getType() {
314 return MSG_TYPE;
315 }
316
317 @Override
318 public ErrorObjListWithOpen getErrorObjListWithOpen() {
319 return this.errObjListWithOpen;
320 }
321
322 @Override
323 public void setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
324 this.errObjListWithOpen = errObjListWithOpen;
325 }
326
327 @Override
328 public PcepErrorInfo getPcepErrorInfo() {
329 return this.errInfo;
330 }
331
332 @Override
333 public void setPcepErrorInfo(PcepErrorInfo errInfo) {
334 this.errInfo = errInfo;
335 }
336
337 /**
338 * Return list of Error types.
339 *
340 * @return error types list
341 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530342 public List<Integer> getErrorType() {
343 List<Integer> llErrorType = new LinkedList<>();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700344 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700345 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
346 llErrorType = errObjListWithOpen.getErrorType();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700347 } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700348 llErrorType = errInfo.getErrorType();
349 }
350
351 return llErrorType;
352 }
353
354 /**
355 * Return list of Error values.
356 *
357 * @return error value list
358 */
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530359 public List<Integer> getErrorValue() {
360 List<Integer> llErrorValue = new LinkedList<>();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700361 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700362 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
363 llErrorValue = errObjListWithOpen.getErrorValue();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700364 } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700365 llErrorValue = errInfo.getErrorValue();
366 }
367
368 return llErrorValue;
369 }
370
371 @Override
372 public String toString() {
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530373 ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass()).omitNullValues();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700374
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700375 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700376 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
377 toStrHelper.add("ErrorObjectListWithOpen", errObjListWithOpen);
378 }
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700379 if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700380 toStrHelper.add("ErrorInfo", errInfo);
381 }
382
383 return toStrHelper.toString();
384 }
385}