BUG-5731: Send Error Message if LSP-IDENTIFIERS TLV is missing
[bgpcep.git] / pcep / ietf-stateful07 / src / main / java / org / opendaylight / protocol / pcep / ietf / stateful07 / Stateful07PCReportMessageParser.java
index 6849dee2c1eb7f07bd98c1338e6d9cfa05152d10..b87e758b5047d36d1e2977dc5335bca4633d07c5 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.protocol.pcep.ietf.stateful07;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
@@ -17,6 +18,7 @@ import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.protocol.pcep.spi.PSTUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Pcrpt;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.PcrptBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.Lsp;
@@ -26,6 +28,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.iet
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.reports.Path;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.reports.PathBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.Srp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.srp.Tlvs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.bandwidth.object.Bandwidth;
@@ -36,6 +39,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.Lspa;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.metric.object.Metric;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.Rro;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.Rp;
 
 /**
  * Parser for {@link Pcrpt}
@@ -53,7 +57,7 @@ public class Stateful07PCReportMessageParser extends AbstractMessageParser {
         Preconditions.checkArgument(message instanceof Pcrpt, "Wrong instance of Message. Passed instance of %s. Need Pcrpt.", message.getClass());
         final Pcrpt msg = (Pcrpt) message;
         final List<Reports> reports = msg.getPcrptMessage().getReports();
-        ByteBuf buffer = Unpooled.buffer();
+        final ByteBuf buffer = Unpooled.buffer();
         for (final Reports report : reports) {
             serializeReport(report, buffer);
         }
@@ -68,31 +72,21 @@ public class Stateful07PCReportMessageParser extends AbstractMessageParser {
         final Path p = report.getPath();
         if (p != null) {
             serializeObject(p.getEro(), buffer);
-            if (p.getLspa() != null) {
-                serializeObject(p.getLspa(), buffer);
-            }
-            if (p.getBandwidth() != null) {
-                serializeObject(p.getBandwidth(), buffer);
-            }
-            if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
+            serializeObject(p.getLspa(), buffer);
+            serializeObject(p.getBandwidth(), buffer);
+            if (p.getMetrics() != null) {
                 for (final Metrics m : p.getMetrics()) {
                     serializeObject(m.getMetric(), buffer);
                 }
             }
-            if (p.getIro() != null) {
-                serializeObject(p.getIro(), buffer);
-            }
-            if (p.getRro() != null) {
-                serializeObject(p.getRro(), buffer);
-            }
+            serializeObject(p.getIro(), buffer);
+            serializeObject(p.getRro(), buffer);
         }
     }
 
     @Override
     public Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
-        if (objects == null) {
-            throw new IllegalArgumentException("Passed list can't be null.");
-        }
+        Preconditions.checkArgument(objects != null, "Passed list can't be null.");
         if (objects.isEmpty()) {
             throw new PCEPDeserializerException("Pcrpt message cannot be empty.");
         }
@@ -111,15 +105,28 @@ public class Stateful07PCReportMessageParser extends AbstractMessageParser {
     protected Reports getValidReports(final List<Object> objects, final List<Message> errors) {
         boolean isValid = true;
         final ReportsBuilder builder = new ReportsBuilder();
+        boolean lspViaSR = false;
         if (objects.get(0) instanceof Srp) {
-            builder.setSrp((Srp) objects.get(0));
+            final Srp srp = (Srp) objects.get(0);
+            final Tlvs tlvs = srp.getTlvs();
+            if (tlvs != null) {
+                lspViaSR = PSTUtil.isDefaultPST(tlvs.getPathSetupType());
+            }
+            builder.setSrp(srp);
             objects.remove(0);
         }
+
         if (objects.get(0) instanceof Lsp) {
-            builder.setLsp((Lsp) objects.get(0));
-            objects.remove(0);
+            final Lsp lsp = (Lsp) objects.get(0);
+            if(!lspViaSR && lsp.getTlvs().getLspIdentifiers() == null && lsp.getPlspId().getValue() != 0) {
+                errors.add(createErrorMsg(PCEPErrors.LSP_IDENTIFIERS_TLV_MISSING, Optional.<Rp>absent()));
+                isValid = false;
+            } else {
+                builder.setLsp(lsp);
+                objects.remove(0);
+            }
         } else {
-            errors.add(createErrorMsg(PCEPErrors.LSP_MISSING));
+            errors.add(createErrorMsg(PCEPErrors.LSP_MISSING, Optional.<Rp>absent()));
             isValid = false;
         }
         if (!objects.isEmpty()) {
@@ -128,7 +135,7 @@ public class Stateful07PCReportMessageParser extends AbstractMessageParser {
                 pBuilder.setEro((Ero) objects.get(0));
                 objects.remove(0);
             } else {
-                errors.add(createErrorMsg(PCEPErrors.ERO_MISSING));
+                errors.add(createErrorMsg(PCEPErrors.ERO_MISSING, Optional.<Rp>absent()));
                 isValid = false;
             }
             parsePath(objects, pBuilder);
@@ -143,48 +150,11 @@ public class Stateful07PCReportMessageParser extends AbstractMessageParser {
     private void parsePath(final List<Object> objects, final PathBuilder builder) {
         final List<Metrics> pathMetrics = Lists.newArrayList();
         Object obj;
-        State state = State.Init;
-        while (!objects.isEmpty() && !state.equals(State.End)) {
+        State state = State.INIT;
+        while (!objects.isEmpty() && !state.equals(State.END)) {
             obj = objects.get(0);
-            switch (state) {
-            case Init:
-                state = State.LspaIn;
-                if (obj instanceof Lspa) {
-                    builder.setLspa((Lspa) obj);
-                    break;
-                }
-            case LspaIn:
-                state = State.BandwidthIn;
-                if (obj instanceof Bandwidth) {
-                    builder.setBandwidth((Bandwidth) obj);
-                    break;
-                }
-            case BandwidthIn:
-                state = State.MetricIn;
-                if (obj instanceof Metric) {
-                    pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
-                    state = State.BandwidthIn;
-                    break;
-                }
-            case MetricIn:
-                state = State.IroIn;
-                if (obj instanceof Iro) {
-                    builder.setIro((Iro) obj);
-                    break;
-                }
-            case IroIn:
-                state = State.RroIn;
-                if (obj instanceof Rro) {
-                    builder.setRro((Rro) obj);
-                    break;
-                }
-            case RroIn:
-                state = State.End;
-                break;
-            case End:
-                break;
-            }
-            if (!state.equals(State.End)) {
+            state = insertObject(state, obj, builder, pathMetrics);
+            if (!state.equals(State.END)) {
                 objects.remove(0);
             }
         }
@@ -193,7 +163,42 @@ public class Stateful07PCReportMessageParser extends AbstractMessageParser {
         }
     }
 
+    private State insertObject(final State state, final Object obj, final PathBuilder builder, final List<Metrics> pathMetrics) {
+        switch (state) {
+        case INIT:
+            if (obj instanceof Lspa) {
+                builder.setLspa((Lspa) obj);
+                return State.LSPA_IN;
+            }
+        case LSPA_IN:
+            if (obj instanceof Bandwidth) {
+                builder.setBandwidth((Bandwidth) obj);
+                return State.BANDWIDTH_IN;
+            }
+        case BANDWIDTH_IN:
+            if (obj instanceof Metric) {
+                pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
+                return State.BANDWIDTH_IN;
+            }
+        case METRIC_IN:
+            if (obj instanceof Iro) {
+                builder.setIro((Iro) obj);
+                return State.IRO_IN;
+            }
+        case IRO_IN:
+            if (obj instanceof Rro) {
+                builder.setRro((Rro) obj);
+                return State.RRO_IN;
+            }
+        case RRO_IN:
+        case END:
+            return State.END;
+        default:
+            return state;
+        }
+    }
+
     private enum State {
-        Init, LspaIn, BandwidthIn, MetricIn, IroIn, RroIn, End
+        INIT, LSPA_IN, BANDWIDTH_IN, METRIC_IN, IRO_IN, RRO_IN, END
     }
 }