Bug-1180: Segment routing message parsers/serilizers 91/8291/4
authorMilos Fabian <milfabia@cisco.com>
Tue, 24 Jun 2014 08:02:27 +0000 (10:02 +0200)
committerRobert Varga <rovarga@cisco.com>
Thu, 26 Jun 2014 12:33:07 +0000 (12:33 +0000)
-added Segment Routing messages parsers/serializers
-extends stateful07 message parsers and PcRepMessage parser
-junit tests
-added parsers/serializers activator

Change-Id: I531b36cd0fc48a30fbfbe8b596a1faa0f1945fb0
Signed-off-by: Milos Fabian <milfabia@cisco.com>
pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SegmentRoutingActivator.java
pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrEroUtil.java [new file with mode: 0644]
pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcInitiateMessageParser.java [new file with mode: 0644]
pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcRepMessageParser.java [new file with mode: 0644]
pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcRptMessageParser.java [new file with mode: 0644]
pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcUpdMessageParser.java [new file with mode: 0644]
pcep/segment-routing/src/test/java/org/opendaylight/protocol/pcep/segment/routing02/SrMessageParserTest.java [new file with mode: 0644]

index 26e8a8aa81c014c5cf96dc168111e6d45bc0d252..ffc43582953f25f2ffce4e6af6c9104f13451744 100644 (file)
@@ -13,11 +13,16 @@ import java.util.List;
 import org.opendaylight.protocol.pcep.lsp.setup.type01.CInitiated00SrpObjectWithPstTlvParser;
 import org.opendaylight.protocol.pcep.lsp.setup.type01.PathSetupTypeTlvParser;
 import org.opendaylight.protocol.pcep.lsp.setup.type01.PcepRpObjectWithPstTlvParser;
+import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
 import org.opendaylight.protocol.pcep.spi.TlvRegistry;
 import org.opendaylight.protocol.pcep.spi.pojo.AbstractPCEPExtensionProviderActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Pcinitiate;
+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.Pcupd;
 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.lsp.setup.type._01.rev140507.path.setup.type.tlv.PathSetupType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcrep;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing._02.rev140506.add.lsp.input.arguments.ero.subobject.subobject.type.SrEroType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing._02.rev140506.sr.pce.capability.tlv.SrPceCapability;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open;
@@ -31,10 +36,10 @@ public class SegmentRoutingActivator extends AbstractPCEPExtensionProviderActiva
 
         /* Tlvs */
         regs.add(context.registerTlvParser(SrPceCapabilityTlvParser.TYPE, new SrPceCapabilityTlvParser()));
-        regs.add(context.registerTlvSerializer(SrPceCapability.class, new SrPceCapabilityTlvParser()));
-
         regs.add(context.registerTlvParser(PathSetupTypeTlvParser.TYPE, new PathSetupTypeTlvParser()));
+
         regs.add(context.registerTlvSerializer(PathSetupType.class, new PathSetupTypeTlvParser()));
+        regs.add(context.registerTlvSerializer(SrPceCapability.class, new SrPceCapabilityTlvParser()));
 
         /* Subobjects */
         regs.add(context.registerEROSubobjectParser(SrEroSubobjectParser.TYPE, new SrEroSubobjectParser()));
@@ -49,6 +54,19 @@ public class SegmentRoutingActivator extends AbstractPCEPExtensionProviderActiva
         regs.add(context.registerObjectSerializer(Srp.class, new CInitiated00SrpObjectWithPstTlvParser(tlvReg)));
         regs.add(context.registerObjectSerializer(Rp.class, new PcepRpObjectWithPstTlvParser(tlvReg)));
         regs.add(context.registerObjectSerializer(Open.class, new PcepOpenObjectWithSpcTlvParser(tlvReg)));
+
+        /* Messages */
+        final ObjectRegistry objRegistry = context.getObjectHandlerRegistry();
+        regs.add(context.registerMessageParser(SrPcRepMessageParser.TYPE, new SrPcRepMessageParser(objRegistry)));
+        regs.add(context.registerMessageParser(SrPcInitiateMessageParser.TYPE, new SrPcInitiateMessageParser(objRegistry)));
+        regs.add(context.registerMessageParser(SrPcRptMessageParser.TYPE, new SrPcRptMessageParser(objRegistry)));
+        regs.add(context.registerMessageParser(SrPcUpdMessageParser.TYPE, new SrPcUpdMessageParser(objRegistry)));
+
+        regs.add(context.registerMessageSerializer(Pcrep.class, new SrPcRepMessageParser(objRegistry)));
+        regs.add(context.registerMessageSerializer(Pcinitiate.class, new SrPcInitiateMessageParser(objRegistry)));
+        regs.add(context.registerMessageSerializer(Pcrpt.class, new SrPcRptMessageParser(objRegistry)));
+        regs.add(context.registerMessageSerializer(Pcupd.class, new SrPcUpdMessageParser(objRegistry)));
+
         return regs;
     }
 }
diff --git a/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrEroUtil.java b/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrEroUtil.java
new file mode 100644 (file)
index 0000000..46495ec
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.pcep.segment.routing02;
+
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.PathSetupTypeTlv;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing._02.rev140506.SrEroSubobject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.Subobject;
+
+public class SrEroUtil {
+
+    private static final int MPLS_LABEL_MIN_VALUE = 16;
+
+    protected static PCEPErrors validateSrEroSubobjects(final Ero ero) {
+        if(ero.getSubobject() == null || ero.getSubobject().isEmpty()) {
+            return null;
+        }
+        for(final Subobject subobject : ero.getSubobject()) {
+            if(!(subobject.getSubobjectType() instanceof SrEroSubobject)) {
+                return PCEPErrors.NON_IDENTICAL_ERO_SUBOBJECTS;
+            }
+            final SrEroSubobject srEroSubobject  = (SrEroSubobject) subobject.getSubobjectType();
+            if(srEroSubobject.getFlags().isM() && srEroSubobject.getSid() < MPLS_LABEL_MIN_VALUE) {
+                return PCEPErrors.BAD_LABEL_VALUE;
+            }
+        }
+        return null;
+    }
+
+    protected static boolean isPst(final PathSetupTypeTlv tlv) {
+        if(tlv != null && tlv.getPathSetupType() != null) {
+            if(tlv.getPathSetupType().isPst()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcInitiateMessageParser.java b/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcInitiateMessageParser.java
new file mode 100644 (file)
index 0000000..5ff342a
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.pcep.segment.routing02;
+
+import io.netty.buffer.ByteBuf;
+import java.util.List;
+import org.opendaylight.protocol.pcep.ietf.initiated00.CInitiated00PCInitiateMessageParser;
+import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.Requests;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.RequestsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.Lsp;
+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.lsp.setup.type._01.rev140507.Tlvs5;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.Tlvs7;
+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.explicit.route.object.Ero;
+
+public class SrPcInitiateMessageParser extends CInitiated00PCInitiateMessageParser {
+
+    public SrPcInitiateMessageParser(ObjectRegistry registry) {
+        super(registry);
+    }
+
+    @Override
+    protected void serializeRequest(Requests req, ByteBuf buffer) {
+        if(isSegmentRoutingPath(req.getSrp())) {
+            serializeObject(req.getSrp(), buffer);
+            if(req.getLsp() != null) {
+                serializeObject(req.getLsp(), buffer);
+            }
+            final Ero srEro = req.getEro();
+            if(srEro != null) {
+                serializeObject(srEro, buffer);
+            }
+        } else {
+            super.serializeRequest(req, buffer);
+        }
+    }
+
+    @Override
+    protected Requests getValidRequest(List<Object> objects) {
+        final Srp srp = (Srp) objects.get(0);
+        if(isSegmentRoutingPath(srp)) {
+            final RequestsBuilder builder = new RequestsBuilder();
+            builder.setSrp(srp);
+            objects.remove(0);
+            builder.setLsp((Lsp) objects.get(0));
+            objects.remove(0);
+
+            final Object obj = objects.get(0);
+            if(obj != null) {
+                if(obj instanceof Ero) {
+                    builder.setEro((Ero)obj);
+                    objects.remove(0);
+                }
+            }
+            return builder.build();
+        }
+        return super.getValidRequest(objects);
+    }
+
+    private boolean isSegmentRoutingPath(final Srp srp) {
+        if(srp != null && srp.getTlvs() != null) {
+            return SrEroUtil.isPst(srp.getTlvs().getAugmentation(Tlvs5.class)) || SrEroUtil.isPst(srp.getTlvs().getAugmentation(Tlvs7.class));
+        }
+        return false;
+    }
+
+}
diff --git a/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcRepMessageParser.java b/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcRepMessageParser.java
new file mode 100644 (file)
index 0000000..fe83fd9
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.pcep.segment.routing02;
+
+import com.google.common.collect.Lists;
+import io.netty.buffer.ByteBuf;
+import java.util.List;
+import org.opendaylight.protocol.pcep.impl.message.PCEPReplyMessageParser;
+import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.Tlvs1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.Tlvs2;
+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.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.Replies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.RepliesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.Result;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.SuccessCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.SuccessCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.success._case.SuccessBuilder;
+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;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.Rp;
+
+public class SrPcRepMessageParser extends PCEPReplyMessageParser {
+
+    public SrPcRepMessageParser(ObjectRegistry registry) {
+        super(registry);
+    }
+
+    @Override
+    protected void serializeReply(Replies reply, ByteBuf buffer) {
+        final Rp rp = reply.getRp();
+        if(isSegmentRoutingPath(rp)) {
+            serializeObject(rp, buffer);
+            if (reply.getResult() != null) {
+                if (reply.getResult() instanceof SuccessCase) {
+                    final SuccessCase s = (SuccessCase) reply.getResult();
+                    for (final Paths p : s.getSuccess().getPaths()) {
+                        final Ero ero = p.getEro();
+                        serializeObject(ero, buffer);
+                    }
+                }
+            }
+        } else {
+            super.serializeReply(reply, buffer);
+        }
+    }
+
+    @Override
+    protected Replies getValidReply(List<Object> objects, List<Message> errors) {
+        if (!(objects.get(0) instanceof Rp)) {
+            errors.add(createErrorMsg(PCEPErrors.RP_MISSING));
+            return null;
+        }
+        final Rp rp = (Rp) objects.get(0);
+        if(isSegmentRoutingPath(rp)) {
+            objects.remove(0);
+            Result res = null;
+            if (!objects.isEmpty()) {
+                if (objects.get(0) instanceof Ero) {
+                    final SuccessBuilder builder = new SuccessBuilder();
+                    final List<Paths> paths = Lists.newArrayList();
+                    final PathsBuilder pBuilder = new PathsBuilder();
+                    while (!objects.isEmpty()) {
+                        final Object object = objects.get(0);
+                        if(object instanceof Ero) {
+                            final Ero ero = (Ero) object;
+                            final PCEPErrors error = SrEroUtil.validateSrEroSubobjects(ero);
+                            if(error != null) {
+                                errors.add(createErrorMsg(error));
+                                return null;
+                            } else {
+                                paths.add(pBuilder.setEro(ero).build());
+                            }
+                        }
+                        objects.remove(0);
+                    }
+                    builder.setPaths(paths);
+                    res = new SuccessCaseBuilder().setSuccess(builder.build()).build();
+                }
+            }
+            return new RepliesBuilder().setRp(rp).setResult(res).build();
+        }
+        return super.getValidReply(objects, errors);
+    }
+
+    private boolean isSegmentRoutingPath(final Rp rp) {
+        if(rp.getTlvs() != null) {
+            return SrEroUtil.isPst(rp.getTlvs().getAugmentation(Tlvs1.class)) || SrEroUtil.isPst(rp.getTlvs().getAugmentation(Tlvs2.class));
+        }
+        return false;
+    }
+}
diff --git a/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcRptMessageParser.java b/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcRptMessageParser.java
new file mode 100644 (file)
index 0000000..372649c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.pcep.segment.routing02;
+
+import io.netty.buffer.ByteBuf;
+import java.util.List;
+import org.opendaylight.protocol.pcep.ietf.stateful07.Stateful07PCReportMessageParser;
+import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.Reports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.ReportsBuilder;
+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.lsp.setup.type._01.rev140507.Tlvs7;
+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.explicit.route.object.Ero;
+
+public class SrPcRptMessageParser extends Stateful07PCReportMessageParser {
+
+    public SrPcRptMessageParser(ObjectRegistry registry) {
+        super(registry);
+    }
+
+    @Override
+    protected void serializeReport(Reports report, ByteBuf buffer) {
+        if(isSegmentRoutingPath(report.getSrp())) {
+            serializeObject(report.getSrp(), buffer);
+            serializeObject(report.getLsp(), buffer);
+            final Ero srEro = report.getPath().getEro();
+            if(srEro != null) {
+                serializeObject(srEro, buffer);
+            }
+        } else {
+            super.serializeReport(report, buffer);
+        }
+    }
+
+    @Override
+    protected Reports getValidReports(List<Object> objects, List<Message> errors) {
+        if(!(objects.get(0) instanceof Srp)) {
+            errors.add(createErrorMsg(PCEPErrors.SRP_MISSING));
+        }
+        final Srp srp = (Srp) objects.get(0);
+        if(isSegmentRoutingPath(srp)) {
+            boolean isValid = true;
+            final ReportsBuilder builder = new ReportsBuilder();
+            builder.setSrp(srp);
+            objects.remove(0);
+            if (objects.get(0) instanceof Lsp) {
+                builder.setLsp((Lsp) objects.get(0));
+                objects.remove(0);
+            } else {
+                errors.add(createErrorMsg(PCEPErrors.LSP_MISSING));
+                isValid = false;
+            }
+
+            final Object obj = objects.get(0);
+            if(obj instanceof Ero) {
+                final Ero ero = (Ero) obj;
+                final PCEPErrors error = SrEroUtil.validateSrEroSubobjects(ero);
+                if(error != null) {
+                    errors.add(createErrorMsg(error));
+                    isValid = false;
+                } else {
+                    builder.setPath(new PathBuilder().setEro(ero).build());
+                }
+                objects.remove(0);
+            } else {
+                errors.add(createErrorMsg(PCEPErrors.ERO_MISSING));
+                isValid = false;
+            }
+            if(isValid) {
+                return builder.build();
+            }
+            return null;
+        }
+        return super.getValidReports(objects, errors);
+    }
+
+    private boolean isSegmentRoutingPath(final Srp srp) {
+        if(srp != null && srp.getTlvs() != null) {
+            return SrEroUtil.isPst(srp.getTlvs().getAugmentation(Tlvs7.class));
+        }
+        return false;
+    }
+
+}
diff --git a/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcUpdMessageParser.java b/pcep/segment-routing/src/main/java/org/opendaylight/protocol/pcep/segment/routing02/SrPcUpdMessageParser.java
new file mode 100644 (file)
index 0000000..612c415
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.pcep.segment.routing02;
+
+import io.netty.buffer.ByteBuf;
+import java.util.List;
+import org.opendaylight.protocol.pcep.ietf.stateful07.Stateful07PCUpdateRequestMessageParser;
+import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.Updates;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.UpdatesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.updates.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.lsp.setup.type._01.rev140507.Tlvs6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.Tlvs7;
+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.explicit.route.object.Ero;
+
+public class SrPcUpdMessageParser extends Stateful07PCUpdateRequestMessageParser {
+
+    public SrPcUpdMessageParser(ObjectRegistry registry) {
+        super(registry);
+    }
+
+    @Override
+    protected void serializeUpdate(Updates update, ByteBuf buffer) {
+        if(isSegmentRoutingPath(update.getSrp())) {
+            serializeObject(update.getSrp(), buffer);
+            if(update.getLsp() != null) {
+                serializeObject(update.getLsp(), buffer);
+            }
+            final Ero srEro = update.getPath().getEro();
+            if(srEro != null) {
+                serializeObject(srEro, buffer);
+            }
+        } else {
+            super.serializeUpdate(update, buffer);
+        }
+    }
+
+    @Override
+    protected Updates getValidUpdates(List<Object> objects, List<Message> errors) {
+        if(objects.get(0) instanceof Srp && isSegmentRoutingPath((Srp) objects.get(0))) {
+            boolean isValid = true;
+            final Srp srp = (Srp) objects.get(0);
+            final UpdatesBuilder builder = new UpdatesBuilder();
+            builder.setSrp(srp);
+            objects.remove(0);
+            if (objects.get(0) instanceof Lsp) {
+                builder.setLsp((Lsp) objects.get(0));
+                objects.remove(0);
+            } else {
+                errors.add(createErrorMsg(PCEPErrors.LSP_MISSING));
+                isValid = false;
+            }
+
+            final Object obj = objects.get(0);
+            if(obj instanceof Ero) {
+                final Ero ero = (Ero) obj;
+                final PCEPErrors error = SrEroUtil.validateSrEroSubobjects(ero);
+                if(error != null) {
+                    errors.add(createErrorMsg(error));
+                    isValid = false;
+                } else {
+                    builder.setPath(new PathBuilder().setEro(ero).build());
+                    objects.remove(0);
+                }
+            } else {
+                errors.add(createErrorMsg(PCEPErrors.ERO_MISSING));
+                isValid = false;
+            }
+            if(isValid) {
+                return builder.build();
+            }
+            return null;
+        }
+        return super.getValidUpdates(objects, errors);
+    }
+
+    private boolean isSegmentRoutingPath(final Srp srp) {
+        if(srp != null && srp.getTlvs() != null) {
+            return SrEroUtil.isPst(srp.getTlvs().getAugmentation(Tlvs6.class)) || SrEroUtil.isPst(srp.getTlvs().getAugmentation(Tlvs7.class));
+        }
+        return false;
+    }
+
+}
diff --git a/pcep/segment-routing/src/test/java/org/opendaylight/protocol/pcep/segment/routing02/SrMessageParserTest.java b/pcep/segment-routing/src/test/java/org/opendaylight/protocol/pcep/segment/routing02/SrMessageParserTest.java
new file mode 100644 (file)
index 0000000..81eaae3
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.pcep.segment.routing02;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import com.google.common.collect.Lists;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.protocol.pcep.ietf.stateful07.StatefulActivator;
+import org.opendaylight.protocol.pcep.impl.Activator;
+import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.pojo.SimplePCEPExtensionProviderContext;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.PcinitiateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.PcinitiateMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.RequestsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.OperationalStatus;
+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.PcupdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.PlspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.SrpIdNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.LspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.PcrptMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.ReportsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.PcupdMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.UpdatesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcupd.message.pcupd.message.updates.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.SrpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.Tlvs1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.Tlvs1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.Tlvs7;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.Tlvs7Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.lsp.setup.type._01.rev140507.path.setup.type.tlv.PathSetupTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcerr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcerrBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcrepBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing._02.rev140506.SidType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing._02.rev140506.SrEroSubobject.Flags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing._02.rev140506.add.lsp.input.arguments.ero.subobject.subobject.type.SrEroTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing._02.rev140506.sr.ero.subobject.nai.IpNodeIdBuilder;
+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.RequestId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.EroBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.Subobject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.SubobjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcep.error.object.ErrorObjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.ErrorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.PcrepMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.Replies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.RepliesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.SuccessCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcrep.message.pcrep.message.replies.result.success._case.SuccessBuilder;
+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;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.Rp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.RpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.rp.TlvsBuilder;
+
+public class SrMessageParserTest {
+
+    private SimplePCEPExtensionProviderContext ctx;
+    private SegmentRoutingActivator srActivator;
+    private Activator activator;
+    private StatefulActivator statefulActivator;
+    private ObjectRegistry objectRegistry;
+
+    @Before
+    public void setup() {
+        this.ctx = new SimplePCEPExtensionProviderContext();
+        this.activator = new Activator();
+        this.activator.start(this.ctx);
+        this.statefulActivator = new StatefulActivator();
+        this.statefulActivator.start(this.ctx);
+        this.srActivator = new SegmentRoutingActivator();
+        this.srActivator.start(this.ctx);
+        this.objectRegistry = this.ctx.getObjectHandlerRegistry();
+    }
+
+    @Test
+    public void testReplyMsg() throws IOException, PCEPDeserializerException {
+        byte[] replyMsgBytes = {
+            0x20,0x04,0x00,0x28,
+            /* rp-object */
+            0x02,0x10,0x00,0x14,
+            0x00,0x00,0x04,0x2d,
+            (byte)0xde,(byte)0xad,(byte)0xbe,(byte)0xef,
+            /* pst-tlv */
+            0x00,0x1b,0x00,0x04,
+            0x00,0x00,0x00,0x01,
+            /* sr-ero-object */
+            0x07,0x10,0x00,0x10,
+            /* sr-ero subobject */
+            0x05,0x0c,(byte) 0x10,0x00,
+            0x00,0x01,(byte) 0xe2,0x40,
+            0x4A,0x7D,0x2b,0x63};
+
+        final SrPcRepMessageParser parser = new SrPcRepMessageParser(this.objectRegistry);
+
+        final PcrepMessageBuilder builder = new PcrepMessageBuilder();
+        final RepliesBuilder rBuilder = new RepliesBuilder();
+
+        final List<Replies> replies = Lists.newArrayList();
+        rBuilder.setRp(createRpObject());
+
+        final List<Paths> paths = Lists.newArrayList();
+        final PathsBuilder paBuilder = new PathsBuilder();
+
+        paBuilder.setEro(createSrEroObject());
+
+        paths.add(paBuilder.build());
+        rBuilder.setResult(new SuccessCaseBuilder().setSuccess(new SuccessBuilder().setPaths(paths).build()).build()).build();
+        replies.add(rBuilder.build());
+        builder.setReplies(replies);
+
+        ByteBuf buf = Unpooled.wrappedBuffer(replyMsgBytes);
+        assertEquals(new PcrepBuilder().setPcrepMessage(builder.build()).build(), parser.parseMessage(buf.slice(4,
+                buf.readableBytes() - 4), Collections.<Message> emptyList()));
+
+        buf = Unpooled.buffer(replyMsgBytes.length);
+        parser.serializeMessage(new PcrepBuilder().setPcrepMessage(builder.build()).build(), buf);
+        assertArrayEquals(replyMsgBytes, buf.array());
+    }
+
+    @Test
+    public void testInitiateMsg() throws PCEPDeserializerException {
+
+        final byte[] statefulMsg= {
+            0x20,0x0C,0x00,0x30,
+            /* srp-object */
+            0x21,0x10,0x00,0x14,
+            0x00,0x00,0x00,0x001,
+            0x00,0x00,0x00,0x01,
+            /* pst-tlv */
+            0x00,0x1b,0x00,0x04,
+            0x00,0x00,0x00,0x01,
+            /* lsp-object */
+            0x20,0x10,0x00,0x08,
+            0x00,0x00,0x00,0x00,
+            /* sr-ero-object */
+            0x07,0x10,0x00,0x10,
+            /* sr-ero subobject */
+            0x05,0x0c,(byte) 0x10,0x00,
+            0x00,0x01,(byte) 0xe2,0x40,
+            0x4A,0x7D,0x2b,0x63};
+
+        final SrPcInitiateMessageParser parser = new SrPcInitiateMessageParser(objectRegistry);
+
+        final PcinitiateMessageBuilder builder = new PcinitiateMessageBuilder();
+        final RequestsBuilder reqBuilder = new RequestsBuilder();
+        reqBuilder.setLsp(createLspObject());
+        reqBuilder.setSrp(createSrpObject());
+
+        reqBuilder.setEro(createSrEroObject());
+        builder.setRequests(Lists.newArrayList(reqBuilder.build()));
+
+        final ByteBuf buf = Unpooled.wrappedBuffer(statefulMsg);
+        assertEquals(new PcinitiateBuilder().setPcinitiateMessage(builder.build()).build(), parser.parseMessage(buf.slice(4,
+                buf.readableBytes() - 4), Collections.<Message> emptyList()));
+
+        final ByteBuf buffer = Unpooled.buffer(statefulMsg.length);
+        parser.serializeMessage(new PcinitiateBuilder().setPcinitiateMessage(builder.build()).build(), buffer);
+        assertArrayEquals(statefulMsg, buffer.array());
+    }
+
+    @Test
+    public void testRptMsg() throws PCEPDeserializerException {
+        final byte[] statefulMsg= {
+            0x20,0x0A,0x00,0x30,
+            /* srp-object */
+            0x21,0x10,0x00,0x14,
+            0x00,0x00,0x00,0x001,
+            0x00,0x00,0x00,0x01,
+            /* pst-tlv */
+            0x00,0x1b,0x00,0x04,
+            0x00,0x00,0x00,0x01,
+            /* lsp-object */
+            0x20,0x10,0x00,0x08,
+            0x00,0x00,0x00,0x00,
+            /* sr-ero-object */
+            0x07,0x10,0x00,0x10,
+            /* sr-ero subobject */
+            0x05,0x0c,(byte) 0x10,0x00,
+            0x00,0x01,(byte) 0xe2,0x40,
+            0x4A,0x7D,0x2b,0x63};
+
+        final SrPcRptMessageParser parser = new SrPcRptMessageParser(objectRegistry);
+        final PcrptMessageBuilder builder = new PcrptMessageBuilder();
+        final ReportsBuilder rptBuilder = new ReportsBuilder();
+        rptBuilder.setLsp(createLspObject());
+        rptBuilder.setSrp(createSrpObject());
+        rptBuilder.setPath(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.pcrpt.message.reports.PathBuilder().setEro(createSrEroObject()).build());
+        builder.setReports(Lists.newArrayList(rptBuilder.build()));
+
+        final ByteBuf buf = Unpooled.wrappedBuffer(statefulMsg);
+        assertEquals(new PcrptBuilder().setPcrptMessage(builder.build()).build(), parser.parseMessage(buf.slice(4,
+                buf.readableBytes() - 4), Collections.<Message> emptyList()));
+
+        final ByteBuf buffer = Unpooled.buffer(statefulMsg.length);
+        parser.serializeMessage(new PcrptBuilder().setPcrptMessage(builder.build()).build(), buffer);
+        assertArrayEquals(statefulMsg, buffer.array());
+    }
+
+    @Test
+    public void testUpdMsg() throws PCEPDeserializerException {
+        final byte[] statefulMsg= {
+            0x20,0x0B,0x00,0x30,
+            /* srp-object */
+            0x21,0x10,0x00,0x14,
+            0x00,0x00,0x00,0x001,
+            0x00,0x00,0x00,0x01,
+            /* pst-tlv */
+            0x00,0x1b,0x00,0x04,
+            0x00,0x00,0x00,0x01,
+            /* lsp-object */
+            0x20,0x10,0x00,0x08,
+            0x00,0x00,0x00,0x00,
+            /* sr-ero-object */
+            0x07,0x10,0x00,0x10,
+            /* sr-ero subobject */
+            0x05,0x0c,(byte) 0x10,0x00,
+            0x00,0x01,(byte) 0xe2,0x40,
+            0x4A,0x7D,0x2b,0x63};
+
+        final SrPcUpdMessageParser parser = new SrPcUpdMessageParser(objectRegistry);
+        final PcupdMessageBuilder builder = new PcupdMessageBuilder();
+        final UpdatesBuilder updBuilder = new UpdatesBuilder();
+        updBuilder.setLsp(createLspObject());
+        updBuilder.setSrp(createSrpObject());
+        updBuilder.setPath(new PathBuilder().setEro(createSrEroObject()).build());
+        builder.setUpdates(Lists.newArrayList(updBuilder.build()));
+
+        final ByteBuf buf = Unpooled.wrappedBuffer(statefulMsg);
+        assertEquals(new PcupdBuilder().setPcupdMessage(builder.build()).build(), parser.parseMessage(buf.slice(4,
+                buf.readableBytes() - 4), Collections.<Message> emptyList()));
+
+        final ByteBuf buffer = Unpooled.buffer(statefulMsg.length);
+        parser.serializeMessage(new PcupdBuilder().setPcupdMessage(builder.build()).build(), buffer);
+        assertArrayEquals(statefulMsg, buffer.array());
+    }
+
+    @Test
+    public void testNonIdenticalEroSubobjectError() throws PCEPDeserializerException {
+        final byte[] statefulMsg= {
+            0x20,0x0B,0x00,0x30,
+            /* srp-object */
+            0x21,0x10,0x00,0x14,
+            0x00,0x00,0x00,0x001,
+            0x00,0x00,0x00,0x01,
+            /* pst-tlv */
+            0x00,0x1b,0x00,0x04,
+            0x00,0x00,0x00,0x01,
+            /* lsp-object */
+            0x20,0x10,0x00,0x08,
+            0x00,0x00,0x00,0x00,
+            /* sr-ero-object */
+            0x07,0x10,0x00,0x18,
+            /* sr-ero subobject */
+            0x05,0x0c,(byte) 0x10,0x00,
+            0x00,0x01,(byte) 0xe2,0x40,
+            0x4A,0x7D,0x2b,0x63,
+            /* ipv4 prefix subobject */
+            (byte) 0x81,0x08,(byte) 0xFF,(byte) 0xFF,
+            (byte) 0xFF,(byte) 0xFF,0x16,0x00};
+
+        final SrPcRptMessageParser parser = new SrPcRptMessageParser(objectRegistry);
+
+        final ByteBuf buf = Unpooled.wrappedBuffer(statefulMsg);
+        List<Message> errors = Lists.newArrayList();
+        parser.parseMessage(buf.slice(4, buf.readableBytes() - 4), errors);
+
+        assertFalse(errors.isEmpty());
+        assertEquals(createErrorMessage((short)10, (short)5), errors.get(0));
+    }
+
+    @Test
+    public void testBadLabelValueError() throws PCEPDeserializerException {
+        final byte[] statefulMsg= {
+            0x20,0x0A,0x00,0x30,
+            /* srp-object */
+            0x21,0x10,0x00,0x14,
+            0x00,0x00,0x00,0x001,
+            0x00,0x00,0x00,0x01,
+            /* pst-tlv */
+            0x00,0x1b,0x00,0x04,
+            0x00,0x00,0x00,0x01,
+            /* lsp-object */
+            0x20,0x10,0x00,0x08,
+            0x00,0x00,0x00,0x00,
+            /* sr-ero-object */
+            0x07,0x10,0x00,0x10,
+            /* sr-ero subobject */
+            0x05,0x0c,(byte) 0x10,0x01,
+            0x00,0x00,0x00,0x03,
+            0x4A,0x7D,0x2b,0x63};
+
+        final SrPcRptMessageParser parser = new SrPcRptMessageParser(objectRegistry);
+
+        final ByteBuf buf = Unpooled.wrappedBuffer(statefulMsg);
+        final List<Message> errors = Lists.newArrayList();
+        parser.parseMessage(buf.slice(4, buf.readableBytes() - 4), errors);
+
+        assertFalse(errors.isEmpty());
+        assertEquals(createErrorMessage((short)10, (short)2), errors.get(0));
+    }
+
+    private Ero createSrEroObject() {
+        final SrEroTypeBuilder srEroBuilder = new SrEroTypeBuilder();
+        srEroBuilder.setFlags(new Flags(false, false, false, false));
+        srEroBuilder.setSidType(SidType.Ipv4NodeId);
+        srEroBuilder.setSid(123456L);
+        srEroBuilder.setNai(new IpNodeIdBuilder().setIpAddress(new IpAddress(new Ipv4Address("74.125.43.99"))).build());
+        final SubobjectBuilder subobjBuilder = new SubobjectBuilder().setSubobjectType(srEroBuilder.build()).setLoose(false);
+
+        final List<Subobject> subobjects = Lists.newArrayList(subobjBuilder.build());
+        return new EroBuilder().setProcessingRule(false).setIgnore(false).setSubobject(subobjects).build();
+    }
+
+    private Lsp createLspObject() {
+        final LspBuilder lspBuilder = new LspBuilder();
+        lspBuilder.setIgnore(false);
+        lspBuilder.setProcessingRule(false);
+        lspBuilder.setAdministrative(false);
+        lspBuilder.setDelegate(false);
+        lspBuilder.setPlspId(new PlspId(0L));
+        lspBuilder.setOperational(OperationalStatus.Down);
+        lspBuilder.setSync(false);
+        lspBuilder.setRemove(false);
+        lspBuilder.setTlvs(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.lsp.object.lsp.TlvsBuilder().build());
+        return lspBuilder.build();
+    }
+
+    private Rp createRpObject() {
+        final RpBuilder rpBuilder = new RpBuilder();
+        rpBuilder.setProcessingRule(false);
+        rpBuilder.setIgnore(false);
+        rpBuilder.setReoptimization(true);
+        rpBuilder.setBiDirectional(false);
+        rpBuilder.setLoose(true);
+        rpBuilder.setMakeBeforeBreak(true);
+        rpBuilder.setOrder(false);
+        rpBuilder.setPathKey(false);
+        rpBuilder.setSupplyOf(false);
+        rpBuilder.setFragmentation(false);
+        rpBuilder.setP2mp(false);
+        rpBuilder.setEroCompression(false);
+        rpBuilder.setPriority((short) 5);
+        rpBuilder.setRequestId(new RequestId(0xdeadbeefL));
+        rpBuilder.setTlvs(new TlvsBuilder().addAugmentation(Tlvs1.class,
+                new Tlvs1Builder().setPathSetupType(new PathSetupTypeBuilder().setPst(true).build()).build()).build());
+        return rpBuilder.build();
+    }
+
+    private Srp createSrpObject() {;
+        final SrpBuilder builder = new SrpBuilder();
+        builder.setProcessingRule(false);
+        builder.setIgnore(false);
+        builder.setOperationId(new SrpIdNumber(1L));
+        builder.addAugmentation(Srp1.class, new Srp1Builder().setRemove(true).build());
+        builder.setTlvs(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.srp.object.srp.TlvsBuilder()
+                .addAugmentation(Tlvs7.class,
+                        new Tlvs7Builder().setPathSetupType(new PathSetupTypeBuilder().setPst(true).build()).build())
+                .build());
+        return builder.build();
+    }
+
+    private Pcerr createErrorMessage(final short type, final short value) {
+        final PcerrMessageBuilder errMsgBuilder = new PcerrMessageBuilder();
+        errMsgBuilder.setErrors(Lists.newArrayList(new ErrorsBuilder().setErrorObject(
+                new ErrorObjectBuilder().setType(type).setValue(value).build()).build()));
+        final PcerrBuilder builder = new PcerrBuilder();
+        builder.setPcerrMessage(errMsgBuilder.build());
+        return builder.build();
+    }
+}