Update MRI projects for Aluminium
[bgpcep.git] / pcep / base-parser / src / main / java / org / opendaylight / protocol / pcep / parser / message / PCEPRequestMessageParser.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.parser.message;
9
10 import com.google.common.base.Preconditions;
11 import io.netty.buffer.ByteBuf;
12 import io.netty.buffer.Unpooled;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Optional;
16 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
17 import org.opendaylight.protocol.pcep.spi.MessageUtil;
18 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
19 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
20 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcreq;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcreqBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Object;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.Bandwidth;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bnc.object.BranchNodeType;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bnc.object.branch.node.type.BranchNodeCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bnc.object.branch.node.type.BranchNodeCaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bnc.object.branch.node.type.NonBranchNodeCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bnc.object.branch.node.type.NonBranchNodeCaseBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.branch.node.object.BranchNodeList;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.classtype.object.ClassType;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.object.EndpointsObj;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.exclude.route.object.Xro;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.gc.object.Gc;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.include.route.object.Iro;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.load.balancing.object.LoadBalancing;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.MetricsBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lspa.object.Lspa;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.metric.object.Metric;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.monitoring.object.Monitoring;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.non.branch.node.object.NonBranchNodeList;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.of.object.Of;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.path.key.object.PathKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcc.id.req.object.PccIdReq;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pce.id.object.PceId;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.PcreqMessage;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.PcreqMessageBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.MonitoringRequest;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.MonitoringRequestBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.Requests;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.RequestsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.Svec;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.SvecBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.monitoring.request.PceIdList;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.monitoring.request.PceIdListBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.PathKeyExpansionBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.SegmentComputation;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.SegmentComputationBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.P2mp;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.P2mpBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.P2p;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.P2pBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.EndpointRroPair;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.EndpointRroPairBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.MetricBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.endpoint.rro.pair.Rros;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.endpoint.rro.pair.RrosBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.endpoint.rro.pair.rros.route.object.ReportedRouteObjectCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.endpoint.rro.pair.rros.route.object.ReportedRouteObjectCaseBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.endpoint.rro.pair.rros.route.object.SecondaryReportedRouteObjectCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.endpoint.rro.pair.rros.route.object.SecondaryReportedRouteObjectCaseBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.iro.bnc.choice.BncCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.iro.bnc.choice.BncCaseBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.iro.bnc.choice.IroCase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2mp.iro.bnc.choice.IroCaseBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.p2p.ReportedRoute;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.reoptimization.bandwidth.object.ReoptimizationBandwidth;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.reported.route.object.Rro;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.Rp;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.secondary.reported.route.object.Srro;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.vendor.information.objects.VendorInformationObject;
84
85 /**
86  * Parser for {@link Pcreq}.
87  */
88 public class PCEPRequestMessageParser extends AbstractMessageParser {
89
90     public static final int TYPE = 3;
91
92     public PCEPRequestMessageParser(final ObjectRegistry registry) {
93         super(registry);
94     }
95
96     @Override
97     public void serializeMessage(final Message message, final ByteBuf out) {
98         Preconditions.checkArgument(message instanceof Pcreq,
99                 "Wrong instance of Message. Passed instance of %s. Need Pcreq.", message.getClass());
100         final PcreqMessage msg = ((Pcreq) message).getPcreqMessage();
101         Preconditions.checkArgument(msg.getRequests() != null && !msg.getRequests().isEmpty(),
102                 "Requests cannot be null or empty.");
103         final ByteBuf buffer = Unpooled.buffer();
104         if (msg.getMonitoringRequest() != null) {
105             serializeMonitoringRequest(msg.getMonitoringRequest(), buffer);
106         }
107         if (msg.getSvec() != null) {
108             serializeSvec(msg, buffer);
109         }
110         serializeRequest(msg, buffer);
111         MessageUtil.formatMessage(TYPE, buffer, out);
112     }
113
114     protected void serializeRequest(final PcreqMessage msg, final ByteBuf buffer) {
115         for (final Requests req : msg.getRequests()) {
116             serializeObject(req.getRp(), buffer);
117             serializeVendorInformationObjects(req.getVendorInformationObject(), buffer);
118             if (req.getPathKeyExpansion() != null) {
119                 serializeObject(req.getPathKeyExpansion().getPathKey(), buffer);
120             }
121             if (req.getSegmentComputation() != null) {
122                 final SegmentComputation sc = req.getSegmentComputation();
123                 if (sc.getP2p() != null) {
124                     serializeP2P(buffer, sc.getP2p());
125                 }
126                 if (sc.getP2mp() != null) {
127                     serializeP2MP(buffer, sc.getP2mp());
128                 }
129             }
130         }
131     }
132
133     protected void serializeSvec(final PcreqMessage msg, final ByteBuf buffer) {
134         for (final Svec s : msg.getSvec()) {
135             serializeObject(s.getSvec(), buffer);
136             serializeObject(s.getOf(), buffer);
137             serializeObject(s.getGc(), buffer);
138             serializeObject(s.getXro(), buffer);
139             if (s.getMetric() != null) {
140                 for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq
141                         .message.pcreq.message.svec.Metric m : s.getMetric()) {
142                     serializeObject(m.getMetric(), buffer);
143                 }
144             }
145             serializeVendorInformationObjects(s.getVendorInformationObject(), buffer);
146         }
147     }
148
149     protected void serializeP2P(final ByteBuf buffer, final P2p p2p) {
150         serializeObject(p2p.getEndpointsObj(), buffer);
151         serializeVendorInformationObjects(p2p.getVendorInformationObject(), buffer);
152         if (p2p.getReportedRoute() != null) {
153             final ReportedRoute rr = p2p.getReportedRoute();
154             if (rr != null) {
155                 serializeObject(rr.getRro(), buffer);
156                 serializeObject(rr.getReoptimizationBandwidth(), buffer);
157             }
158         }
159         serializeObject(p2p.getLoadBalancing(), buffer);
160         serializeObject(p2p.getLspa(), buffer);
161         serializeObject(p2p.getBandwidth(), buffer);
162         if (p2p.getMetrics() != null) {
163             for (final Metrics m : p2p.getMetrics()) {
164                 serializeObject(m.getMetric(), buffer);
165             }
166         }
167         serializeObject(p2p.getIro(), buffer);
168         serializeObject(p2p.getRro(), buffer);
169         serializeObject(p2p.getXro(), buffer);
170         serializeObject(p2p.getOf(), buffer);
171         serializeObject(p2p.getClassType(), buffer);
172     }
173
174     protected void serializeP2MP(final ByteBuf buffer, final P2mp p2mp) {
175         final List<EndpointRroPair> endpointRroPairList = p2mp.getEndpointRroPair();
176         if (endpointRroPairList == null || endpointRroPairList.isEmpty()) {
177             throw new IllegalStateException("At least one instance of Endpoint must be present in P2MP Request!");
178         }
179         endpointRroPairList.forEach(pair -> {
180             serializeObject(pair.getEndpointsObj(), buffer);
181             pair.getRros().forEach(rro -> {
182                 if (rro.getRouteObject() instanceof ReportedRouteObjectCase) {
183                     serializeObject(((ReportedRouteObjectCase) rro.getRouteObject()).getRro(), buffer);
184                 } else if (rro.getRouteObject() instanceof SecondaryReportedRouteObjectCase) {
185                     serializeObject(((SecondaryReportedRouteObjectCase) rro.getRouteObject()).getSrro(), buffer);
186                 }
187             });
188             serializeObject(pair.getReoptimizationBandwidth(), buffer);
189         });
190         serializeObject(p2mp.getOf(), buffer);
191         serializeObject(p2mp.getLspa(), buffer);
192         serializeObject(p2mp.getBandwidth(), buffer);
193         if (p2mp.getMetric() != null) {
194             for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq
195                     .message.pcreq.message.requests.segment.computation.p2mp.Metric m : p2mp.getMetric()) {
196                 serializeObject(m.getMetric(), buffer);
197             }
198         }
199         if (p2mp.getIroBncChoice() instanceof IroCase) {
200             serializeObject(((IroCase) p2mp.getIroBncChoice()).getIro(), buffer);
201         } else if (p2mp.getIroBncChoice() instanceof BncCase) {
202             final BranchNodeType branchNodeType = ((BncCase) p2mp.getIroBncChoice()).getBranchNodeType();
203             if (branchNodeType instanceof BranchNodeCase) {
204                 serializeObject(((BranchNodeCase) branchNodeType).getBranchNodeList(), buffer);
205             } else if (branchNodeType instanceof NonBranchNodeCase) {
206                 serializeObject(((NonBranchNodeCase) branchNodeType).getNonBranchNodeList(), buffer);
207             }
208         }
209         serializeObject(p2mp.getLoadBalancing(), buffer);
210     }
211
212     protected void serializeMonitoringRequest(final MonitoringRequest monReq, final ByteBuf out) {
213         serializeObject(monReq.getMonitoring(), out);
214         serializeObject(monReq.getPccIdReq(), out);
215         if (monReq.getPceIdList() != null) {
216             for (final PceIdList pceId : monReq.getPceIdList()) {
217                 serializeObject(pceId.getPceId(), out);
218             }
219         }
220     }
221
222     @Override
223     protected Message validate(final List<Object> objects, final List<Message> errors)
224             throws PCEPDeserializerException {
225         Preconditions.checkArgument(objects != null, "Passed list can't be null.");
226         if (objects.isEmpty()) {
227             throw new PCEPDeserializerException("Pcrep message cannot be empty.");
228         }
229         final PcreqMessageBuilder mBuilder = new PcreqMessageBuilder().setMonitoringRequest(getMonitoring(objects));
230         final List<Svec> svecs = getSvecs(objects);
231         if (!svecs.isEmpty()) {
232             mBuilder.setSvec(svecs);
233         }
234         final List<Requests> requests = getRequests(objects, errors);
235         if (requests != null) {
236             mBuilder.setRequests(requests);
237         } else {
238             errors.add(createErrorMsg(PCEPErrors.RP_MISSING, Optional.empty()));
239         }
240         if (!objects.isEmpty()) {
241             throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
242         }
243         return new PcreqBuilder().setPcreqMessage(mBuilder.build()).build();
244     }
245
246     protected List<Svec> getSvecs(final List<Object> objects) {
247         final List<Svec> svecList = new ArrayList<>();
248         while (!objects.isEmpty()) {
249             final SvecBuilder sBuilder = new SvecBuilder();
250             final Svec svecComp = getValidSvec(sBuilder, objects);
251             if (svecComp == null) {
252                 break;
253             }
254             svecList.add(svecComp);
255         }
256         return svecList;
257     }
258
259     protected List<Requests> getRequests(final List<Object> objects, final List<Message> errors) {
260         final List<Requests> requests = new ArrayList<>();
261         while (!objects.isEmpty()) {
262             final RequestsBuilder rBuilder = new RequestsBuilder();
263             Rp rpObj = null;
264             if (!(objects.get(0) instanceof Rp)) {
265                 // if RP obj is missing return error only
266                 errors.add(createErrorMsg(PCEPErrors.RP_MISSING, Optional.empty()));
267                 return null;
268             }
269             rpObj = (Rp) objects.get(0);
270             objects.remove(0);
271             if (!rpObj.isProcessingRule()) {
272                 errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.empty()));
273             } else {
274                 rBuilder.setRp(rpObj);
275             }
276             final List<VendorInformationObject> vendorInfo = addVendorInformationObjects(objects);
277             if (!vendorInfo.isEmpty()) {
278                 rBuilder.setVendorInformationObject(vendorInfo);
279             }
280             // expansion
281             if (rpObj.isPathKey() && objects.get(0) instanceof PathKey) {
282                 rBuilder.setPathKeyExpansion(
283                         new PathKeyExpansionBuilder().setPathKey((PathKey) objects.get(0)).build());
284             }
285
286             if (objects.isEmpty() || !(objects.get(0) instanceof EndpointsObj)) {
287                 errors.add(createErrorMsg(PCEPErrors.END_POINTS_MISSING, Optional.of(rpObj)));
288                 return null;
289             }
290
291             if (!rpObj.isP2mp()) {
292                 // p2p
293                 final P2pBuilder p2pBuilder = new P2pBuilder();
294                 final EndpointsObj ep = (EndpointsObj) objects.get(0);
295                 objects.remove(0);
296                 if (!ep.isProcessingRule()) {
297                     errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.of(rpObj)));
298                 } else {
299                     p2pBuilder.setEndpointsObj(ep);
300                 }
301
302                 final SegmentComputation segm = getP2PSegmentComputation(p2pBuilder, objects, errors, rpObj);
303                 if (segm != null) {
304                     rBuilder.setSegmentComputation(segm);
305                 }
306             } else {
307                 // p2mp
308                 final SegmentComputation segm = getP2MPSegmentComputation(objects, errors, rpObj);
309                 if (segm != null) {
310                     rBuilder.setSegmentComputation(segm);
311                 }
312             }
313             requests.add(rBuilder.build());
314         }
315         return requests;
316     }
317
318     protected SegmentComputation getP2PSegmentComputation(final P2pBuilder builder,
319                                                           final List<Object> objects,
320                                                           final List<Message> errors,
321                                                           final Rp rp) {
322         final List<Metrics> metrics = new ArrayList<>();
323         final List<VendorInformationObject> viObjects = new ArrayList<>();
324
325         P2PState p2PState = P2PState.INIT;
326         while (!objects.isEmpty() && p2PState != P2PState.END) {
327             p2PState = insertP2PObject(p2PState, objects, viObjects, builder, metrics, errors, rp);
328             if (!p2PState.equals(P2PState.END)) {
329                 objects.remove(0);
330             }
331         }
332         if (!metrics.isEmpty()) {
333             builder.setMetrics(metrics);
334         }
335         if (!viObjects.isEmpty()) {
336             builder.setVendorInformationObject(viObjects);
337         }
338
339         if (rp.isReoptimization() && builder.getBandwidth() != null
340                 && !builder.getReportedRoute().getReoptimizationBandwidth().getBandwidth().equals(
341                         new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network
342                             .concepts.rev131125.Bandwidth(new byte[] { 0 }))
343                 && builder.getReportedRoute().getRro() == null) {
344             errors.add(createErrorMsg(PCEPErrors.RRO_MISSING, Optional.of(rp)));
345             return null;
346         }
347         return new SegmentComputationBuilder().setP2p(builder.build()).build();
348     }
349
350     private static P2PState insertP2PObject(final P2PState p2PState,
351                                             final List<Object> objects,
352                                             final List<VendorInformationObject> viObjects,
353                                             final P2pBuilder builder,
354                                             final List<Metrics> metrics,
355                                             final List<Message> errors,
356                                             final Rp rp) {
357         final Object obj = objects.get(0);
358         switch (p2PState) {
359             case INIT:
360                 if (obj instanceof Rro) {
361                     builder.setRro((Rro) obj);
362                     objects.remove(0);
363                     final Object nextObj = objects.get(0);
364                     if (nextObj instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types
365                             .rev181109.reoptimization.bandwidth.object.ReoptimizationBandwidth) {
366                         builder.setReoptimizationBandwidth((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns
367                                 .yang.pcep.types.rev181109.reoptimization.bandwidth.object
368                                 .ReoptimizationBandwidth) nextObj);
369                     }
370                     return P2PState.REPORTED_IN;
371                 }
372                 // fallthrough
373             case REPORTED_IN:
374                 if (obj instanceof VendorInformationObject) {
375                     viObjects.add((VendorInformationObject) obj);
376                     return P2PState.REPORTED_IN;
377                 }
378                 // fallthrough
379             case VENDOR_INFO_LIST:
380                 if (obj instanceof LoadBalancing) {
381                     builder.setLoadBalancing((LoadBalancing) obj);
382                     return P2PState.LOAD_BIN;
383                 }
384                 // fallthrough
385             case LOAD_BIN:
386                 if (obj instanceof Lspa) {
387                     builder.setLspa((Lspa) obj);
388                     return P2PState.LSPA_IN;
389                 }
390                 // fallthrough
391             case LSPA_IN:
392                 if (obj instanceof Bandwidth) {
393                     builder.setBandwidth((Bandwidth) obj);
394                     return P2PState.BANDWIDTH_IN;
395                 }
396                 // fallthrough
397             case BANDWIDTH_IN:
398                 if (obj instanceof Metric) {
399                     metrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
400                     return P2PState.BANDWIDTH_IN;
401                 }
402                 // fallthrough
403             case METRIC_IN:
404                 if (obj instanceof Iro) {
405                     builder.setIro((Iro) obj);
406                     return P2PState.IRO_IN;
407                 }
408                 // fallthrough
409             case IRO_IN:
410                 if (obj instanceof Rro) {
411                     builder.setRro((Rro) obj);
412                     return P2PState.RRO_IN;
413                 }
414                 // fallthrough
415             case RRO_IN:
416                 if (obj instanceof Xro) {
417                     builder.setXro((Xro) obj);
418                     return P2PState.XRO_IN;
419                 }
420                 // fallthrough
421             case XRO_IN:
422                 if (obj instanceof Of) {
423                     builder.setOf((Of) obj);
424                     return P2PState.OF_IN;
425                 }
426                 // fallthrough
427             case OF_IN:
428                 if (obj instanceof ClassType) {
429                     final ClassType classType = (ClassType) obj;
430                     if (!classType.isProcessingRule()) {
431                         errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.of(rp)));
432                     } else {
433                         builder.setClassType(classType);
434                     }
435                     return P2PState.CT_IN;
436                 }
437                 // fallthrough
438             case CT_IN:
439             case END:
440                 return P2PState.END;
441             default:
442                 return p2PState;
443         }
444     }
445
446     private static SvecState insertP2PObject(final SvecState state, final Object obj, final SvecBuilder builder,
447             final List<Metrics> metrics, final List<VendorInformationObject> viObjects) {
448         switch (state) {
449             case INIT:
450                 if (obj instanceof Of) {
451                     builder.setOf((Of) obj);
452                     return SvecState.OF_IN;
453                 }
454                 // fallthrough
455             case OF_IN:
456                 if (obj instanceof Gc) {
457                     builder.setGc((Gc) obj);
458                     return SvecState.GC_IN;
459                 }
460                 // fallthrough
461             case GC_IN:
462                 if (obj instanceof Xro) {
463                     builder.setXro((Xro) obj);
464                     return SvecState.XRO_IN;
465                 }
466                 // fallthrough
467             case XRO_IN:
468                 if (obj instanceof Metric) {
469                     metrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
470                     return SvecState.XRO_IN;
471                 }
472                 // fallthrough
473             case METRIC_IN:
474                 if (obj instanceof VendorInformationObject) {
475                     viObjects.add((VendorInformationObject) obj);
476                     return SvecState.METRIC_IN;
477                 }
478                 // fallthrough
479             case VENDOR_INFO:
480             case END:
481                 return SvecState.END;
482             default:
483                 return state;
484         }
485     }
486
487     private enum P2PState {
488         INIT,
489         REPORTED_IN,
490         VENDOR_INFO_LIST,
491         LOAD_BIN, LSPA_IN,
492         BANDWIDTH_IN,
493         METRIC_IN,
494         IRO_IN,
495         RRO_IN,
496         XRO_IN,
497         OF_IN,
498         CT_IN,
499         END
500     }
501
502     protected SegmentComputation getP2MPSegmentComputation(final List<Object> objects, final List<Message> errors,
503             final Rp rp) {
504         final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message
505             .pcreq.message.requests.segment.computation.p2mp.Metric> metrics = new ArrayList<>();
506         final P2mpBuilder builder = new P2mpBuilder();
507         final List<EndpointRroPair> epRros = new ArrayList<>();
508
509         P2MPState state = P2MPState.RP;
510         while (!objects.isEmpty() && state != P2MPState.END) {
511             state = insertP2MPObject(state, objects, builder, epRros, metrics, errors, rp);
512             if (!state.equals(P2MPState.END)) {
513                 objects.remove(0);
514             }
515         }
516         if (!epRros.isEmpty()) {
517             builder.setEndpointRroPair(epRros);
518         }
519         if (!metrics.isEmpty()) {
520             builder.setMetric(metrics);
521         }
522
523         if (rp.isReoptimization() && builder.getBandwidth() != null) {
524             if (!isValidReoptimizationRro(epRros) || !isValidReoptimizationBandwidth(epRros)) {
525                 errors.add(createErrorMsg(PCEPErrors.RRO_MISSING, Optional.of(rp)));
526             }
527         }
528
529         return new SegmentComputationBuilder().setP2mp(builder.build()).build();
530     }
531
532     private boolean isValidReoptimizationRro(final List<EndpointRroPair> epRros) {
533         for (EndpointRroPair epRro : epRros) {
534             if (epRro.getRros() == null || epRro.getRros().isEmpty()) {
535                 return false;
536             }
537         }
538         return true;
539     }
540
541     private boolean isValidReoptimizationBandwidth(final List<EndpointRroPair> epRros) {
542         for (EndpointRroPair epRro : epRros) {
543             if (epRro.getReoptimizationBandwidth() == null) {
544                 return false;
545             }
546         }
547         return true;
548     }
549
550     private static P2MPState insertP2MPObject(final P2MPState p2MPState, final List<Object> objects,
551             final P2mpBuilder builder, final List<EndpointRroPair> epRros,
552             final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq
553                 .message.pcreq.message.requests.segment.computation.p2mp.Metric> metrics,
554             final List<Message> errors, final Rp rp) {
555         final Object obj = objects.get(0);
556         switch (p2MPState) {
557             case RP:
558                 if (obj instanceof EndpointsObj) {
559                     final EndpointRroPairBuilder rroPairBuilder = new EndpointRroPairBuilder();
560                     if (obj.isProcessingRule()) {
561                         rroPairBuilder.setEndpointsObj((EndpointsObj) obj);
562                     } else {
563                         errors.add(createErrorMsg(PCEPErrors.P_FLAG_NOT_SET, Optional.of(rp)));
564                     }
565                     epRros.add(rroPairBuilder.setRros(new ArrayList<>()).build());
566                     return P2MPState.ENDPOINT;
567                 }
568                 // fallthrough
569             case ENDPOINT:
570                 if (obj instanceof Rro || obj instanceof Srro) {
571                     if (obj.isProcessingRule()) {
572                         final int lastIndex = epRros.size() - 1;
573                         final EndpointRroPair endpointRroPair = epRros.get(lastIndex);
574                         List<Rros> rros = endpointRroPair.getRros();
575                         if (rros == null) {
576                             rros = new ArrayList<>();
577                         }
578                         if (obj instanceof Rro) {
579                             rros.add(new RrosBuilder()
580                                     .setRouteObject(new ReportedRouteObjectCaseBuilder().setRro((Rro) obj)
581                                             .build()).build());
582                         } else {
583                             rros.add(new RrosBuilder()
584                                     .setRouteObject(new SecondaryReportedRouteObjectCaseBuilder().setSrro((Srro) obj)
585                                             .build()).build());
586                         }
587                         epRros.remove(lastIndex);
588                         epRros.add(lastIndex, new EndpointRroPairBuilder(endpointRroPair).setRros(rros).build());
589                     }
590                     return P2MPState.ENDPOINT;
591                 }
592                 // fallthrough
593             case RRO_SRRO:
594                 if (obj instanceof ReoptimizationBandwidth) {
595                     final int lastIndex = epRros.size() - 1;
596                     final EndpointRroPair endpointRroPair = epRros.get(lastIndex);
597                     epRros.remove(lastIndex);
598                     epRros.add(lastIndex, new EndpointRroPairBuilder(endpointRroPair)
599                             .setReoptimizationBandwidth((ReoptimizationBandwidth) obj)
600                             .build());
601                     return P2MPState.BANDWIDTH;
602                 }
603                 // fallthrough
604             case BANDWIDTH:
605                 if (obj instanceof EndpointsObj) {
606                     return P2MPState.RP;
607                 }
608                 if (obj instanceof Of) {
609                     builder.setOf((Of) obj);
610                     return P2MPState.OF_IN;
611                 }
612                 // fallthrough
613             case OF_IN:
614                 if (obj instanceof Lspa) {
615                     builder.setLspa((Lspa) obj);
616                     return P2MPState.LSPA_IN;
617                 }
618                 // fallthrough
619             case LSPA_IN:
620                 if (obj instanceof Bandwidth) {
621                     builder.setBandwidth((Bandwidth) obj);
622                     return P2MPState.BANDWIDTH_IN;
623                 }
624                 // fallthrough
625             case BANDWIDTH_IN:
626                 if (obj instanceof Metric) {
627                     metrics.add(new MetricBuilder().setMetric((Metric) obj).build());
628                     return P2MPState.BANDWIDTH_IN;
629                 }
630                 // fallthrough
631             case METRIC_IN:
632                 if (obj instanceof Iro) {
633                     builder.setIroBncChoice(new IroCaseBuilder().setIro((Iro) obj).build());
634                     return P2MPState.IRO_BNC_IN;
635                 }
636                 if (obj instanceof BranchNodeList) {
637                     builder.setIroBncChoice(new BncCaseBuilder().setBranchNodeType(new BranchNodeCaseBuilder()
638                             .setBranchNodeList((BranchNodeList) obj).build()).build());
639                     return P2MPState.IRO_BNC_IN;
640                 }
641                 if (obj instanceof NonBranchNodeList) {
642                     builder.setIroBncChoice(new BncCaseBuilder().setBranchNodeType(new NonBranchNodeCaseBuilder()
643                             .setNonBranchNodeList((NonBranchNodeList) obj).build()).build());
644                     return P2MPState.IRO_BNC_IN;
645                 }
646                 // fallthrough
647             case IRO_BNC_IN:
648                 if (obj instanceof LoadBalancing) {
649                     builder.setLoadBalancing((LoadBalancing) obj);
650                     return P2MPState.LOAD_BIN;
651                 }
652                 // fallthrough
653             case LOAD_BIN:
654             case END:
655             default:
656                 return P2MPState.END;
657         }
658     }
659
660     private enum P2MPState {
661         RP, ENDPOINT, RRO_SRRO, BANDWIDTH, OF_IN, LSPA_IN, BANDWIDTH_IN, METRIC_IN, IRO_BNC_IN, LOAD_BIN, END
662     }
663
664     private static Svec getValidSvec(final SvecBuilder builder, final List<Object> objects) {
665         Preconditions.checkArgument(objects != null && !objects.isEmpty(), "Passed list can't be null or empty.");
666
667         if (objects.get(0) instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types
668                 .rev181109.svec.object.Svec) {
669             builder.setSvec((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109
670                                 .svec.object.Svec) objects.get(0));
671             objects.remove(0);
672         } else {
673             return null;
674         }
675
676         final List<Metrics> metrics = new ArrayList<>();
677         final List<VendorInformationObject> viObjects = new ArrayList<>();
678
679         Object obj = null;
680         SvecState state = SvecState.INIT;
681         while (!objects.isEmpty() && !state.equals(SvecState.END)) {
682             obj = objects.get(0);
683             state = insertP2PObject(state, obj, builder, metrics, viObjects);
684             if (!state.equals(SvecState.END)) {
685                 objects.remove(0);
686             }
687         }
688         if (!viObjects.isEmpty()) {
689             builder.setVendorInformationObject(viObjects);
690         }
691         return builder.build();
692     }
693
694     private enum SvecState {
695         INIT, OF_IN, GC_IN, XRO_IN, METRIC_IN, VENDOR_INFO, END
696     }
697
698     protected MonitoringRequest getMonitoring(final List<Object> objects) {
699         final MonitoringRequestBuilder builder = new MonitoringRequestBuilder();
700         if (!objects.isEmpty() && objects.get(0) instanceof Monitoring) {
701             builder.setMonitoring((Monitoring) objects.get(0));
702             objects.remove(0);
703         } else {
704             return null;
705         }
706         if (!objects.isEmpty() && objects.get(0) instanceof PccIdReq) {
707             builder.setPccIdReq((PccIdReq) objects.get(0));
708             objects.remove(0);
709         }
710         final List<PceIdList> pceIdList = new ArrayList<>();
711         while (!objects.isEmpty() && objects.get(0) instanceof PceId) {
712             pceIdList.add(new PceIdListBuilder().setPceId((PceId) objects.get(0)).build());
713             objects.remove(0);
714         }
715         if (!pceIdList.isEmpty()) {
716             builder.setPceIdList(pceIdList);
717         }
718         return builder.build();
719     }
720 }