Bug-479: Implementation of Vendor-Information Object 48/9648/7
authorMilos Fabian <milfabia@cisco.com>
Mon, 4 Aug 2014 11:25:04 +0000 (13:25 +0200)
committerRobert Varga <rovarga@cisco.com>
Tue, 5 Aug 2014 12:14:45 +0000 (14:14 +0200)
-reference: http://tools.ietf.org/html/draft-ietf-pce-rfc7150bis-00
-added yang model of new object
-added abstract skeleton of Vendor-Information object parser/serializer
-PCReq and PCRep Messages models and parsers enhanced with list of VI objects
-introduced new Vendor-Information object parsers/serializers registry
-added junit tests

Change-Id: Icbf1ff79542cc2f7e5219de208ec015e31323730
Signed-off-by: Milos Fabian <milfabia@cisco.com>
25 files changed:
pcep/api/src/main/yang/pcep-types.yang
pcep/ietf-stateful02/src/main/java/org/opendaylight/protocol/pcep/ietf/stateful02/Stateful02PCReplyMessageParser.java
pcep/ietf-stateful02/src/main/java/org/opendaylight/protocol/pcep/ietf/stateful02/Stateful02PCRequestMessageParser.java
pcep/ietf-stateful02/src/main/java/org/opendaylight/protocol/pcep/ietf/stateful02/StatefulActivator.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/Activator.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/message/PCEPReplyMessageParser.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/message/PCEPRequestMessageParser.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/object/AbstractVendorInformationObjectParser.java [new file with mode: 0644]
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPObjectParserTest.java
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPValidatorTest.java
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/TestVendorInformationActivator.java
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/TestVendorInformationObjectParser.java [new file with mode: 0644]
pcep/impl/src/test/resources/PCRep.6.bin [new file with mode: 0644]
pcep/impl/src/test/resources/PCReq.7.bin [new file with mode: 0644]
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/SrPcRepMessageParser.java
pcep/segment-routing/src/test/java/org/opendaylight/protocol/pcep/segment/routing02/SrMessageParserTest.java
pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/AbstractMessageParser.java
pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/PCEPExtensionConsumerContext.java
pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/PCEPExtensionProviderContext.java
pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/VendorInformationObjectRegistry.java [new file with mode: 0644]
pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/VendorInformationUtil.java
pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/pojo/SimplePCEPExtensionProviderContext.java
pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/pojo/SimpleVendorInformationObjectRegistry.java [new file with mode: 0644]
pcep/spi/src/test/java/org/opendaylight/protocol/pcep/spi/UtilsTest.java

index 5aaa39090151a78d777d6ce5f06827e017e3c82b..90bbb8872eb759c427dbb450e9381c817f7d47c9 100644 (file)
@@ -214,6 +214,15 @@ module pcep-types {
         }
     }
 
+    grouping vendor-information-objects {
+        list vendor-information-object {
+            description "VENDOR-INFORMATION-OBJECT";
+            reference "http://tools.ietf.org/html/draft-ietf-pce-rfc7150bis-00#section-2";
+            uses object;
+            uses vendor-information;
+        }
+    }
+
     grouping open-object {
         description "OPEN Object";
         reference "https://tools.ietf.org/html/rfc5440#section-7.3";
@@ -854,11 +863,15 @@ module pcep-types {
                             uses bandwidth-object;
                         }
 
+                        uses vendor-information-objects;
+
                         uses load-balancing-object;
 
                         uses lsp-attributes;
                     }
                 }
+
+                uses vendor-information-objects;
             }
 
             list svec {
@@ -873,6 +886,8 @@ module pcep-types {
                 list metric {
                     uses metric-object;
                 }
+
+                uses vendor-information-objects;
             }
         }
     }
@@ -894,6 +909,7 @@ module pcep-types {
 
             list replies {
                 uses rp-object;
+                uses vendor-information-objects;
 
                 choice result {
                     case success-case {
@@ -901,6 +917,7 @@ module pcep-types {
                             list paths {
                                 uses path-definition;
                             }
+                            uses vendor-information-objects;
                         }
                     }
                     case failure-case {
index a0249b8246d85a50c1fe49ab19e9aa38f4d13d04..993f5fea1eb76ae66f3db24fa69a97f322f14ea2 100644 (file)
@@ -9,16 +9,14 @@ package org.opendaylight.protocol.pcep.ietf.stateful02;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
-
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-
 import java.util.List;
-
 import org.opendaylight.protocol.pcep.impl.message.PCEPReplyMessageParser;
 import org.opendaylight.protocol.pcep.spi.MessageUtil;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.protocol.pcep.spi.VendorInformationObjectRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Replies1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Replies1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.Lsp;
@@ -45,8 +43,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
  */
 public final class Stateful02PCReplyMessageParser extends PCEPReplyMessageParser {
 
-    public Stateful02PCReplyMessageParser(final ObjectRegistry registry) {
-        super(registry);
+    public Stateful02PCReplyMessageParser(final ObjectRegistry registry, final VendorInformationObjectRegistry viReg) {
+        super(registry, viReg);
     }
 
     @Override
index afbd0e6e1882db993abf4c20fe3bf78220148229..7003ada7be2fe33cbe75a3650b66e744558b505c 100644 (file)
@@ -13,6 +13,7 @@ import java.util.List;
 import org.opendaylight.protocol.pcep.impl.message.PCEPRequestMessageParser;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.protocol.pcep.spi.VendorInformationObjectRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.P2p1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.P2p1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.Lsp;
@@ -42,8 +43,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
  */
 public final class Stateful02PCRequestMessageParser extends PCEPRequestMessageParser {
 
-    public Stateful02PCRequestMessageParser(final ObjectRegistry registry) {
-        super(registry);
+    public Stateful02PCRequestMessageParser(final ObjectRegistry registry, final VendorInformationObjectRegistry viReg) {
+        super(registry, viReg);
     }
 
     @Override
index 784e346493b57996fb3e709dd162482a41a129c8..0c176966258a7ffcbb31347aded80399efc97801 100644 (file)
@@ -39,12 +39,15 @@ public class StatefulActivator extends AbstractPCEPExtensionProviderActivator {
         regs.add(context.registerMessageSerializer(Pcrpt.class, new Stateful02PCReportMessageParser(context.getObjectHandlerRegistry())));
 
         regs.add(context.registerMessageParser(Stateful02PCReplyMessageParser.TYPE,
-                new Stateful02PCReplyMessageParser(context.getObjectHandlerRegistry())));
-        regs.add(context.registerMessageSerializer(Pcrep.class, new Stateful02PCReplyMessageParser(context.getObjectHandlerRegistry())));
+                new Stateful02PCReplyMessageParser(context.getObjectHandlerRegistry(), context.getVendorInformationObjectRegistry())));
+        regs.add(context.registerMessageSerializer(Pcrep.class, new Stateful02PCReplyMessageParser(context.getObjectHandlerRegistry(),
+                context.getVendorInformationObjectRegistry())));
 
         regs.add(context.registerMessageParser(Stateful02PCRequestMessageParser.TYPE,
-                new Stateful02PCRequestMessageParser(context.getObjectHandlerRegistry())));
-        regs.add(context.registerMessageSerializer(Pcreq.class, new Stateful02PCRequestMessageParser(context.getObjectHandlerRegistry())));
+                new Stateful02PCRequestMessageParser(context.getObjectHandlerRegistry(),
+                        context.getVendorInformationObjectRegistry())));
+        regs.add(context.registerMessageSerializer(Pcreq.class, new Stateful02PCRequestMessageParser(context.getObjectHandlerRegistry(),
+                context.getVendorInformationObjectRegistry())));
 
         regs.add(context.registerObjectParser(Stateful02LspObjectParser.CLASS, Stateful02LspObjectParser.TYPE,
                 new Stateful02LspObjectParser(context.getTlvHandlerRegistry(), context.getVendorInformationTlvRegistry())));
index 773c117e7ff2498fc73a13f9adac38aa19a0f651..45223efbe2f1fee51edbebbfafc20bca7c8782fa 100644 (file)
@@ -71,6 +71,7 @@ import org.opendaylight.protocol.pcep.spi.LabelRegistry;
 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.VendorInformationObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.VendorInformationTlvRegistry;
 import org.opendaylight.protocol.pcep.spi.pojo.AbstractPCEPExtensionProviderActivator;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Close;
@@ -128,6 +129,7 @@ public final class Activator extends AbstractPCEPExtensionProviderActivator {
         registerObjectParsers(regs, context);
 
         final ObjectRegistry objReg = context.getObjectHandlerRegistry();
+        final VendorInformationObjectRegistry viObjReg = context.getVendorInformationObjectRegistry();
         final PCEPOpenMessageParser openParser = new PCEPOpenMessageParser(objReg);
         regs.add(context.registerMessageParser(PCEPOpenMessageParser.TYPE, openParser));
         regs.add(context.registerMessageSerializer(
@@ -138,11 +140,11 @@ public final class Activator extends AbstractPCEPExtensionProviderActivator {
         regs.add(context.registerMessageParser(PCEPKeepAliveMessageParser.TYPE, kaParser));
         regs.add(context.registerMessageSerializer(Keepalive.class, kaParser));
 
-        final PCEPRequestMessageParser reqParser = new PCEPRequestMessageParser(objReg);
+        final PCEPRequestMessageParser reqParser = new PCEPRequestMessageParser(objReg, viObjReg);
         regs.add(context.registerMessageParser(PCEPRequestMessageParser.TYPE, reqParser));
         regs.add(context.registerMessageSerializer(Pcreq.class, reqParser));
 
-        final PCEPReplyMessageParser repParser = new PCEPReplyMessageParser(objReg);
+        final PCEPReplyMessageParser repParser = new PCEPReplyMessageParser(objReg, viObjReg);
         regs.add(context.registerMessageParser(PCEPReplyMessageParser.TYPE, repParser));
         regs.add(context.registerMessageSerializer(Pcrep.class, repParser));
 
index 509179209401724cff379af5f96fa6fe72a06099..93a7fb029193c40d2fa54603ed481657f9b65483 100644 (file)
@@ -17,6 +17,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.VendorInformationObjectRegistry;
 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.message.rev131007.PcrepBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
@@ -42,6 +43,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.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.vendor.information.objects.VendorInformationObject;
 
 /**
  * Parser for {@link Pcrep}
@@ -50,8 +52,8 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
 
     public static final int TYPE = 4;
 
-    public PCEPReplyMessageParser(final ObjectRegistry registry) {
-        super(registry);
+    public PCEPReplyMessageParser(final ObjectRegistry registry, final VendorInformationObjectRegistry viRegistry) {
+        super(registry, viRegistry);
     }
 
     @Override
@@ -73,6 +75,7 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
 
     protected void serializeReply(final Replies reply, final ByteBuf buffer) {
         serializeObject(reply.getRp(), buffer);
+        serializeVendorInformationObjects(reply.getVendorInformationObject(), buffer);
         if (reply.getResult() != null) {
             if (reply.getResult() instanceof FailureCase) {
                 final FailureCase f = ((FailureCase) reply.getResult());
@@ -113,6 +116,7 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
                         serializeObject(p.getIro(), buffer);
                     }
                 }
+                serializeVendorInformationObjects(s.getSuccess().getVendorInformationObject(), buffer);
             }
         }
     }
@@ -145,6 +149,7 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
         }
         final Rp rp = (Rp) objects.get(0);
         objects.remove(0);
+        final List<VendorInformationObject> vendorInfo = addVendorInformationObjects(objects);
         Result res = null;
         if (!objects.isEmpty()) {
             if (objects.get(0) instanceof NoPath) {
@@ -164,6 +169,10 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
                 final PathsBuilder pBuilder = new PathsBuilder();
                 pBuilder.setEro(ero);
                 while (!objects.isEmpty()) {
+                    final List<VendorInformationObject> vendorInfoObjects = addVendorInformationObjects(objects);
+                    if (!vendorInfoObjects.isEmpty()) {
+                        builder.setVendorInformationObject(vendorInfoObjects);
+                    }
                     this.parsePath(pBuilder, objects);
                     paths.add(pBuilder.build());
                 }
@@ -171,7 +180,11 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
                 res = new SuccessCaseBuilder().setSuccess(builder.build()).build();
             }
         }
-        return new RepliesBuilder().setRp(rp).setResult(res).build();
+        final RepliesBuilder builder = new RepliesBuilder();
+        if (!vendorInfo.isEmpty()) {
+            builder.setVendorInformationObject(vendorInfo);
+        }
+        return builder.setRp(rp).setResult(res).build();
     }
 
     protected void parseAttributes(final FailureCaseBuilder builder, final List<Object> objects) {
@@ -218,7 +231,9 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
                 objects.remove(0);
             }
         }
-        builder.setMetrics(pathMetrics);
+        if (!pathMetrics.isEmpty()) {
+            builder.setMetrics(pathMetrics);
+        }
     }
 
     protected void parsePath(final PathsBuilder builder, final List<Object> objects) {
@@ -271,7 +286,9 @@ public class PCEPReplyMessageParser extends AbstractMessageParser {
                 objects.remove(0);
             }
         }
-        builder.setMetrics(pathMetrics);
+        if (!pathMetrics.isEmpty()) {
+            builder.setMetrics(pathMetrics);
+        }
     }
 
     private enum State {
index 924cffc81dd1d992fd0f010a8b067dce3f79dfc1..2572cb3ef26995e0359c5071c83df13585887204 100644 (file)
@@ -17,6 +17,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.VendorInformationObjectRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcreq;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcreqBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
@@ -49,6 +50,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.pcreq.message.pcreq.message.requests.segment.computation.p2p.ReportedRouteBuilder;
 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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.objects.VendorInformationObject;
 
 /**
  * Parser for {@link Pcreq}
@@ -57,8 +59,8 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
 
     public static final int TYPE = 3;
 
-    public PCEPRequestMessageParser(final ObjectRegistry registry) {
-        super(registry);
+    public PCEPRequestMessageParser(final ObjectRegistry registry, final VendorInformationObjectRegistry viRegistry) {
+        super(registry, viRegistry);
     }
 
     @Override
@@ -71,6 +73,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         final ByteBuf buffer = Unpooled.buffer();
         for (final Requests req : msg.getRequests()) {
             serializeObject(req.getRp(), buffer);
+            serializeVendorInformationObjects(req.getVendorInformationObject(), buffer);
             if (req.getPathKeyExpansion() != null) {
                 serializeObject(req.getPathKeyExpansion().getPathKey(), buffer);
             }
@@ -98,6 +101,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
                         serializeObject(m.getMetric(), buffer);
                     }
                 }
+                serializeVendorInformationObjects(s.getVendorInformationObject(), buffer);
             }
         }
         MessageUtil.formatMessage(TYPE, buffer, out);
@@ -107,6 +111,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         if (p2p.getEndpointsObj() != null) {
             serializeObject(p2p.getEndpointsObj(), buffer);
         }
+        serializeVendorInformationObjects(p2p.getVendorInformationObject(), buffer);
         if (p2p.getReportedRoute() != null) {
             final ReportedRoute rr = p2p.getReportedRoute();
             if (rr.getRro() != null) {
@@ -173,7 +178,10 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
                 errors.add(createErrorMsg(PCEPErrors.RP_MISSING));
                 return null;
             }
-
+            final List<VendorInformationObject> vendorInfo = addVendorInformationObjects(objects);
+            if (!vendorInfo.isEmpty()) {
+                rBuilder.setVendorInformationObject(vendorInfo);
+            }
             // expansion
             if (rpObj.isPathKey()) {
                 if (objects.get(0) instanceof PathKey) {
@@ -225,6 +233,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
     protected SegmentComputation getSegmentComputation(final P2pBuilder builder, final List<Object> objects, final List<Message> errors,
             final Rp rp) {
         final List<Metrics> metrics = Lists.newArrayList();
+        final List<VendorInformationObject> viObjects = Lists.newArrayList();
 
         State state = State.Init;
         while (!objects.isEmpty() && state != State.End) {
@@ -244,6 +253,13 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
                     break;
                 }
             case ReportedIn:
+                state = State.VendorInfoList;
+                if (obj instanceof VendorInformationObject) {
+                    viObjects.add((VendorInformationObject) obj);
+                    state = State.ReportedIn;
+                    break;
+                }
+            case VendorInfoList:
                 state = State.LoadBIn;
                 if (obj instanceof LoadBalancing) {
                     builder.setLoadBalancing((LoadBalancing) obj);
@@ -316,6 +332,9 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         if (!metrics.isEmpty()) {
             builder.setMetrics(metrics);
         }
+        if (!viObjects.isEmpty()) {
+            builder.setVendorInformationObject(viObjects);
+        }
 
         if (rp.isReoptimization()
                 && builder.getBandwidth() != null
@@ -329,7 +348,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
     }
 
     private enum State {
-        Init, ReportedIn, LoadBIn, LspaIn, BandwidthIn, MetricIn, IroIn, RroIn, XroIn, OfIn, CtIn, End
+        Init, ReportedIn, VendorInfoList, LoadBIn, LspaIn, BandwidthIn, MetricIn, IroIn, RroIn, XroIn, OfIn, CtIn, End
     }
 
     private Svec getValidSvec(final SvecBuilder builder, final List<Object> objects) {
@@ -345,6 +364,7 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
         }
 
         final List<Metrics> metrics = Lists.newArrayList();
+        final List<VendorInformationObject> viObjects = Lists.newArrayList();
 
         Object obj = null;
         SvecState state = SvecState.Init;
@@ -378,6 +398,13 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
                     break;
                 }
             case MetricIn:
+                state = SvecState.VendorInfo;
+                if (obj instanceof VendorInformationObject) {
+                    viObjects.add((VendorInformationObject) obj);
+                    state = SvecState.MetricIn;
+                    break;
+                }
+            case VendorInfo:
                 state = SvecState.End;
                 break;
             case End:
@@ -387,10 +414,13 @@ public class PCEPRequestMessageParser extends AbstractMessageParser {
                 objects.remove(0);
             }
         }
+        if (!viObjects.isEmpty()) {
+            builder.setVendorInformationObject(viObjects);
+        }
         return builder.build();
     }
 
     private enum SvecState {
-        Init, OfIn, GcIn, XroIn, MetricIn, End
+        Init, OfIn, GcIn, XroIn, MetricIn, VendorInfo, End
     }
 }
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/object/AbstractVendorInformationObjectParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/object/AbstractVendorInformationObjectParser.java
new file mode 100644 (file)
index 0000000..b1414c9
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.impl.object;
+
+import static org.opendaylight.protocol.pcep.spi.VendorInformationUtil.VENDOR_INFORMATION_OBJECT_CLASS;
+import static org.opendaylight.protocol.pcep.spi.VendorInformationUtil.VENDOR_INFORMATION_OBJECT_TYPE;
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedInt;
+
+import com.google.common.base.Preconditions;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+
+import org.opendaylight.protocol.pcep.spi.EnterpriseSpecificInformationParser;
+import org.opendaylight.protocol.pcep.spi.ObjectParser;
+import org.opendaylight.protocol.pcep.spi.ObjectSerializer;
+import org.opendaylight.protocol.pcep.spi.ObjectUtil;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.iana.rev130816.EnterpriseNumber;
+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.ObjectHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.objects.VendorInformationObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.objects.VendorInformationObjectBuilder;
+
+public abstract class AbstractVendorInformationObjectParser implements ObjectSerializer, ObjectParser, EnterpriseSpecificInformationParser {
+
+    @Override
+    public final Object parseObject(final ObjectHeader header, final ByteBuf buffer) throws PCEPDeserializerException {
+        Preconditions.checkArgument(buffer != null && buffer.isReadable(), "Array of bytes is mandatory. Can't be null or empty.");
+        final VendorInformationObjectBuilder builder = new VendorInformationObjectBuilder();
+        buffer.readUnsignedInt();
+        builder.setEnterpriseNumber(new EnterpriseNumber(getEnterpriseNumber()));
+        builder.setEnterpriseSpecificInformation(parseEnterpriseSpecificInformation(buffer));
+        return builder.build();
+    }
+
+    @Override
+    public final void serializeObject(final Object object, final ByteBuf buffer) {
+        Preconditions.checkArgument(object instanceof VendorInformationObject, "Wrong instance of PCEPObject. Passed %s. Needed VendorInformationObject.", object.getClass());
+        final ByteBuf body = Unpooled.buffer();
+        writeUnsignedInt(getEnterpriseNumber().getValue(), body);
+        serializeEnterpriseSpecificInformation(((VendorInformationObject) object).getEnterpriseSpecificInformation(), body);
+        ObjectUtil.formatSubobject(VENDOR_INFORMATION_OBJECT_TYPE, VENDOR_INFORMATION_OBJECT_CLASS, object.isProcessingRule(), object.isIgnore(), body, buffer);
+    }
+
+}
index 24aad5e64b751e52ac2cce77b3d19ddd38a184f3..057175f1e7da6bdb91a17118eca8074f16d12389 100644 (file)
@@ -100,6 +100,8 @@ 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.req.missing.tlv.ReqMissingBuilder;
 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.svec.object.SvecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.objects.VendorInformationObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.objects.VendorInformationObjectBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.tlvs.VendorInformationTlv;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.tlvs.VendorInformationTlvBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.AttributeFilter;
@@ -780,4 +782,27 @@ public class PCEPObjectParserTest {
         parser.serializeObject(builder.build(), buf);
         assertArrayEquals(result.array(), ByteArray.getAllBytes(buf));
     }
+
+    @Test
+    public void testVendorInformationObject() throws PCEPDeserializerException {
+        final byte[] viObjBytes = {
+            /* vendor-information object */
+            0x22, 0x10, 0x00, 0x0C,
+            /* enterprise number */
+            0x00, 0x00, 0x00, 0x00,
+            /* enterprise specific information */
+            0x00, 0x00, 0x00, 0x05
+        };
+        final TestVendorInformationObjectParser parser = new TestVendorInformationObjectParser();
+        final TestEnterpriseSpecificInformation esInfo = new TestEnterpriseSpecificInformation(5);
+        final VendorInformationObject viObj = new VendorInformationObjectBuilder().setEnterpriseNumber(new EnterpriseNumber(0L))
+                .setEnterpriseSpecificInformation(esInfo).build();
+        final ByteBuf result = Unpooled.wrappedBuffer(viObjBytes);
+
+        assertEquals(viObj, parser.parseObject(new ObjectHeaderImpl(false, false), result.slice(4, result.readableBytes() - 4)));
+
+        final ByteBuf buf = Unpooled.buffer(viObjBytes.length);
+        parser.serializeObject(viObj, buf);
+        assertArrayEquals(result.array(), ByteArray.getAllBytes(buf));
+    }
 }
index aa8a2066e03a10abb7310632788f806215159df4..264430730207d07ff31b894012cd778082b7ffd9 100644 (file)
@@ -19,6 +19,7 @@ import java.util.Collections;
 import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.protocol.pcep.impl.TestVendorInformationTlvParser.TestEnterpriseSpecificInformation;
 import org.opendaylight.protocol.pcep.impl.message.PCEPCloseMessageParser;
 import org.opendaylight.protocol.pcep.impl.message.PCEPErrorMessageParser;
 import org.opendaylight.protocol.pcep.impl.message.PCEPKeepAliveMessageParser;
@@ -28,9 +29,11 @@ import org.opendaylight.protocol.pcep.impl.message.PCEPReplyMessageParser;
 import org.opendaylight.protocol.pcep.impl.message.PCEPRequestMessageParser;
 import org.opendaylight.protocol.pcep.spi.ObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.VendorInformationObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.pojo.SimplePCEPExtensionProviderContext;
 import org.opendaylight.protocol.util.ByteArray;
 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.iana.rev130816.EnterpriseNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ieee754.rev130819.Float32;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.CloseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.KeepaliveBuilder;
@@ -99,6 +102,8 @@ 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.rp.object.RpBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.svec.object.Svec;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.svec.object.SvecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.objects.VendorInformationObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.objects.VendorInformationObjectBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.AttributeFilter;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.basic.explicit.route.subobjects.subobject.type.AsNumberCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.basic.explicit.route.subobjects.subobject.type.AsNumberCaseBuilder;
@@ -107,6 +112,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev
 public class PCEPValidatorTest {
 
     private ObjectRegistry objectRegistry;
+    private VendorInformationObjectRegistry viObjRegistry;
 
     private Open open;
     private Rp rpTrue;
@@ -119,18 +125,23 @@ public class PCEPValidatorTest {
     private Of of;
     private EndpointsObj endpoints;
     private Svec svec;
+    private List<VendorInformationObject> viObjects;
 
     private AsNumberCase eroASSubobject;
 
     private SimplePCEPExtensionProviderContext ctx;
     private Activator act;
+    private TestVendorInformationActivator viObjAct;
 
     @Before
     public void setUp() throws Exception {
         this.ctx = new SimplePCEPExtensionProviderContext();
         this.act = new Activator();
+        this.viObjAct = new TestVendorInformationActivator();
         this.act.start(this.ctx);
+        this.viObjAct.start(this.ctx);
         this.objectRegistry = this.ctx.getObjectHandlerRegistry();
+        this.viObjRegistry = this.ctx.getVendorInformationObjectRegistry();
         final RpBuilder rpBuilder = new RpBuilder();
         rpBuilder.setProcessingRule(true);
         rpBuilder.setIgnore(false);
@@ -236,6 +247,12 @@ public class PCEPValidatorTest {
         sBuilder.setSrlgDiverse(false);
         sBuilder.setRequestsIds(Lists.newArrayList(new RequestId(1L)));
         this.svec = sBuilder.build();
+
+        this.viObjects = Lists.newArrayList();
+        final TestEnterpriseSpecificInformation esInfo = new TestEnterpriseSpecificInformation(5);
+        final VendorInformationObject viObj = new VendorInformationObjectBuilder().setEnterpriseNumber(new EnterpriseNumber(0L))
+                .setEnterpriseSpecificInformation(esInfo).build();
+        this.viObjects.add(viObj);
     }
 
     @Test
@@ -291,7 +308,7 @@ public class PCEPValidatorTest {
     public void testRequestMsg() throws IOException, PCEPDeserializerException {
         ByteBuf result = Unpooled.wrappedBuffer(ByteArray.fileToBytes("src/test/resources/PCEPRequestMessage1.bin"));
 
-        final PCEPRequestMessageParser parser = new PCEPRequestMessageParser(this.objectRegistry);
+        final PCEPRequestMessageParser parser = new PCEPRequestMessageParser(this.objectRegistry, this.viObjRegistry);
 
         final PcreqMessageBuilder builder = new PcreqMessageBuilder();
         final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcreq.message.pcreq.message.Requests> reqs1 = Lists.newArrayList();
@@ -335,7 +352,7 @@ public class PCEPValidatorTest {
         // only RP
         ByteBuf result = Unpooled.wrappedBuffer(ByteArray.fileToBytes("src/test/resources/PCRep.1.bin"));
 
-        final PCEPReplyMessageParser parser = new PCEPReplyMessageParser(this.objectRegistry);
+        final PCEPReplyMessageParser parser = new PCEPReplyMessageParser(this.objectRegistry, this.viObjRegistry);
 
         final PcrepMessageBuilder builder = new PcrepMessageBuilder();
         RepliesBuilder rBuilder = new RepliesBuilder();
@@ -495,4 +512,56 @@ public class PCEPValidatorTest {
         parser.serializeMessage(new PcerrBuilder().setPcerrMessage(builder.build()).build(), buf);
         assertArrayEquals(result.array(), buf.array());
     }
+
+    @Test
+    public void testReqMsgWithVendorInfoObjects() throws IOException, PCEPDeserializerException {
+        final ByteBuf result = Unpooled.wrappedBuffer(ByteArray.fileToBytes("src/test/resources/PCReq.7.bin"));
+        final PCEPRequestMessageParser parser = new PCEPRequestMessageParser(this.objectRegistry, this.viObjRegistry);
+
+        final PcreqMessageBuilder builder = new PcreqMessageBuilder();
+        final List<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcreq.message.pcreq.message.Requests> reqs1 = Lists.newArrayList();
+        final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcreq.message.pcreq.message.RequestsBuilder rBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcreq.message.pcreq.message.RequestsBuilder();
+        rBuilder.setRp(this.rpTrue);
+        rBuilder.setVendorInformationObject(this.viObjects);
+        final SegmentComputationBuilder sBuilder = new SegmentComputationBuilder();
+        sBuilder.setP2p(new P2pBuilder().setEndpointsObj(this.endpoints).setVendorInformationObject(this.viObjects).build());
+        rBuilder.setSegmentComputation(sBuilder.build());
+        reqs1.add(rBuilder.build());
+        builder.setSvec(Lists.newArrayList(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcreq.message.pcreq.message.SvecBuilder().setSvec(
+                this.svec).setVendorInformationObject(this.viObjects).build()));
+        builder.setRequests(reqs1);
+
+        assertEquals(new PcreqBuilder().setPcreqMessage(builder.build()).build(), parser.parseMessage(result.slice(4,
+            result.readableBytes() - 4), Collections.<Message> emptyList()));
+        ByteBuf buf = Unpooled.buffer(result.readableBytes());
+        parser.serializeMessage(new PcreqBuilder().setPcreqMessage(builder.build()).build(), buf);
+
+        assertArrayEquals(result.array(), buf.array());
+    }
+
+    @Test
+    public void testRepMsgWithVendorInforObjects() throws IOException, PCEPDeserializerException {
+        final PCEPReplyMessageParser parser = new PCEPReplyMessageParser(this.objectRegistry, this.viObjRegistry);
+
+        final PcrepMessageBuilder builder = new PcrepMessageBuilder();
+        RepliesBuilder rBuilder = new RepliesBuilder();
+        final ByteBuf result = Unpooled.wrappedBuffer(ByteArray.fileToBytes("src/test/resources/PCRep.6.bin"));
+        final List<Replies> replies = Lists.newArrayList();
+        rBuilder = new RepliesBuilder();
+        rBuilder.setRp(this.rpTrue);
+        rBuilder.setVendorInformationObject(this.viObjects);
+        final List<Paths> paths = Lists.newArrayList();
+        final PathsBuilder paBuilder = new PathsBuilder();
+        paBuilder.setEro(this.ero);
+        paths.add(paBuilder.build());
+        rBuilder.setResult(new SuccessCaseBuilder().setSuccess(new SuccessBuilder().setPaths(paths).setVendorInformationObject(this.viObjects).build()).build()).build();
+        replies.add(rBuilder.build());
+        builder.setReplies(replies);
+
+        assertEquals(new PcrepBuilder().setPcrepMessage(builder.build()).build(), parser.parseMessage(result.slice(4,
+            result.readableBytes() - 4), Collections.<Message> emptyList()));
+        final ByteBuf buf = Unpooled.buffer(result.readableBytes());
+        parser.serializeMessage(new PcrepBuilder().setPcrepMessage(builder.build()).build(), buf);
+        assertArrayEquals(result.array(), buf.array());
+    }
 }
index 19e5a2cf7474f91a0ce5e366d9034afa8f47032c..626d7b59a244a982251a9562fda146847d79aedd 100644 (file)
@@ -22,6 +22,11 @@ public class TestVendorInformationActivator extends AbstractPCEPExtensionProvide
         final TestVendorInformationTlvParser parser = new TestVendorInformationTlvParser();
         regs.add(context.registerVendorInformationTlvParser(parser.getEnterpriseNumber(), parser));
         regs.add(context.registerVendorInformationTlvSerializer(TestEnterpriseSpecificInformation.class, parser));
+
+        // Vendor-information object registration
+        final TestVendorInformationObjectParser objParser = new TestVendorInformationObjectParser();
+        regs.add(context.registerVendorInformationObjectParser(parser.getEnterpriseNumber(), objParser));
+        regs.add(context.registerVendorInformationObjectSerializer(TestEnterpriseSpecificInformation.class, objParser));
         return regs;
     }
 
diff --git a/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/TestVendorInformationObjectParser.java b/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/TestVendorInformationObjectParser.java
new file mode 100644 (file)
index 0000000..a9dbc53
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.impl;
+
+import io.netty.buffer.ByteBuf;
+
+import org.opendaylight.protocol.pcep.impl.TestVendorInformationTlvParser.TestEnterpriseSpecificInformation;
+import org.opendaylight.protocol.pcep.impl.object.AbstractVendorInformationObjectParser;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.iana.rev130816.EnterpriseNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.EnterpriseSpecificInformation;
+
+public class TestVendorInformationObjectParser extends AbstractVendorInformationObjectParser {
+
+    private static final EnterpriseNumber TEST_ENTERPRISE_NUMBER = new EnterpriseNumber(0L);
+
+    @Override
+    public void serializeEnterpriseSpecificInformation(final EnterpriseSpecificInformation enterpriseSpecificInformation,
+            final ByteBuf buffer) {
+        buffer.writeInt(((TestEnterpriseSpecificInformation) enterpriseSpecificInformation).getValue());
+    }
+
+    @Override
+    public EnterpriseSpecificInformation parseEnterpriseSpecificInformation(final ByteBuf buffer)
+            throws PCEPDeserializerException {
+        return new TestEnterpriseSpecificInformation(buffer.readInt());
+    }
+
+    @Override
+    public EnterpriseNumber getEnterpriseNumber() {
+        return TEST_ENTERPRISE_NUMBER;
+    }
+
+}
diff --git a/pcep/impl/src/test/resources/PCRep.6.bin b/pcep/impl/src/test/resources/PCRep.6.bin
new file mode 100644 (file)
index 0000000..3af4493
Binary files /dev/null and b/pcep/impl/src/test/resources/PCRep.6.bin differ
diff --git a/pcep/impl/src/test/resources/PCReq.7.bin b/pcep/impl/src/test/resources/PCReq.7.bin
new file mode 100644 (file)
index 0000000..c8efd0f
Binary files /dev/null and b/pcep/impl/src/test/resources/PCReq.7.bin differ
index f4bcedbf903ce8cae249b912d247d74549ff824f..37f465586fd0c900fd303292ea4afb5a6904081c 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.protocol.pcep.lsp.setup.type01.PcepRpObjectWithPstTlvPar
 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.VendorInformationObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.VendorInformationTlvRegistry;
 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;
@@ -62,13 +63,14 @@ public class SegmentRoutingActivator extends AbstractPCEPExtensionProviderActiva
 
         /* Messages */
         final ObjectRegistry objRegistry = context.getObjectHandlerRegistry();
-        regs.add(context.registerMessageParser(SrPcRepMessageParser.TYPE, new SrPcRepMessageParser(objRegistry)));
+        final VendorInformationObjectRegistry objReg = context.getVendorInformationObjectRegistry();
+        regs.add(context.registerMessageParser(SrPcRepMessageParser.TYPE, new SrPcRepMessageParser(objRegistry, objReg)));
         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(Pcrep.class, new SrPcRepMessageParser(objRegistry, objReg)));
         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)));
index 864e838c2b6e5bbe4e6933446fab789dbf98a4e7..29db7de09e9ef6fc87c17906163ab830a965ddc5 100644 (file)
@@ -14,6 +14,7 @@ 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.protocol.pcep.spi.VendorInformationObjectRegistry;
 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;
@@ -31,8 +32,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 
 public class SrPcRepMessageParser extends PCEPReplyMessageParser {
 
-    public SrPcRepMessageParser(ObjectRegistry registry) {
-        super(registry);
+    public SrPcRepMessageParser(final ObjectRegistry registry, final VendorInformationObjectRegistry viRegistry) {
+        super(registry, viRegistry);
     }
 
     @Override
index 81eaae38de3c0b1cb680e03f40b1de67b58a6f39..3c37dacd11022ead6c5bdf4a8f6376bca8a75b17 100644 (file)
@@ -24,6 +24,7 @@ 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.VendorInformationObjectRegistry;
 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;
@@ -85,6 +86,7 @@ public class SrMessageParserTest {
     private Activator activator;
     private StatefulActivator statefulActivator;
     private ObjectRegistry objectRegistry;
+    private VendorInformationObjectRegistry viObjReg;
 
     @Before
     public void setup() {
@@ -96,6 +98,7 @@ public class SrMessageParserTest {
         this.srActivator = new SegmentRoutingActivator();
         this.srActivator.start(this.ctx);
         this.objectRegistry = this.ctx.getObjectHandlerRegistry();
+        this.viObjReg = this.ctx.getVendorInformationObjectRegistry();
     }
 
     @Test
@@ -116,7 +119,7 @@ public class SrMessageParserTest {
             0x00,0x01,(byte) 0xe2,0x40,
             0x4A,0x7D,0x2b,0x63};
 
-        final SrPcRepMessageParser parser = new SrPcRepMessageParser(this.objectRegistry);
+        final SrPcRepMessageParser parser = new SrPcRepMessageParser(this.objectRegistry, this.viObjReg);
 
         final PcrepMessageBuilder builder = new PcrepMessageBuilder();
         final RepliesBuilder rBuilder = new RepliesBuilder();
index 4b1907a2e06a911873709bc8fff00c83dd5da31e..1ae5cd57e1bedcd7093ff61a528241ac61acf489 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.protocol.pcep.spi;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.primitives.UnsignedBytes;
@@ -19,6 +20,7 @@ import java.util.BitSet;
 import java.util.List;
 
 import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.iana.rev130816.EnterpriseNumber;
 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.types.rev131005.Message;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object;
@@ -30,6 +32,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.pcerr.message.pcerr.message.error.type.request._case.RequestBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.pcerr.message.error.type.request._case.request.RpsBuilder;
 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.vendor.information.objects.VendorInformationObject;
 
 public abstract class AbstractMessageParser implements MessageParser, MessageSerializer {
 
@@ -49,9 +52,16 @@ public abstract class AbstractMessageParser implements MessageParser, MessageSer
     private static final int I_FLAG_OFFSET = 7;
 
     private final ObjectRegistry registry;
+    private final VendorInformationObjectRegistry viRegistry;
 
     protected AbstractMessageParser(final ObjectRegistry registry) {
         this.registry = Preconditions.checkNotNull(registry);
+        this.viRegistry = null;
+    }
+
+    protected AbstractMessageParser(final ObjectRegistry registry, final VendorInformationObjectRegistry viRegistry) {
+        this.registry = Preconditions.checkNotNull(registry);
+        this.viRegistry = Preconditions.checkNotNull(viRegistry);
     }
 
     protected void serializeObject(final Object object, final ByteBuf buffer) {
@@ -86,11 +96,21 @@ public abstract class AbstractMessageParser implements MessageParser, MessageSer
 
             final ObjectHeader header = new ObjectHeaderImpl(flags.get(P_FLAG_OFFSET), flags.get(I_FLAG_OFFSET));
 
-            // parseObject is required to return null for P=0 errored objects
-            final Object o = this.registry.parseObject(objClass, objType, header, bytesToPass);
-            if (o != null) {
-                objs.add(o);
+            if (VendorInformationUtil.isVendorInformationObject(objClass, objType)) {
+                Preconditions.checkState(this.viRegistry != null);
+                final EnterpriseNumber enterpriseNumber = new EnterpriseNumber(bytes.getUnsignedInt(bytes.readerIndex()));
+                final Optional<? extends Object> obj = this.viRegistry.parseVendorInformationObject(enterpriseNumber, header, bytesToPass);
+                if (obj.isPresent()) {
+                    objs.add(obj.get());
+                }
+            } else {
+                // parseObject is required to return null for P=0 errored objects
+                final Object o = this.registry.parseObject(objClass, objType, header, bytesToPass);
+                if (o != null) {
+                    objs.add(o);
+                }
             }
+
             bytes.readerIndex(bytes.readerIndex() + objLength - COMMON_OBJECT_HEADER_LENGTH);
         }
 
@@ -129,4 +149,22 @@ public abstract class AbstractMessageParser implements MessageParser, MessageSer
         // Run validation
         return validate(objs, errors);
     }
+
+    protected final void serializeVendorInformationObjects(final List<VendorInformationObject> viObjects, final ByteBuf buffer) {
+        if (viObjects != null && !viObjects.isEmpty()) {
+            for (final VendorInformationObject viObject : viObjects) {
+                this.viRegistry.serializeVendorInformationObject(viObject, buffer);
+            }
+        }
+    }
+
+    protected final List<VendorInformationObject> addVendorInformationObjects(final List<Object> objects) {
+        final List<VendorInformationObject> vendorInfo = Lists.newArrayList();
+        while (!objects.isEmpty() && objects.get(0) instanceof VendorInformationObject) {
+            final VendorInformationObject viObject = (VendorInformationObject) objects.get(0);
+            vendorInfo.add(viObject);
+            objects.remove(0);
+        }
+        return vendorInfo;
+    }
 }
index 57916753ab23aedf3f525dd24cdd9240ef6daee3..cd1255dffbf383f51732aae890710e1f76d3cae1 100644 (file)
@@ -24,4 +24,6 @@ public interface PCEPExtensionConsumerContext {
     TlvRegistry getTlvHandlerRegistry();
 
     VendorInformationTlvRegistry getVendorInformationTlvRegistry();
+
+    VendorInformationObjectRegistry getVendorInformationObjectRegistry();
 }
index 9dfeb1842127f7eb3d7ae39ffe2477151ce6d190..38ab66e6b590e8c83aae107374384fa445c56df7 100644 (file)
@@ -49,4 +49,8 @@ public interface PCEPExtensionProviderContext extends PCEPExtensionConsumerConte
     AutoCloseable registerXROSubobjectSerializer(Class<? extends SubobjectType> subobjectClass, XROSubobjectSerializer serializer);
 
     AutoCloseable registerXROSubobjectParser(int subobjectType, XROSubobjectParser parser);
+
+    AutoCloseable registerVendorInformationObjectSerializer(Class<? extends EnterpriseSpecificInformation> esInformationClass, ObjectSerializer serializer);
+
+    AutoCloseable registerVendorInformationObjectParser(EnterpriseNumber enterpriseNumber, ObjectParser parser);
 }
diff --git a/pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/VendorInformationObjectRegistry.java b/pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/VendorInformationObjectRegistry.java
new file mode 100644 (file)
index 0000000..1fe9a9f
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.spi;
+
+import com.google.common.base.Optional;
+
+import io.netty.buffer.ByteBuf;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.iana.rev130816.EnterpriseNumber;
+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.ObjectHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.objects.VendorInformationObject;
+
+public interface VendorInformationObjectRegistry {
+
+    Optional<? extends Object> parseVendorInformationObject(final EnterpriseNumber enterpriseNumber, final ObjectHeader header, final ByteBuf buffer) throws PCEPDeserializerException;
+
+    void serializeVendorInformationObject(final VendorInformationObject viObject, final ByteBuf buffer);
+
+}
index 873e3dc57809a934d4bba801bebf13f08fbf7f4a..d638fa98705189ea1e3e9d5ceff5177a0a6b1e5b 100644 (file)
@@ -12,10 +12,18 @@ public class VendorInformationUtil {
 
     public static final int VENDOR_INFORMATION_TLV_TYPE = 7;
 
+    public static final int VENDOR_INFORMATION_OBJECT_CLASS = 34;
+
+    public static final int VENDOR_INFORMATION_OBJECT_TYPE = 1;
+
     private VendorInformationUtil() {
     }
 
     public static boolean isVendorInformationTlv(final int type) {
         return type == VENDOR_INFORMATION_TLV_TYPE;
     }
+
+    public static boolean isVendorInformationObject(final int objectClass, final int objectType) {
+        return objectType == VENDOR_INFORMATION_OBJECT_TYPE && objectClass == VENDOR_INFORMATION_OBJECT_CLASS;
+    }
 }
index 024ae2fea76d448ae9048bdecbe5dde230c6dd60..2134d4f446f27159946b43714cb6e3fdd5a4e2ef 100644 (file)
@@ -28,6 +28,7 @@ import org.opendaylight.protocol.pcep.spi.RROSubobjectSerializer;
 import org.opendaylight.protocol.pcep.spi.TlvParser;
 import org.opendaylight.protocol.pcep.spi.TlvRegistry;
 import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.pcep.spi.VendorInformationObjectRegistry;
 import org.opendaylight.protocol.pcep.spi.VendorInformationTlvRegistry;
 import org.opendaylight.protocol.pcep.spi.XROSubobjectParser;
 import org.opendaylight.protocol.pcep.spi.XROSubobjectRegistry;
@@ -53,6 +54,7 @@ public class SimplePCEPExtensionProviderContext implements PCEPExtensionProvider
     private final SimpleXROSubobjectRegistry xroSubReg = new SimpleXROSubobjectRegistry();
     private final SimpleTlvRegistry tlvReg = new SimpleTlvRegistry();
     private final SimpleVendorInformationTlvRegistry viTlvReg = new SimpleVendorInformationTlvRegistry();
+    private final SimpleVendorInformationObjectRegistry viObjReg = new SimpleVendorInformationObjectRegistry();
 
     @Override
     public final LabelRegistry getLabelHandlerRegistry() {
@@ -178,4 +180,20 @@ public class SimplePCEPExtensionProviderContext implements PCEPExtensionProvider
     public AutoCloseable registerVendorInformationTlvParser(final EnterpriseNumber enterpriseNumber, final TlvParser parser) {
         return this.viTlvReg.registerVendorInformationTlvParser(enterpriseNumber, parser);
     }
+
+    @Override
+    public AutoCloseable registerVendorInformationObjectSerializer(
+            final Class<? extends EnterpriseSpecificInformation> esInformationClass, final ObjectSerializer serializer) {
+        return this.viObjReg.registerVendorInformationObjectSerializer(esInformationClass, serializer);
+    }
+
+    @Override
+    public AutoCloseable registerVendorInformationObjectParser(final EnterpriseNumber enterpriseNumber, final ObjectParser parser) {
+        return this.viObjReg.registerVendorInformationObjectParser(enterpriseNumber, parser);
+    }
+
+    @Override
+    public VendorInformationObjectRegistry getVendorInformationObjectRegistry() {
+        return this.viObjReg;
+    }
 }
diff --git a/pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/pojo/SimpleVendorInformationObjectRegistry.java b/pcep/spi/src/main/java/org/opendaylight/protocol/pcep/spi/pojo/SimpleVendorInformationObjectRegistry.java
new file mode 100644 (file)
index 0000000..f663325
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.spi.pojo;
+
+import com.google.common.base.Optional;
+import com.google.common.primitives.Ints;
+
+import io.netty.buffer.ByteBuf;
+
+import org.opendaylight.protocol.concepts.HandlerRegistry;
+import org.opendaylight.protocol.pcep.spi.ObjectParser;
+import org.opendaylight.protocol.pcep.spi.ObjectSerializer;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.protocol.pcep.spi.UnknownObject;
+import org.opendaylight.protocol.pcep.spi.VendorInformationObjectRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.iana.rev130816.EnterpriseNumber;
+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.ObjectHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.EnterpriseSpecificInformation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.objects.VendorInformationObject;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+public class SimpleVendorInformationObjectRegistry implements VendorInformationObjectRegistry {
+
+    private final HandlerRegistry<DataContainer, ObjectParser, ObjectSerializer> handlers = new HandlerRegistry<>();
+
+    public AutoCloseable registerVendorInformationObjectParser(final EnterpriseNumber enterpriseNumber, final ObjectParser parser) {
+        return this.handlers.registerParser(Ints.checkedCast(enterpriseNumber.getValue()), parser);
+    }
+
+    public AutoCloseable registerVendorInformationObjectSerializer(final Class<? extends EnterpriseSpecificInformation> esInformationClass, final ObjectSerializer serializer) {
+        return this.handlers.registerSerializer(esInformationClass, serializer);
+    }
+
+    @Override
+    public Optional<? extends Object> parseVendorInformationObject(final EnterpriseNumber enterpriseNumber, final ObjectHeader header, final ByteBuf buffer)
+            throws PCEPDeserializerException {
+        final ObjectParser parser = this.handlers.getParser(Ints.checkedCast(enterpriseNumber.getValue()));
+        if (parser == null) {
+            if (!header.isProcessingRule()) {
+                return Optional.absent();
+            }
+            return Optional.of(new UnknownObject(PCEPErrors.UNRECOGNIZED_OBJ_CLASS));
+        }
+        return Optional.of(parser.parseObject(header, buffer));
+    }
+
+    @Override
+    public void serializeVendorInformationObject(final VendorInformationObject viObject, final ByteBuf buffer) {
+        final ObjectSerializer serializer = this.handlers.getSerializer(viObject.getEnterpriseSpecificInformation().getImplementedInterface());
+        if (serializer == null) {
+            return;
+        }
+        serializer.serializeObject(viObject, buffer);
+    }
+
+}
index f285efcaef28c9c36923944d60a60942c5f52b7f..db37a86affd0199f69c245682821b5113395b592 100644 (file)
@@ -8,6 +8,8 @@
 package org.opendaylight.protocol.pcep.spi;
 
 import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
@@ -107,4 +109,15 @@ public class UtilsTest {
         EROSubobjectUtil.formatSubobject(2, false, body, out);
         assertArrayEquals(expected, ByteArray.getAllBytes(out));
     }
+
+    @Test
+    public void testVendorInformationUtil() {
+        assertTrue(VendorInformationUtil.isVendorInformationTlv(VendorInformationUtil.VENDOR_INFORMATION_TLV_TYPE));
+        assertFalse(VendorInformationUtil.isVendorInformationTlv(VendorInformationUtil.VENDOR_INFORMATION_OBJECT_CLASS));
+
+        assertTrue(VendorInformationUtil.isVendorInformationObject(VendorInformationUtil.VENDOR_INFORMATION_OBJECT_CLASS, VendorInformationUtil.VENDOR_INFORMATION_OBJECT_TYPE));
+        assertFalse(VendorInformationUtil.isVendorInformationObject(VendorInformationUtil.VENDOR_INFORMATION_OBJECT_CLASS, VendorInformationUtil.VENDOR_INFORMATION_TLV_TYPE));
+        assertFalse(VendorInformationUtil.isVendorInformationObject(VendorInformationUtil.VENDOR_INFORMATION_TLV_TYPE, VendorInformationUtil.VENDOR_INFORMATION_OBJECT_TYPE));
+        assertFalse(VendorInformationUtil.isVendorInformationObject(VendorInformationUtil.VENDOR_INFORMATION_OBJECT_TYPE, VendorInformationUtil.VENDOR_INFORMATION_OBJECT_CLASS));
+    }
 }