blob: 927d83d6342137f9a1e790052887e3cc347cd261 [file] [log] [blame]
Thomas Vachuska58de4162015-09-10 16:15:33 -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 */
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -070016package org.onosproject.pcepio.protocol.ver1;
17
18import java.util.LinkedList;
19
20import org.jboss.netty.buffer.ChannelBuffer;
21import org.onosproject.pcepio.exceptions.PcepParseException;
22import org.onosproject.pcepio.protocol.PcepErrorInfo;
23import org.onosproject.pcepio.protocol.PcepErrorMsg;
24import org.onosproject.pcepio.protocol.PcepErrorObject;
25import org.onosproject.pcepio.protocol.PcepMessageReader;
26import org.onosproject.pcepio.protocol.PcepMessageWriter;
27import org.onosproject.pcepio.protocol.PcepOpenObject;
28import org.onosproject.pcepio.protocol.PcepType;
29import org.onosproject.pcepio.protocol.PcepVersion;
30import org.onosproject.pcepio.types.ErrorObjListWithOpen;
31import org.onosproject.pcepio.types.PcepObjectHeader;
32import org.slf4j.Logger;
33import org.slf4j.LoggerFactory;
34
35import com.google.common.base.MoreObjects;
36import com.google.common.base.MoreObjects.ToStringHelper;
37
38/**
39 * Provides PCEP Error Message.
40 */
41public class PcepErrorMsgVer1 implements PcepErrorMsg {
42
43 /*
44 * PCE Error message format.
45
46 <PCErr Message> ::= <Common Header>
47 ( <error-obj-list> [<Open>] ) | <error>
48 [<error-list>]
49
50 <error-obj-list> ::=<PCEP-ERROR>[<error-obj-list>]
51
52 <error> ::=[<request-id-list> | <te-id-list>]
53 <error-obj-list>
54
55 <request-id-list> ::=<RP>[<request-id-list>]
56
57 <te-id-list> ::=<TE>[<te-id-list>]
58
59 <error-list> ::=<error>[<error-list>]
60 */
61
62 protected static final Logger log = LoggerFactory.getLogger(PcepOpenMsgVer1.class);
63 public static final byte PACKET_VERSION = 1;
64 public static final int PACKET_MINIMUM_LENGTH = 12;
65 public static final PcepType MSG_TYPE = PcepType.ERROR;
66
67 //Below either one should be present.
68 private ErrorObjListWithOpen errObjListWithOpen; //optional ( <error-obj-list> [<Open>] )
69 private PcepErrorInfo errInfo; //optional <error> [<error-list>]
70
71 public static final PcepErrorMsgVer1.Reader READER = new Reader();
72
73 /**
74 * constructor to initialize variables.
75 */
76 public PcepErrorMsgVer1() {
77 errObjListWithOpen = null;
78 errInfo = null;
79 }
80
81 /**
82 * Constructor to initialize variables.
83 *
84 * @param errObjListWithOpen error-object-list with open object
85 * @param errInfo error information
86 */
87 public PcepErrorMsgVer1(ErrorObjListWithOpen errObjListWithOpen, PcepErrorInfo errInfo) {
88 this.errObjListWithOpen = errObjListWithOpen;
89 this.errInfo = errInfo;
90 }
91
92 /**
93 * Reader class for reading PCEP error Message from channel buffer.
94 */
95 public static class Reader implements PcepMessageReader<PcepErrorMsg> {
96
97 ErrorObjListWithOpen errObjListWithOpen;
98 PcepErrorInfo errInfo;
99 PcepObjectHeader tempObjHeader;
100
101 @Override
102 public PcepErrorMsg readFrom(ChannelBuffer cb) throws PcepParseException {
103
104 errObjListWithOpen = null;
105 errInfo = null;
106 tempObjHeader = null;
107
108 if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
109 throw new PcepParseException("Packet size is less than the minimum length.");
110 }
111
112 byte version = cb.readByte();
113 version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
114 if (version != PACKET_VERSION) {
115 throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version);
116 }
117 // fixed value property type == 1
118 byte type = cb.readByte();
119 if (type != MSG_TYPE.getType()) {
120 throw new PcepParseException("Wrong type: Expected=PcepType.ERROR(6), got=" + type);
121 }
122 int length = cb.readShort();
123 if (length < PACKET_MINIMUM_LENGTH) {
124 throw new PcepParseException(
125 "Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + length);
126 }
127
128 //parse <PCErr Message>
129 parsePCErrMsg(cb);
130
131 // If other than RP or TE or PCEP-ERROR present then it is error.
132 if (0 < cb.readableBytes()) {
133 PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
134 throw new PcepParseException("Unexpected Object found. Object Class : " + tempObjHeader.getObjClass());
135 }
136
137 return new PcepErrorMsgVer1(errObjListWithOpen, errInfo);
138 }
139
140 /**
141 * Parsing PCErr Message.
142 *
143 * @param cb channel buffer.
144 * @throws PcepParseException if mandatory fields are missing
145 * output: this.errObjListWithOpen, this.errInfo
146 */
147 public void parsePCErrMsg(ChannelBuffer cb) throws PcepParseException {
148 //If PCEP-ERROR list is followed by OPEN Object then store into ErrorObjListWithOpen.
149 // ( <error-obj-list> [<Open>]
150 //If PCEP-ERROR list is followed by RP or TE Object then store into errInfo. <error> [<error-list>]
151 //If only PCEP-ERROR list is present then store into ErrorObjListWithOpen.
152 PcepObjectHeader tempObjHeader;
153 LinkedList<PcepErrorObject> llErrObjList;
154
155 if (0 >= cb.readableBytes()) {
156 throw new PcepParseException("PCEP-ERROR message came with empty objects.");
157 }
158
159 //parse PCEP-ERROR list
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700160 llErrObjList = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700161 tempObjHeader = parseErrorObjectList(llErrObjList, cb);
162
163 //check whether OPEN-OBJECT is present.
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700164 if ((tempObjHeader != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700165 && (tempObjHeader.getObjClass() == PcepOpenObjectVer1.OPEN_OBJ_CLASS)) {
166
167 if (llErrObjList.isEmpty()) {
168 throw new PcepParseException("<error-obj-list> should be present if OPEN-OBJECT exists");
169 }
170
171 PcepOpenObject pcepOpenObj = PcepOpenObjectVer1.read(cb);
172 this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList, pcepOpenObj);
173
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700174 } else if ((tempObjHeader != null) //check whether RP or TE Object is present.
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700175 && ((tempObjHeader.getObjClass() == PcepRPObjectVer1.RP_OBJ_CLASS)
176 || (tempObjHeader.getObjClass() == PcepTEObjectVer1.TE_OBJ_CLASS))) {
177
178 this.errInfo = new PcepErrorInfoVer1(null, null, llErrObjList);
179 this.errInfo.read(cb);
180
Sho SHIMIZU2cb7e802015-09-03 11:41:12 -0700181 } else if (!llErrObjList.isEmpty()) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700182 //If only PCEP-ERROR list is present then store it in errObjListWithOpen.
183 this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList);
184 } else {
185 throw new PcepParseException("Empty PCEP-ERROR message.");
186 }
187 }
188
189 /**
190 * Parse error-obj-list.
191 *
192 * @param llErrObjList error object list output
193 * @param cb channel buffer input
194 * @throws PcepParseException if mandatory fields are missing
195 * @return error object header
196 */
197 public PcepObjectHeader parseErrorObjectList(LinkedList<PcepErrorObject> llErrObjList, ChannelBuffer cb)
198 throws PcepParseException {
199 PcepObjectHeader tempObjHeader = null;
200
201 while (0 < cb.readableBytes()) {
202 cb.markReaderIndex();
203 tempObjHeader = PcepObjectHeader.read(cb);
204 cb.resetReaderIndex();
205 if (tempObjHeader.getObjClass() == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
206 llErrObjList.add(PcepErrorObjectVer1.read(cb));
207 } else {
208 break;
209 }
210 }
211 return tempObjHeader;
212 }
213 }
214
215 /**
216 * Builder class for PCEP error message.
217 */
218 public static class Builder implements PcepErrorMsg.Builder {
219 // Pcep error message fields
220
221 private ErrorObjListWithOpen errObjListWithOpen = null; //optional ( <error-obj-list> [<Open>] )
222 private PcepErrorInfo errInfo = null; //optional <error> [<error-list>]
223
224 @Override
225 public PcepVersion getVersion() {
226 return PcepVersion.PCEP_1;
227 }
228
229 @Override
230 public PcepType getType() {
231 return PcepType.ERROR;
232 }
233
234 @Override
235 public PcepErrorMsg build() {
236 return new PcepErrorMsgVer1(this.errObjListWithOpen, this.errInfo);
237 }
238
239 @Override
240 public ErrorObjListWithOpen getErrorObjListWithOpen() {
241 return this.errObjListWithOpen;
242 }
243
244 @Override
245 public Builder setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
246 this.errObjListWithOpen = errObjListWithOpen;
247 return this;
248 }
249
250 @Override
251 public PcepErrorInfo getPcepErrorInfo() {
252 return this.errInfo;
253 }
254
255 @Override
256 public Builder setPcepErrorInfo(PcepErrorInfo errInfo) {
257 this.errInfo = errInfo;
258 return this;
259 }
260 }
261
262 @Override
263 public void writeTo(ChannelBuffer cb) throws PcepParseException {
264 WRITER.write(cb, this);
265 }
266
267 public static final Writer WRITER = new Writer();
268
269 /**
270 * Writer class for writing PCEP error Message to channel buffer.
271 */
272 static class Writer implements PcepMessageWriter<PcepErrorMsgVer1> {
273 @Override
274 public void write(ChannelBuffer cb, PcepErrorMsgVer1 message) throws PcepParseException {
275 int startIndex = cb.writerIndex();
276 // first 3 bits set to version
277 cb.writeByte((byte) (PACKET_VERSION << PcepMessageVer1.SHIFT_FLAG));
278 // message type 0xC
279 cb.writeByte(MSG_TYPE.getType());
280 // length is length of variable message, will be updated at the end
281 // Store the position of message
282 // length in buffer
283 int msgLenIndex = cb.writerIndex();
284 cb.writeShort(0);
285 ErrorObjListWithOpen errObjListWithOpen = message.getErrorObjListWithOpen();
286 PcepErrorInfo errInfo = message.getPcepErrorInfo();
287
288 // write ( <error-obj-list> [<Open>] ) if exists.
289 // otherwise write <error> [<error-list>]
290
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700291 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700292 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
293 errObjListWithOpen.write(cb);
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700294 } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700295 errInfo.write(cb);
296 } else {
297 throw new PcepParseException("Empty PCEP-ERROR message.");
298 }
299 // PcepErrorMessage message length field
300 int length = cb.writerIndex() - startIndex;
301 cb.setShort(msgLenIndex, (short) length);
302 }
303 }
304
305 @Override
306 public PcepVersion getVersion() {
307 return PcepVersion.PCEP_1;
308 }
309
310 @Override
311 public PcepType getType() {
312 return MSG_TYPE;
313 }
314
315 @Override
316 public ErrorObjListWithOpen getErrorObjListWithOpen() {
317 return this.errObjListWithOpen;
318 }
319
320 @Override
321 public void setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
322 this.errObjListWithOpen = errObjListWithOpen;
323 }
324
325 @Override
326 public PcepErrorInfo getPcepErrorInfo() {
327 return this.errInfo;
328 }
329
330 @Override
331 public void setPcepErrorInfo(PcepErrorInfo errInfo) {
332 this.errInfo = errInfo;
333 }
334
335 /**
336 * Return list of Error types.
337 *
338 * @return error types list
339 */
340 public LinkedList<Integer> getErrorType() {
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700341 LinkedList<Integer> llErrorType = new LinkedList<>();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700342 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700343 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
344 llErrorType = errObjListWithOpen.getErrorType();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700345 } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700346 llErrorType = errInfo.getErrorType();
347 }
348
349 return llErrorType;
350 }
351
352 /**
353 * Return list of Error values.
354 *
355 * @return error value list
356 */
357 public LinkedList<Integer> getErrorValue() {
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700358 LinkedList<Integer> llErrorValue = new LinkedList<>();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700359 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700360 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
361 llErrorValue = errObjListWithOpen.getErrorValue();
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700362 } else if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700363 llErrorValue = errInfo.getErrorValue();
364 }
365
366 return llErrorValue;
367 }
368
369 @Override
370 public String toString() {
371 ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
372
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700373 if ((errObjListWithOpen != null)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700374 && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
375 toStrHelper.add("ErrorObjectListWithOpen", errObjListWithOpen);
376 }
Sho SHIMIZU92cd34f2015-09-03 10:29:30 -0700377 if ((errInfo != null) && (errInfo.isErrorInfoPresent())) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700378 toStrHelper.add("ErrorInfo", errInfo);
379 }
380
381 return toStrHelper.toString();
382 }
383}