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.impl.message;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.Unpooled;
14 import java.util.ArrayList;
15 import java.util.List;
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.protocol.pcep.spi.VendorInformationObjectRegistry;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcrep;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcrepBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.bandwidth.object.Bandwidth;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.include.route.object.Iro;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.Metrics;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.MetricsBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.Lspa;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.metric.object.Metric;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.monitoring.metrics.MetricPce;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.monitoring.metrics.MetricPceBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.monitoring.object.Monitoring;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.of.object.Of;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.overload.object.Overload;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcc.id.req.object.PccIdReq;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pce.id.object.PceId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.PcrepMessageBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.Replies;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.RepliesBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.Result;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.FailureCase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.FailureCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.SuccessCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.SuccessCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.failure._case.NoPath;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.success._case.SuccessBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.success._case.success.Paths;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.success._case.success.PathsBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.proc.time.object.ProcTime;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.Rp;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.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, final VendorInformationObjectRegistry viRegistry) {
64 super(registry, viRegistry);
68 public void serializeMessage(final Message message, final ByteBuf out) {
69 Preconditions.checkArgument(message instanceof Pcrep, "Wrong instance of Message. Passed instance of %s. Need Pcrep.", message.getClass());
70 final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.PcrepMessage repMsg = ((Pcrep) message).getPcrepMessage();
71 if (repMsg.getReplies() == null || repMsg.getReplies().isEmpty()) {
72 throw new IllegalArgumentException("Replies cannot be null or empty.");
74 final ByteBuf buffer = Unpooled.buffer();
75 for (final Replies reply : repMsg.getReplies()) {
76 if (reply.getRp() == null) {
77 throw new IllegalArgumentException("Reply must contain RP object.");
79 serializeReply(reply, buffer);
81 MessageUtil.formatMessage(TYPE, buffer, out);
84 protected void serializeReply(final Replies reply, final ByteBuf buffer) {
85 serializeObject(reply.getRp(), buffer);
86 serializeMonitoring(reply, buffer);
87 serializeVendorInformationObjects(reply.getVendorInformationObject(), buffer);
88 if (reply.getResult() == null) {
91 if (reply.getResult() instanceof FailureCase) {
92 final FailureCase f = ((FailureCase) reply.getResult());
94 serializeObject(f.getNoPath(), buffer);
95 serializeObject(f.getLspa(), buffer);
96 serializeObject(f.getBandwidth(), buffer);
97 if (f.getMetrics() != null) {
98 for (final Metrics m : f.getMetrics()) {
99 serializeObject(m.getMetric(), buffer);
102 serializeObject(f.getIro(), buffer);
106 final SuccessCase s = (SuccessCase) reply.getResult();
107 if (s != null && s.getSuccess() != null) {
108 for (final Paths p : s.getSuccess().getPaths()) {
109 serializeObject(p.getEro(), buffer);
110 serializeObject(p.getLspa(), buffer);
111 serializeObject(p.getOf(), buffer);
112 serializeObject(p.getBandwidth(), buffer);
113 if (p.getMetrics() != null) {
114 for (final Metrics m : p.getMetrics()) {
115 serializeObject(m.getMetric(), buffer);
118 serializeObject(p.getIro(), buffer);
120 serializeVendorInformationObjects(s.getSuccess().getVendorInformationObject(), buffer);
122 serializeMonitoringMetrics(reply, buffer);
125 private void serializeMonitoring(final Replies reply, final ByteBuf buffer) {
126 serializeObject(reply.getMonitoring(), buffer);
127 serializeObject(reply.getPccIdReq(), buffer);
130 private void serializeMonitoringMetrics(final Replies reply, final ByteBuf buffer) {
131 if (reply.getMetricPce() != null) {
132 for (final MetricPce metricPce : reply.getMetricPce()) {
133 serializeMetricPce(metricPce, buffer);
138 protected void serializeMetricPce(final MetricPce metricPce, final ByteBuf buffer) {
139 Preconditions.checkArgument(metricPce.getPceId() != null, "PCE-ID must be present.");
140 serializeObject(metricPce.getPceId(), buffer);
141 serializeObject(metricPce.getProcTime(), buffer);
142 serializeObject(metricPce.getOverload(), buffer);
146 protected Pcrep validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
147 if (objects == null) {
148 throw new IllegalArgumentException("Passed list can't be null.");
150 if (objects.isEmpty()) {
151 throw new PCEPDeserializerException("Pcrep message cannot be empty.");
153 final List<Replies> replies = new ArrayList<>();
154 while (!objects.isEmpty()) {
155 final Replies r = this.getValidReply(objects, errors);
160 if (!objects.isEmpty()) {
161 throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
163 return new PcrepBuilder().setPcrepMessage(new PcrepMessageBuilder().setReplies(replies).build()).build();
166 protected Replies getValidReply(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
167 if (!(objects.get(0) instanceof Rp)) {
168 errors.add(createErrorMsg(PCEPErrors.RP_MISSING, Optional.<Rp>absent()));
171 final Rp rp = (Rp) objects.get(0);
173 final RepliesBuilder repliesBuilder = new RepliesBuilder();
174 if (!objects.isEmpty() && objects.get(0) instanceof Monitoring) {
175 repliesBuilder.setMonitoring((Monitoring) objects.get(0));
178 if (!objects.isEmpty() && objects.get(0) instanceof PccIdReq) {
179 repliesBuilder.setPccIdReq((PccIdReq) objects.get(0));
182 final List<VendorInformationObject> vendorInfo = addVendorInformationObjects(objects);
184 if (!objects.isEmpty()) {
185 if (objects.get(0) instanceof NoPath) {
186 final NoPath noPath = (NoPath) objects.get(0);
188 final FailureCaseBuilder builder = new FailureCaseBuilder();
189 builder.setNoPath(noPath);
190 while (!objects.isEmpty() && !(objects.get(0) instanceof PceId)) {
191 this.parseAttributes(builder, objects);
193 res = builder.build();
194 } else if (objects.get(0) instanceof Ero) {
195 final Ero ero = (Ero) objects.get(0);
197 final SuccessBuilder builder = new SuccessBuilder();
198 final List<Paths> paths = new ArrayList<>();
199 final PathsBuilder pBuilder = new PathsBuilder();
200 pBuilder.setEro(ero);
201 while (!objects.isEmpty() && !(objects.get(0) instanceof PceId)) {
202 final List<VendorInformationObject> vendorInfoObjects = addVendorInformationObjects(objects);
203 if (!vendorInfoObjects.isEmpty()) {
204 builder.setVendorInformationObject(vendorInfoObjects);
206 this.parsePath(pBuilder, objects);
207 paths.add(pBuilder.build());
209 builder.setPaths(paths);
210 res = new SuccessCaseBuilder().setSuccess(builder.build()).build();
213 final List<MetricPce> metricPceList = new ArrayList<>();
214 if (!objects.isEmpty() && objects.get(0) instanceof PceId) {
215 while (!objects.isEmpty()) {
216 metricPceList.add(validateMetricPce(objects));
219 if (!vendorInfo.isEmpty()) {
220 repliesBuilder.setVendorInformationObject(vendorInfo);
222 if (!metricPceList.isEmpty()) {
223 repliesBuilder.setMetricPce(metricPceList);
225 return repliesBuilder.setRp(rp).setResult(res).build();
228 protected void parseAttributes(final FailureCaseBuilder builder, final List<Object> objects) {
229 final List<Metrics> pathMetrics = new ArrayList<>();
232 State state = State.INIT;
233 while (!objects.isEmpty() && !state.equals(State.END)) {
234 obj = objects.get(0);
238 state = State.LSPA_IN;
239 if (obj instanceof Lspa) {
240 builder.setLspa((Lspa) obj);
244 state = State.BANDWIDTH_IN;
245 if (obj instanceof Bandwidth) {
246 builder.setBandwidth((Bandwidth) obj);
250 state = State.METRIC_IN;
251 if (obj instanceof Metric) {
252 pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
253 state = State.METRIC_IN;
257 state = State.IRO_IN;
258 if (obj instanceof Iro) {
259 builder.setIro((Iro) obj);
270 if (!state.equals(State.END)) {
274 if (!pathMetrics.isEmpty()) {
275 builder.setMetrics(pathMetrics);
279 protected void parsePath(final PathsBuilder builder, final List<Object> objects) {
280 final List<Metrics> pathMetrics = new ArrayList<>();
283 State state = State.INIT;
284 while (!objects.isEmpty() && !state.equals(State.END)) {
285 obj = objects.get(0);
289 state = State.LSPA_IN;
290 if (obj instanceof Lspa) {
291 builder.setLspa((Lspa) obj);
296 if (obj instanceof Of) {
297 builder.setOf((Of) obj);
301 state = State.BANDWIDTH_IN;
302 if (obj instanceof Bandwidth) {
303 builder.setBandwidth((Bandwidth) obj);
307 state = State.METRIC_IN;
308 if (obj instanceof Metric) {
309 pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
310 state = State.BANDWIDTH_IN;
314 state = State.IRO_IN;
315 if (obj instanceof Iro) {
316 builder.setIro((Iro) obj);
327 if (!state.equals(State.END)) {
331 if (!pathMetrics.isEmpty()) {
332 builder.setMetrics(pathMetrics);
337 INIT, LSPA_IN, OF_IN, BANDWIDTH_IN, METRIC_IN, IRO_IN, END
340 protected MetricPce validateMetricPce(final List<Object> objects) throws PCEPDeserializerException {
341 final MetricPceBuilder metricPceBuilder = new MetricPceBuilder();
342 if (!(objects.get(0) instanceof PceId)) {
343 throw new PCEPDeserializerException("metric-pce-list must start with PCE-ID object.");
345 metricPceBuilder.setPceId((PceId) (objects.get(0)));
347 MetricPceState state = MetricPceState.START;
348 while (!objects.isEmpty() && !state.equals(MetricPceState.END)) {
349 final Object obj = objects.get(0);
352 state = MetricPceState.PROC_TIME;
353 if (obj instanceof ProcTime) {
354 metricPceBuilder.setProcTime((ProcTime) obj);
358 state = MetricPceState.OVERLOAD;
359 if (obj instanceof Overload) {
360 metricPceBuilder.setOverload((Overload) obj);
364 state = MetricPceState.END;
369 if (!state.equals(MetricPceState.END)) {
373 return metricPceBuilder.build();
376 private enum MetricPceState {
377 START, PROC_TIME, OVERLOAD, END;