Revert "BUG-47 : unfinished PCEP migration to generated DTOs."
[bgpcep.git] / pcep / impl / src / main / java / org / opendaylight / protocol / pcep / impl / message / PCEPReplyMessageValidator.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.protocol.pcep.impl.message;
9
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Collections;
13 import java.util.List;
14
15 import org.opendaylight.protocol.pcep.PCEPDeserializerException;
16 import org.opendaylight.protocol.pcep.PCEPDocumentedException;
17 import org.opendaylight.protocol.pcep.PCEPErrors;
18 import org.opendaylight.protocol.pcep.PCEPObject;
19 import org.opendaylight.protocol.pcep.impl.PCEPMessageValidator;
20 import org.opendaylight.protocol.pcep.impl.object.UnknownObject;
21 import org.opendaylight.protocol.pcep.message.PCEPErrorMessage;
22 import org.opendaylight.protocol.pcep.message.PCEPReplyMessage;
23 import org.opendaylight.protocol.pcep.object.CompositeErrorObject;
24 import org.opendaylight.protocol.pcep.object.CompositePathObject;
25 import org.opendaylight.protocol.pcep.object.CompositeReplySvecObject;
26 import org.opendaylight.protocol.pcep.object.CompositeResponseObject;
27 import org.opendaylight.protocol.pcep.object.PCEPErrorObject;
28 import org.opendaylight.protocol.pcep.object.PCEPExplicitRouteObject;
29 import org.opendaylight.protocol.pcep.object.PCEPIncludeRouteObject;
30 import org.opendaylight.protocol.pcep.object.PCEPLspObject;
31 import org.opendaylight.protocol.pcep.object.PCEPLspaObject;
32 import org.opendaylight.protocol.pcep.object.PCEPMetricObject;
33 import org.opendaylight.protocol.pcep.object.PCEPNoPathObject;
34 import org.opendaylight.protocol.pcep.object.PCEPObjectiveFunctionObject;
35 import org.opendaylight.protocol.pcep.object.PCEPRequestParameterObject;
36 import org.opendaylight.protocol.pcep.object.PCEPRequestedPathBandwidthObject;
37 import org.opendaylight.protocol.pcep.object.PCEPSvecObject;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
39
40 import com.google.common.collect.Lists;
41
42 /**
43  * PCEPReplyMessage validator. Validates message integrity.
44  */
45 public class PCEPReplyMessageValidator extends PCEPMessageValidator {
46
47         private static class SubReplyValidator {
48
49                 private boolean requestRejected = true;
50
51                 private List<Message> msgs = Lists.newArrayList();
52
53                 private PCEPRequestParameterObject rpObj;
54
55                 private PCEPNoPathObject noPath;
56                 private PCEPLspObject lsp;
57                 private PCEPLspaObject lspa;
58                 private PCEPRequestedPathBandwidthObject bandwidth;
59                 private List<PCEPMetricObject> metrics;
60                 private PCEPIncludeRouteObject iro;
61                 private List<CompositePathObject> paths;
62
63                 private void init() {
64                         this.requestRejected = false;
65                         this.msgs = Lists.newArrayList();
66
67                         this.noPath = null;
68                         this.lsp = null;
69                         this.lspa = null;
70                         this.iro = null;
71                         this.rpObj = null;
72                         this.metrics = new ArrayList<PCEPMetricObject>();
73                         this.paths = new ArrayList<CompositePathObject>();
74                 }
75
76                 public List<Message> validate(final List<PCEPObject> objects, final List<CompositeReplySvecObject> svecList) {
77                         this.init();
78
79                         if (!(objects.get(0) instanceof PCEPRequestParameterObject))
80                                 return null;
81
82                         final PCEPRequestParameterObject rpObj = (PCEPRequestParameterObject) objects.get(0);
83                         objects.remove(0);
84
85                         PCEPObject obj;
86                         int state = 1;
87                         while (!objects.isEmpty()) {
88                                 obj = objects.get(0);
89                                 if (obj instanceof UnknownObject) {
90                                         if (((UnknownObject) obj).isProcessed()) {
91                                                 this.msgs.add(new PCEPErrorMessage(new CompositeErrorObject(copyRP(rpObj, false), new PCEPErrorObject(((UnknownObject) obj).getError()))));
92                                                 this.requestRejected = true;
93                                         }
94
95                                         objects.remove(0);
96                                         continue;
97                                 }
98
99                                 switch (state) {
100                                 case 1:
101                                         state = 2;
102                                         if (obj instanceof PCEPNoPathObject) {
103                                                 this.noPath = (PCEPNoPathObject) obj;
104                                                 break;
105                                         }
106                                 case 2:
107                                         state = 3;
108                                         if (obj instanceof PCEPLspObject) {
109                                                 this.lsp = (PCEPLspObject) obj;
110                                                 break;
111                                         }
112                                 case 3:
113                                         state = 4;
114                                         if (obj instanceof PCEPLspaObject) {
115                                                 this.lspa = (PCEPLspaObject) obj;
116                                                 break;
117                                         }
118                                 case 4:
119                                         state = 5;
120                                         if (obj instanceof PCEPRequestedPathBandwidthObject) {
121                                                 this.bandwidth = (PCEPRequestedPathBandwidthObject) obj;
122                                                 break;
123                                         }
124                                 case 5:
125                                         state = 6;
126                                         if (obj instanceof PCEPMetricObject) {
127                                                 this.metrics.add((PCEPMetricObject) obj);
128                                                 state = 5;
129                                                 break;
130                                         }
131                                 case 6:
132                                         state = 7;
133                                         if (obj instanceof PCEPIncludeRouteObject) {
134                                                 this.iro = (PCEPIncludeRouteObject) obj;
135                                                 state = 8;
136                                                 break;
137                                         }
138                                 }
139
140                                 if (state == 7)
141                                         break;
142
143                                 objects.remove(0);
144
145                                 if (state == 8)
146                                         break;
147                         }
148
149                         if (!objects.isEmpty()) {
150                                 CompositePathObject path = this.getValidCompositePath(objects);
151                                 while (path != null) {
152                                         this.paths.add(path);
153                                         if (objects.isEmpty())
154                                                 break;
155                                         path = this.getValidCompositePath(objects);
156                                 }
157                         }
158
159                         if (!this.requestRejected) {
160                                 this.msgs.add(new PCEPReplyMessage(Collections.unmodifiableList(Arrays.asList(new CompositeResponseObject(rpObj, this.noPath, this.lsp, this.lspa, this.bandwidth, this.metrics, this.iro, this.paths))), Collections.unmodifiableList(svecList)));
161                         }
162
163                         return this.msgs;
164                 }
165
166                 private CompositePathObject getValidCompositePath(final List<PCEPObject> objects) {
167                         if (!(objects.get(0) instanceof PCEPExplicitRouteObject))
168                                 return null;
169
170                         final PCEPExplicitRouteObject explicitRoute = (PCEPExplicitRouteObject) objects.get(0);
171                         objects.remove(0);
172
173                         PCEPLspaObject pathLspa = null;
174                         PCEPRequestedPathBandwidthObject pathBandwidth = null;
175                         final List<PCEPMetricObject> pathMetrics = new ArrayList<PCEPMetricObject>();
176                         PCEPIncludeRouteObject pathIro = null;
177
178                         PCEPObject obj;
179                         int state = 1;
180                         while (!objects.isEmpty()) {
181                                 obj = objects.get(0);
182                                 if (obj instanceof UnknownObject) {
183                                         if (((UnknownObject) obj).isProcessed()) {
184                                                 this.msgs.add(new PCEPErrorMessage(new CompositeErrorObject(copyRP(this.rpObj, false), new PCEPErrorObject(((UnknownObject) obj).getError()))));
185                                                 this.requestRejected = true;
186                                         }
187                                         objects.remove(0);
188                                         continue;
189                                 }
190
191                                 switch (state) {
192                                 case 1:
193                                         state = 2;
194                                         if (obj instanceof PCEPLspaObject) {
195                                                 pathLspa = (PCEPLspaObject) obj;
196                                                 break;
197                                         }
198                                 case 2:
199                                         state = 3;
200                                         if (obj instanceof PCEPRequestedPathBandwidthObject) {
201                                                 pathBandwidth = (PCEPRequestedPathBandwidthObject) obj;
202                                                 break;
203                                         }
204                                 case 3:
205                                         state = 4;
206                                         if (obj instanceof PCEPMetricObject) {
207                                                 pathMetrics.add((PCEPMetricObject) obj);
208                                                 state = 3;
209                                                 break;
210                                         }
211                                 case 4:
212                                         state = 5;
213                                         if (obj instanceof PCEPIncludeRouteObject) {
214                                                 pathIro = (PCEPIncludeRouteObject) obj;
215                                                 state = 6;
216                                                 break;
217                                         }
218
219                                 }
220
221                                 if (state == 5)
222                                         break;
223
224                                 objects.remove(0);
225
226                                 if (state == 6)
227                                         break;
228                         }
229
230                         return new CompositePathObject(explicitRoute, pathLspa, pathBandwidth, pathMetrics, pathIro);
231                 }
232         }
233
234         @Override
235         public List<Message> validate(final List<PCEPObject> objects) throws PCEPDeserializerException {
236                 if (objects == null)
237                         throw new IllegalArgumentException("Passed list can't be null.");
238
239                 final List<Message> msgs = Lists.newArrayList();
240                 final List<CompositeReplySvecObject> svecList = new ArrayList<CompositeReplySvecObject>();
241
242                 CompositeReplySvecObject svecComp;
243                 while (!objects.isEmpty()) {
244                         try {
245                                 if ((svecComp = this.getValidSvecComposite(objects)) == null)
246                                         break;
247                         } catch (final PCEPDocumentedException e) {
248                                 msgs.add(new PCEPErrorMessage(new PCEPErrorObject(e.getError())));
249                                 return msgs;
250                         }
251
252                         svecList.add(svecComp);
253                 }
254
255                 List<Message> subMessages;
256                 final SubReplyValidator subValidator = new SubReplyValidator();
257                 while (!objects.isEmpty()) {
258                         subMessages = subValidator.validate(objects, svecList);
259                         if (subMessages == null)
260                                 break;
261                         msgs.addAll(subMessages);
262                 }
263
264                 if (msgs.isEmpty()) {
265                         msgs.add(new PCEPErrorMessage(new PCEPErrorObject(PCEPErrors.RP_MISSING)));
266                         return msgs;
267                 }
268
269                 if (!objects.isEmpty())
270                         throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
271
272                 return msgs;
273         }
274
275         private CompositeReplySvecObject getValidSvecComposite(final List<PCEPObject> objects) throws PCEPDocumentedException {
276                 if (objects == null)
277                         throw new IllegalArgumentException("List cannot be null.");
278
279                 if (!(objects.get(0) instanceof PCEPSvecObject))
280                         return null;
281
282                 final PCEPSvecObject svec = (PCEPSvecObject) objects.get(0);
283                 objects.remove(0);
284
285                 PCEPObjectiveFunctionObject of = null;
286                 final List<PCEPMetricObject> metrics = new ArrayList<PCEPMetricObject>();
287
288                 PCEPObject obj;
289                 int state = 1;
290                 while (!objects.isEmpty()) {
291                         obj = objects.get(0);
292
293                         if (obj instanceof UnknownObject)
294                                 throw new PCEPDocumentedException("Unknown object", ((UnknownObject) obj).getError());
295
296                         switch (state) {
297                         case 1:
298                                 state = 2;
299                                 if (obj instanceof PCEPObjectiveFunctionObject) {
300                                         of = (PCEPObjectiveFunctionObject) obj;
301                                         break;
302                                 }
303                         case 2:
304                                 state = 3;
305                                 if (obj instanceof PCEPMetricObject) {
306                                         metrics.add((PCEPMetricObject) obj);
307                                         state = 2;
308                                         break;
309                                 }
310                         }
311
312                         if (state == 3)
313                                 break;
314
315                         objects.remove(0);
316                 }
317
318                 return new CompositeReplySvecObject(svec, of, metrics);
319         }
320
321         private static PCEPRequestParameterObject copyRP(final PCEPRequestParameterObject origRp, final boolean processed) {
322                 return new PCEPRequestParameterObject(origRp.isLoose(), origRp.isBidirectional(), origRp.isReoptimized(), origRp.isMakeBeforeBreak(), origRp.isReportRequestOrder(), origRp.isSuplyOFOnResponse(), origRp.isFragmentation(), origRp.isP2mp(), origRp.isEroCompression(), origRp.getPriority(), origRp.getRequestID(), origRp.getTlvs(), processed, origRp.isIgnored());
323         }
324 }