2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.pcep.parser.message;
10 import static com.google.common.base.Preconditions.checkArgument;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.Unpooled;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Optional;
17 import java.util.Queue;
18 import org.opendaylight.protocol.pcep.parser.util.Util;
19 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
20 import org.opendaylight.protocol.pcep.spi.MessageUtil;
21 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
22 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
23 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcrep;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcrepBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Object;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.Bandwidth;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.include.route.object.Iro;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.MetricsBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lspa.object.Lspa;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.metric.object.Metric;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.monitoring.metrics.MetricPce;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.monitoring.object.Monitoring;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.of.object.Of;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcc.id.req.object.PccIdReq;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pce.id.object.PceId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.PcrepMessage;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.PcrepMessageBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.Replies;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.RepliesBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.Result;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.FailureCase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.FailureCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.SuccessCase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.SuccessCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.failure._case.NoPath;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.SuccessBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.success.Paths;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.success.PathsBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.Rp;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.vendor.information.objects.VendorInformationObject;
57 * Parser for {@link Pcrep}.
59 public class PCEPReplyMessageParser extends AbstractMessageParser {
61 public static final int TYPE = 4;
63 public PCEPReplyMessageParser(final ObjectRegistry registry) {
68 public void serializeMessage(final Message message, final ByteBuf out) {
69 checkArgument(message instanceof Pcrep,
70 "Wrong instance of Message. Passed instance of %s. Need Pcrep.", message.getClass());
71 final PcrepMessage repMsg = ((Pcrep) message).getPcrepMessage();
72 final List<Replies> replies = repMsg.nonnullReplies();
74 checkArgument(!replies.isEmpty(), "Replies cannot be null or empty.");
75 final ByteBuf buffer = Unpooled.buffer();
76 for (final Replies reply : replies) {
77 checkArgument(reply.getRp() != null, "Reply must contain RP object.");
78 serializeReply(reply, buffer);
80 MessageUtil.formatMessage(TYPE, buffer, out);
83 protected void serializeReply(final Replies reply, final ByteBuf buffer) {
84 serializeObject(reply.getRp(), buffer);
85 serializeMonitoring(reply, buffer);
86 serializeVendorInformationObjects(reply.getVendorInformationObject(), buffer);
87 if (reply.getResult() == null) {
90 if (reply.getResult() instanceof FailureCase) {
91 final FailureCase f = (FailureCase) reply.getResult();
92 serializeFailure(f, buffer);
95 final SuccessCase s = (SuccessCase) reply.getResult();
96 serializeSuccess(s, buffer);
97 serializeMonitoringMetrics(reply, buffer);
100 private void serializeFailure(final FailureCase failure, final ByteBuf buffer) {
101 if (failure == null) {
104 serializeObject(failure.getNoPath(), buffer);
105 serializeObject(failure.getLspa(), buffer);
106 serializeObject(failure.getBandwidth(), buffer);
107 for (final Metrics m : failure.nonnullMetrics()) {
108 serializeObject(m.getMetric(), buffer);
110 serializeObject(failure.getIro(), buffer);
113 private void serializeSuccess(final SuccessCase success, final ByteBuf buffer) {
114 if (success == null || success.getSuccess() == null) {
117 for (final Paths p : success.getSuccess().nonnullPaths()) {
118 serializeObject(p.getEro(), buffer);
119 serializeObject(p.getLspa(), buffer);
120 serializeObject(p.getOf(), buffer);
121 serializeObject(p.getBandwidth(), buffer);
122 for (final Metrics m : p.nonnullMetrics()) {
123 serializeObject(m.getMetric(), buffer);
125 serializeObject(p.getIro(), buffer);
127 serializeVendorInformationObjects(success.getSuccess().getVendorInformationObject(), buffer);
130 private void serializeMonitoring(final Replies reply, final ByteBuf buffer) {
131 serializeObject(reply.getMonitoring(), buffer);
132 serializeObject(reply.getPccIdReq(), buffer);
135 private void serializeMonitoringMetrics(final Replies reply, final ByteBuf buffer) {
136 for (final MetricPce metricPce : reply.nonnullMetricPce()) {
137 serializeMetricPce(metricPce, buffer);
141 protected void serializeMetricPce(final MetricPce metricPce, final ByteBuf buffer) {
142 checkArgument(metricPce.getPceId() != null, "PCE-ID must be present.");
143 serializeObject(metricPce.getPceId(), buffer);
144 serializeObject(metricPce.getProcTime(), buffer);
145 serializeObject(metricPce.getOverload(), buffer);
149 protected Pcrep validate(final Queue<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
150 checkArgument(objects != null, "Passed list can't be null.");
151 if (objects.isEmpty()) {
152 throw new PCEPDeserializerException("Pcrep message cannot be empty.");
154 final List<Replies> replies = new ArrayList<>();
155 while (!objects.isEmpty()) {
156 final Replies r = this.getValidReply(objects, errors);
161 if (!objects.isEmpty()) {
162 throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
164 return new PcrepBuilder().setPcrepMessage(new PcrepMessageBuilder().setReplies(replies).build()).build();
167 protected Replies getValidReply(final Queue<Object> objects, final List<Message> errors)
168 throws PCEPDeserializerException {
169 Object obj = objects.remove();
170 if (!(obj instanceof Rp)) {
171 errors.add(createErrorMsg(PCEPErrors.RP_MISSING, Optional.empty()));
175 final RepliesBuilder repliesBuilder = new RepliesBuilder().setRp((Rp) obj);
176 obj = objects.peek();
177 if (obj instanceof Monitoring) {
178 repliesBuilder.setMonitoring((Monitoring) obj);
180 obj = objects.peek();
182 if (obj instanceof PccIdReq) {
183 repliesBuilder.setPccIdReq((PccIdReq) obj);
185 // last option, no need to peek
188 // note: this may modify 'objects'
189 final List<VendorInformationObject> vendorInfo = addVendorInformationObjects(objects);
190 if (!vendorInfo.isEmpty()) {
191 repliesBuilder.setVendorInformationObject(vendorInfo);
195 obj = objects.peek();
196 if (obj instanceof NoPath) {
198 res = handleNoPath((NoPath) obj, objects);
199 } else if (obj instanceof Ero) {
200 res = handleEros(objects);
205 if (objects.peek() instanceof PceId) {
206 final List<MetricPce> metricPceList = new ArrayList<>();
207 while (!objects.isEmpty()) {
208 metricPceList.add(Util.validateMonitoringMetrics(objects));
210 if (!metricPceList.isEmpty()) {
211 repliesBuilder.setMetricPce(metricPceList);
215 return repliesBuilder.setResult(res).build();
218 private Result handleNoPath(final NoPath noPath, final Queue<Object> objects) {
219 final FailureCaseBuilder builder = new FailureCaseBuilder().setNoPath(noPath);
220 for (Object obj = objects.peek(); obj != null && !(obj instanceof PceId); obj = objects.peek()) {
221 this.parseAttributes(builder, objects);
223 return builder.build();
226 private Result handleEros(final Queue<Object> objects) {
227 final SuccessBuilder builder = new SuccessBuilder();
228 final List<Paths> paths = new ArrayList<>();
230 for (Object obj = objects.peek(); obj != null && !(obj instanceof PceId); obj = objects.peek()) {
231 final PathsBuilder pBuilder = new PathsBuilder();
232 if (obj instanceof Ero) {
233 pBuilder.setEro((Ero) obj);
236 final List<VendorInformationObject> vendorInfoObjects = addVendorInformationObjects(objects);
237 if (!vendorInfoObjects.isEmpty()) {
238 builder.setVendorInformationObject(vendorInfoObjects);
240 this.parsePath(pBuilder, objects);
241 paths.add(pBuilder.build());
243 builder.setPaths(paths);
244 return new SuccessCaseBuilder().setSuccess(builder.build()).build();
247 protected void parseAttributes(final FailureCaseBuilder builder, final Queue<Object> objects) {
248 final List<Metrics> pathMetrics = new ArrayList<>();
250 State state = State.INIT;
251 for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
252 state = insertObject(state, obj, builder, pathMetrics);
253 if (state == State.END) {
259 if (!pathMetrics.isEmpty()) {
260 builder.setMetrics(pathMetrics);
264 private static State insertObject(final State state, final Object obj, final FailureCaseBuilder builder,
265 final List<Metrics> pathMetrics) {
268 if (obj instanceof Lspa) {
269 builder.setLspa((Lspa) obj);
270 return State.LSPA_IN;
274 if (obj instanceof Bandwidth) {
275 builder.setBandwidth((Bandwidth) obj);
276 return State.BANDWIDTH_IN;
280 if (obj instanceof Metric) {
281 pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
282 return State.BANDWIDTH_IN;
286 if (obj instanceof Iro) {
287 builder.setIro((Iro) obj);
299 private static State insertObject(final State state, final Object obj, final PathsBuilder builder,
300 final List<Metrics> pathMetrics) {
303 if (obj instanceof Lspa) {
304 builder.setLspa((Lspa) obj);
305 return State.LSPA_IN;
309 if (obj instanceof Of) {
310 builder.setOf((Of) obj);
315 if (obj instanceof Bandwidth) {
316 builder.setBandwidth((Bandwidth) obj);
317 return State.BANDWIDTH_IN;
321 if (obj instanceof Metric) {
322 pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
323 return State.BANDWIDTH_IN;
327 if (obj instanceof Iro) {
328 builder.setIro((Iro) obj);
340 protected void parsePath(final PathsBuilder builder, final Queue<Object> objects) {
341 final List<Metrics> pathMetrics = new ArrayList<>();
343 State state = State.INIT;
344 for (Object obj = objects.peek(); obj != null; obj = objects.peek()) {
345 state = insertObject(state, obj, builder, pathMetrics);
346 if (state == State.END) {
353 if (!pathMetrics.isEmpty()) {
354 builder.setMetrics(pathMetrics);
359 INIT, LSPA_IN, OF_IN, BANDWIDTH_IN, METRIC_IN, IRO_IN, END