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