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 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.parser.util.Util;
17 import org.opendaylight.protocol.pcep.spi.AbstractMessageParser;
18 import org.opendaylight.protocol.pcep.spi.MessageUtil;
19 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
20 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
21 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcrep;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcrepBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Object;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.Bandwidth;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.include.route.object.Iro;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.MetricsBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lspa.object.Lspa;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.metric.object.Metric;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.monitoring.metrics.MetricPce;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.monitoring.object.Monitoring;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.of.object.Of;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcc.id.req.object.PccIdReq;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pce.id.object.PceId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.PcrepMessage;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.PcrepMessageBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.Replies;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.RepliesBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.Result;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.FailureCase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.FailureCaseBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.SuccessCase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.SuccessCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.failure._case.NoPath;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.SuccessBuilder;
49 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;
50 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;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.Rp;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.vendor.information.objects.VendorInformationObject;
55 * Parser for {@link Pcrep}.
57 public class PCEPReplyMessageParser extends AbstractMessageParser {
59 public static final int TYPE = 4;
61 public PCEPReplyMessageParser(final ObjectRegistry registry) {
66 public void serializeMessage(final Message message, final ByteBuf out) {
67 Preconditions.checkArgument(message instanceof Pcrep,
68 "Wrong instance of Message. Passed instance of %s. Need Pcrep.", message.getClass());
69 final PcrepMessage repMsg = ((Pcrep) message).getPcrepMessage();
70 Preconditions.checkArgument(repMsg.getReplies() != null && !repMsg.getReplies().isEmpty(),
71 "Replies cannot be null or empty.");
72 final ByteBuf buffer = Unpooled.buffer();
73 for (final Replies reply : repMsg.getReplies()) {
74 Preconditions.checkArgument(reply.getRp() != null, "Reply must contain RP object.");
75 serializeReply(reply, buffer);
77 MessageUtil.formatMessage(TYPE, buffer, out);
80 protected void serializeReply(final Replies reply, final ByteBuf buffer) {
81 serializeObject(reply.getRp(), buffer);
82 serializeMonitoring(reply, buffer);
83 serializeVendorInformationObjects(reply.getVendorInformationObject(), buffer);
84 if (reply.getResult() == null) {
87 if (reply.getResult() instanceof FailureCase) {
88 final FailureCase f = (FailureCase) reply.getResult();
89 serializeFailure(f, buffer);
92 final SuccessCase s = (SuccessCase) reply.getResult();
93 serializeSuccess(s, buffer);
94 serializeMonitoringMetrics(reply, buffer);
97 private void serializeFailure(final FailureCase failure, final ByteBuf buffer) {
98 if (failure == null) {
101 serializeObject(failure.getNoPath(), buffer);
102 serializeObject(failure.getLspa(), buffer);
103 serializeObject(failure.getBandwidth(), buffer);
104 if (failure.getMetrics() != null) {
105 for (final Metrics m : failure.getMetrics()) {
106 serializeObject(m.getMetric(), buffer);
109 serializeObject(failure.getIro(), buffer);
112 private void serializeSuccess(final SuccessCase success, final ByteBuf buffer) {
113 if (success == null || success.getSuccess() == null) {
116 for (final Paths p : success.getSuccess().getPaths()) {
117 serializeObject(p.getEro(), buffer);
118 serializeObject(p.getLspa(), buffer);
119 serializeObject(p.getOf(), buffer);
120 serializeObject(p.getBandwidth(), buffer);
121 if (p.getMetrics() != null) {
122 for (final Metrics m : p.getMetrics()) {
123 serializeObject(m.getMetric(), buffer);
126 serializeObject(p.getIro(), buffer);
128 serializeVendorInformationObjects(success.getSuccess().getVendorInformationObject(), buffer);
131 private void serializeMonitoring(final Replies reply, final ByteBuf buffer) {
132 serializeObject(reply.getMonitoring(), buffer);
133 serializeObject(reply.getPccIdReq(), buffer);
136 private void serializeMonitoringMetrics(final Replies reply, final ByteBuf buffer) {
137 if (reply.getMetricPce() != null) {
138 for (final MetricPce metricPce : reply.getMetricPce()) {
139 serializeMetricPce(metricPce, buffer);
144 protected void serializeMetricPce(final MetricPce metricPce, final ByteBuf buffer) {
145 Preconditions.checkArgument(metricPce.getPceId() != null, "PCE-ID must be present.");
146 serializeObject(metricPce.getPceId(), buffer);
147 serializeObject(metricPce.getProcTime(), buffer);
148 serializeObject(metricPce.getOverload(), buffer);
152 protected Pcrep validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
153 Preconditions.checkArgument(objects != null, "Passed list can't be null.");
154 if (objects.isEmpty()) {
155 throw new PCEPDeserializerException("Pcrep message cannot be empty.");
157 final List<Replies> replies = new ArrayList<>();
158 while (!objects.isEmpty()) {
159 final Replies r = this.getValidReply(objects, errors);
164 if (!objects.isEmpty()) {
165 throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
167 return new PcrepBuilder().setPcrepMessage(new PcrepMessageBuilder().setReplies(replies).build()).build();
170 protected Replies getValidReply(final List<Object> objects, final List<Message> errors)
171 throws PCEPDeserializerException {
172 Object object = objects.remove(0);
173 if (!(object instanceof Rp)) {
174 errors.add(createErrorMsg(PCEPErrors.RP_MISSING, Optional.empty()));
177 final Rp rp = (Rp) object;
178 final RepliesBuilder repliesBuilder = new RepliesBuilder();
179 if (!objects.isEmpty() && objects.get(0) instanceof Monitoring) {
180 repliesBuilder.setMonitoring((Monitoring) objects.get(0));
183 if (!objects.isEmpty() && objects.get(0) instanceof PccIdReq) {
184 repliesBuilder.setPccIdReq((PccIdReq) objects.get(0));
187 final List<VendorInformationObject> vendorInfo = addVendorInformationObjects(objects);
189 if (!objects.isEmpty()) {
190 if (objects.get(0) instanceof NoPath) {
191 res = handleNoPath((NoPath) objects.get(0), objects);
192 } else if (objects.get(0) instanceof Ero) {
193 res = handleEros(objects);
196 final List<MetricPce> metricPceList = new ArrayList<>();
197 if (!objects.isEmpty() && objects.get(0) instanceof PceId) {
198 while (!objects.isEmpty()) {
199 metricPceList.add(Util.validateMonitoringMetrics(objects));
202 if (!vendorInfo.isEmpty()) {
203 repliesBuilder.setVendorInformationObject(vendorInfo);
205 if (!metricPceList.isEmpty()) {
206 repliesBuilder.setMetricPce(metricPceList);
208 return repliesBuilder.setRp(rp).setResult(res).build();
211 private Result handleNoPath(final NoPath noPath, final List<Object> objects) {
213 final FailureCaseBuilder builder = new FailureCaseBuilder().setNoPath(noPath);
214 while (!objects.isEmpty() && !(objects.get(0) instanceof PceId)) {
215 this.parseAttributes(builder, objects);
217 return builder.build();
220 private Result handleEros(final List<Object> objects) {
221 final SuccessBuilder builder = new SuccessBuilder();
222 final List<Paths> paths = new ArrayList<>();
223 while (!objects.isEmpty() && !(objects.get(0) instanceof PceId)) {
224 final PathsBuilder pBuilder = new PathsBuilder();
225 if (objects.get(0) instanceof Ero) {
226 pBuilder.setEro((Ero ) objects.remove(0));
228 final List<VendorInformationObject> vendorInfoObjects = addVendorInformationObjects(objects);
229 if (!vendorInfoObjects.isEmpty()) {
230 builder.setVendorInformationObject(vendorInfoObjects);
232 this.parsePath(pBuilder, objects);
233 paths.add(pBuilder.build());
235 builder.setPaths(paths);
236 return new SuccessCaseBuilder().setSuccess(builder.build()).build();
239 protected void parseAttributes(final FailureCaseBuilder builder, final List<Object> objects) {
240 final List<Metrics> pathMetrics = new ArrayList<>();
243 State state = State.INIT;
244 while (!objects.isEmpty() && !state.equals(State.END)) {
245 obj = objects.get(0);
246 state = insertObject(state, obj, builder, pathMetrics);
247 if (!state.equals(State.END)) {
251 if (!pathMetrics.isEmpty()) {
252 builder.setMetrics(pathMetrics);
256 private static State insertObject(final State state, final Object obj, final FailureCaseBuilder builder,
257 final List<Metrics> pathMetrics) {
260 if (obj instanceof Lspa) {
261 builder.setLspa((Lspa) obj);
262 return State.LSPA_IN;
266 if (obj instanceof Bandwidth) {
267 builder.setBandwidth((Bandwidth) obj);
268 return State.BANDWIDTH_IN;
272 if (obj instanceof Metric) {
273 pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
274 return State.BANDWIDTH_IN;
278 if (obj instanceof Iro) {
279 builder.setIro((Iro) obj);
291 private static State insertObject(final State state, final Object obj, final PathsBuilder builder,
292 final List<Metrics> pathMetrics) {
295 if (obj instanceof Lspa) {
296 builder.setLspa((Lspa) obj);
297 return State.LSPA_IN;
301 if (obj instanceof Of) {
302 builder.setOf((Of) obj);
307 if (obj instanceof Bandwidth) {
308 builder.setBandwidth((Bandwidth) obj);
309 return State.BANDWIDTH_IN;
313 if (obj instanceof Metric) {
314 pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
315 return State.BANDWIDTH_IN;
319 if (obj instanceof Iro) {
320 builder.setIro((Iro) obj);
332 protected void parsePath(final PathsBuilder builder, final List<Object> objects) {
333 final List<Metrics> pathMetrics = new ArrayList<>();
336 State state = State.INIT;
337 while (!objects.isEmpty() && !state.equals(State.END)) {
338 obj = objects.get(0);
339 state = insertObject(state, obj, builder, pathMetrics);
340 if (!state.equals(State.END)) {
344 if (!pathMetrics.isEmpty()) {
345 builder.setMetrics(pathMetrics);
350 INIT, LSPA_IN, OF_IN, BANDWIDTH_IN, METRIC_IN, IRO_IN, END