BUG 2230: LSP TE 62/25462/20
authorClaudio D. Gasparini <cgaspari@cisco.com>
Thu, 20 Aug 2015 09:31:22 +0000 (11:31 +0200)
committerClaudio D. Gasparini <cgaspari@cisco.com>
Tue, 22 Sep 2015 15:03:10 +0000 (17:03 +0200)
Extented BGP Linkstate to support LSP State TLV,
which is carried in the optional non-transitive
BGP Attribute "LINK_STATE Attribute"

-ref.: http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03

Change-Id: Ifad8364c9c230ba75ae57a0d0442e7599d6244c3
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
16 files changed:
bgp/controller-config/src/main/resources/initial/31-bgp.xml
bgp/linkstate/pom.xml
bgp/linkstate/src/main/java/org/opendaylight/controller/config/yang/bgp/linkstate/LinkstateModule.java
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/BGPActivator.java
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/LinkstateAttributeParser.java
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/TeLspAttributesParser.java [new file with mode: 0644]
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/nlri/LinkstateNlriParser.java
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/nlri/TeLspNlriParser.java [new file with mode: 0644]
bgp/linkstate/src/main/yang/bgp-linkstate.yang
bgp/linkstate/src/main/yang/odl-bgp-linkstate-cfg.yang
bgp/linkstate/src/test/java/org/opendaylight/controller/config/yang/bgp/linkstate/LinkstateModuleTest.java
bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/ActivatorTest.java
bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAttributeParserTest.java
bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateNlriParserTest.java
features/bgp/pom.xml
features/bgp/src/main/features/features.xml

index 38097207e1716cf62a65e69c95825ae08651d9c4..9bc2b1476fd71dc961982844c66ade8e0bc01d0c 100644 (file)
     <required-capabilities>
         <capability>urn:opendaylight:params:xml:ns:yang:bgp-linkstate?module=bgp-linkstate&amp;revision=2015-02-10</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:bgp-types?module=bgp-types&amp;revision=2013-09-19</capability>
-        <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:linkstate?module=odl-bgp-linkstate-cfg&amp;revision=2013-11-15</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:linkstate?module=odl-bgp-linkstate-cfg&amp;revision=2015-08-26</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:flowspec?module=odl-bgp-flowspec-cfg&amp;revision=2015-04-23</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:parser:spi?module=odl-bgp-parser-spi-cfg&amp;revision=2013-11-15</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:spi?module=odl-bgp-rib-spi-cfg&amp;revision=2013-11-15</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:bgp:rib:impl?module=odl-bgp-rib-impl-cfg&amp;revision=2013-04-09</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
         <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:rsvp:spi?module=odl-rsvp-parser-spi-cfg&amp;revision=2015-08-26</capability>
     </required-capabilities>
     <configuration>
 
                     <!-- IANA has issued an early allocation for the BGP Linkstate path attribute (=29).
                         To preserve (TYPE = 99) set value bellow to false; to use IANA assigned type set the value to true or remove (true by default)-->
                     <iana-linkstate-attribute-type>true</iana-linkstate-attribute-type>
+                    <!-- RSVP Extensions -->
+                    <rsvp-extensions>
+                        <type xmlns:rsvp-spi="urn:opendaylight:params:xml:ns:yang:controller:rsvp:spi">rsvp-spi:rsvp-extensions</type>
+                        <name>global-rsvp-extensions</name>
+                    </rsvp-extensions>
                 </module>
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:bgp:flowspec">prefix:bgp-flowspec</type>
index f9811919f825641ffd4a9c65352af7a49641868a..6f0fc691792ace114725928a25b7019020a85334 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>concepts</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>rsvp-spi</artifactId>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>bgp-concepts</artifactId>
             <artifactId>bgp-bmp-api</artifactId>
          </dependency>
          <!-- test scope dependencies -->
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>rsvp-impl</artifactId>
+            <scope>test</scope>
+        </dependency>
          <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
index 06a6220af4bb4c47288c0b3ae0b2894a2f334929..30b2dcd023f90392c0f4dbf24a358633d893c64c 100644 (file)
@@ -47,7 +47,8 @@ public final class LinkstateModule extends org.opendaylight.controller.config.ya
     @Override
     public java.lang.AutoCloseable createInstance() {
         final class LinkstateExtension implements AutoCloseable, BGPExtensionProviderActivator, RIBExtensionProviderActivator {
-            private final BGPExtensionProviderActivator bgpact = new BGPActivator(getIanaLinkstateAttributeType());
+            private final BGPExtensionProviderActivator bgpact = new BGPActivator(getIanaLinkstateAttributeType(),
+                getRsvpExtensionsDependency().getRsvpRegistry());
             private final RIBExtensionProviderActivator ribact = new RIBActivator();
 
             @Override
index fc3af906b6ea101fbb0b810e17176daf65df8b42..6b9c17ae9f918efc02308f3aa0b9ef6df9dd7511 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.protocol.bgp.linkstate.attribute.LinkstateAttributeParse
 import org.opendaylight.protocol.bgp.linkstate.nlri.LinkstateNlriParser;
 import org.opendaylight.protocol.bgp.parser.spi.AbstractBGPExtensionProviderActivator;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
+import org.opendaylight.protocol.rsvp.parser.spi.RSVPTeObjectRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Attributes1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily;
@@ -30,13 +31,17 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
 
     private final boolean ianaLinkstateAttributeType;
 
+    private final RSVPTeObjectRegistry rsvpTeObjectRegistry;
+
     public BGPActivator() {
         super();
         this.ianaLinkstateAttributeType = true;
+        rsvpTeObjectRegistry = null;
     }
 
-    public BGPActivator(final boolean ianaLinkstateAttributeType) {
+    public BGPActivator(final boolean ianaLinkstateAttributeType, final RSVPTeObjectRegistry rsvpTeObjectRegistry) {
         super();
+        this.rsvpTeObjectRegistry = rsvpTeObjectRegistry;
         this.ianaLinkstateAttributeType = ianaLinkstateAttributeType;
     }
 
@@ -53,8 +58,8 @@ public final class BGPActivator extends AbstractBGPExtensionProviderActivator {
                 new LinkstateNlriParser(true)));
         regs.add(context.registerNlriSerializer(LinkstateRoutes.class, new LinkstateNlriParser(false)));
 
-        regs.add(context.registerAttributeSerializer(Attributes1.class, new LinkstateAttributeParser(this.ianaLinkstateAttributeType)));
-        final LinkstateAttributeParser linkstateAttributeParser = new LinkstateAttributeParser(this.ianaLinkstateAttributeType);
+        regs.add(context.registerAttributeSerializer(Attributes1.class, new LinkstateAttributeParser(this.ianaLinkstateAttributeType, this.rsvpTeObjectRegistry)));
+        final LinkstateAttributeParser linkstateAttributeParser = new LinkstateAttributeParser(this.ianaLinkstateAttributeType, this.rsvpTeObjectRegistry);
         regs.add(context.registerAttributeParser(linkstateAttributeParser.getType(), linkstateAttributeParser));
 
         return regs;
index 58c9f5f837017d248543e9ba563f0f920c083967..8914998ce69e98c60341a39fb3d67b976d6ebd5a 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeUtil;
+import org.opendaylight.protocol.rsvp.parser.spi.RSVPTeObjectRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Attributes1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Attributes1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.ObjectType;
@@ -23,10 +24,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.NodeCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.LinkStateAttribute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.LinkAttributesCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.PrefixAttributesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.TeLspAttributesCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
@@ -51,8 +54,25 @@ public class LinkstateAttributeParser implements AttributeParser, AttributeSeria
 
     private final int type;
 
-    public LinkstateAttributeParser(final boolean isIanaAssignedType) {
+    private final RSVPTeObjectRegistry rsvpTeObjectRegistry;
+
+    public LinkstateAttributeParser(final boolean isIanaAssignedType, final RSVPTeObjectRegistry rsvpTeObjectRegistry) {
         this.type = (isIanaAssignedType) ? TYPE : LEGACY_TYPE;
+        this.rsvpTeObjectRegistry = rsvpTeObjectRegistry;
+    }
+
+    private static Multimap<Integer, ByteBuf> getAttributesMap(final ByteBuf buffer) {
+        /*
+         * e.g. IS-IS Area Identifier TLV can occur multiple times
+         */
+        final Multimap<Integer, ByteBuf> map = HashMultimap.create();
+        while (buffer.isReadable()) {
+            final int type = buffer.readUnsignedShort();
+            final int length = buffer.readUnsignedShort();
+            final ByteBuf value = buffer.readSlice(length);
+            map.put(type, value);
+        }
+        return map;
     }
 
     public int getType() {
@@ -92,23 +112,17 @@ public class LinkstateAttributeParser implements AttributeParser, AttributeSeria
         return null;
     }
 
-    private static LinkStateAttribute parseLinkState(final ObjectType nlri, final ByteBuf buffer) throws BGPParsingException {
-        /*
-         * e.g. IS-IS Area Identifier TLV can occur multiple times
-         */
-        final Multimap<Integer, ByteBuf> map = HashMultimap.create();
-        while (buffer.isReadable()) {
-            final int type = buffer.readUnsignedShort();
-            final int length = buffer.readUnsignedShort();
-            final ByteBuf value = buffer.readSlice(length);
-            map.put(type, value);
-        }
+    private LinkStateAttribute parseLinkState(final ObjectType nlri, final ByteBuf buffer) throws BGPParsingException {
+
         if (nlri instanceof PrefixCase) {
-            return PrefixAttributesParser.parsePrefixAttributes(map);
+            return PrefixAttributesParser.parsePrefixAttributes(getAttributesMap(buffer));
         } else if (nlri instanceof LinkCase) {
-            return LinkAttributesParser.parseLinkAttributes(map);
+            return LinkAttributesParser.parseLinkAttributes(getAttributesMap(buffer));
         } else if (nlri instanceof NodeCase) {
-            return NodeAttributesParser.parseNodeAttributes(map);
+            return NodeAttributesParser.parseNodeAttributes(getAttributesMap(buffer));
+        } else if (nlri instanceof TeLspCase) {
+            return TeLspAttributesParser.parseTeLspAttributes(this.rsvpTeObjectRegistry, getAttributesMap(buffer)
+                .entries().iterator().next().getValue());
         } else {
             throw new IllegalStateException("Unhandled NLRI type " + nlri);
         }
@@ -117,7 +131,7 @@ public class LinkstateAttributeParser implements AttributeParser, AttributeSeria
     /**
      * Serialize linkstate attributes.
      *
-     * @param attribute DataObject representing LinkstatePathAttribute
+     * @param attribute      DataObject representing LinkstatePathAttribute
      * @param byteAggregator ByteBuf where all serialized data are aggregated
      */
 
@@ -136,6 +150,10 @@ public class LinkstateAttributeParser implements AttributeParser, AttributeSeria
             NodeAttributesParser.serializeNodeAttributes((NodeAttributesCase) linkState, lsBuffer);
         } else if (linkState instanceof PrefixAttributesCase) {
             PrefixAttributesParser.serializePrefixAttributes((PrefixAttributesCase) linkState, lsBuffer);
+        } else if (linkState instanceof TeLspAttributesCase) {
+            TeLspAttributesParser.serializeLspAttributes(this.rsvpTeObjectRegistry, (TeLspAttributesCase) linkState, lsBuffer);
+            byteAggregator.writeBytes(lsBuffer);
+            return;
         }
         AttributeUtil.formatAttribute(AttributeUtil.OPTIONAL, getType(), lsBuffer, byteAggregator);
     }
diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/TeLspAttributesParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/attribute/TeLspAttributesParser.java
new file mode 100644 (file)
index 0000000..d512ef2
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2015 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.bgp.linkstate.attribute;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.rsvp.parser.spi.RSVPParsingException;
+import org.opendaylight.protocol.rsvp.parser.spi.RSVPTeObjectRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.LinkStateAttribute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.TeLspAttributesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.TeLspAttributesCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.te.lsp.attributes._case.TeLspAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.te.lsp.attributes._case.TeLspAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.RsvpTeObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.admin.status.object.AdminStatusObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.association.object.AssociationObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.bandwidth.object.BandwidthObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.bandwidth.object.bandwidth.object.BasicBandwidthObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.bandwidth.object.bandwidth.object.ReoptimizationBandwidthObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.detour.object.DetourObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.detour.object.detour.object.Ipv4DetourObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.detour.object.detour.object.Ipv6DetourObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.exclude.route.object.ExcludeRouteObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.explicit.route.object.ExplicitRouteObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.fast.reroute.object.FastRerouteObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.fast.reroute.object.fast.reroute.object.BasicFastRerouteObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.fast.reroute.object.fast.reroute.object.LegacyFastRerouteObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.flow.spec.object.FlowSpecObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.lsp.attributes.object.LspAttributesObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.lsp.required.attributes.object.LspRequiredAttributesObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.metric.object.MetricObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.primary.path.route.object.PrimaryPathRouteObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.protection.object.ProtectionObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.protection.object.protection.object.BasicProtectionObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.protection.object.protection.object.DynamicControlProtectionObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.record.route.object.RecordRouteObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.secondary.explicit.route.object.SecondaryExplicitRouteObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.secondary.record.route.object.SecondaryRecordRouteObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.session.attribute.object.SessionAttributeObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.session.attribute.object.session.attribute.object.BasicSessionAttributeObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.session.attribute.object.session.attribute.object.SessionAttributeObjectWithResourcesAffinities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.tspec.object.TspecObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class TeLspAttributesParser {
+
+    private static final Logger LOG = LoggerFactory.getLogger(TeLspAttributesParser.class);
+    private static final int MAGIC_NUMBER = 99;  // TODO: TBD BY IANA
+
+    public static LinkStateAttribute parseTeLspAttributes(final RSVPTeObjectRegistry registry, final ByteBuf attributes) throws BGPParsingException {
+
+        TeLspAttributesBuilder builder = new TeLspAttributesBuilder();
+        LOG.trace("Initiated parsing TE LSP Objects.");
+        while (attributes.isReadable()) {
+            final int length = attributes.readUnsignedShort();
+            final int classNum = attributes.readUnsignedByte();
+            final int cType = attributes.readUnsignedByte();
+            final ByteBuf value = attributes.readSlice(length);
+            try {
+                addObject(builder, registry.parseRSPVTe(classNum, cType, value));
+            } catch (RSVPParsingException e) {
+                throw new BGPParsingException(e.getMessage());
+            }
+        }
+        LOG.trace("Finished parsing TE LSP Objects.");
+        return new TeLspAttributesCaseBuilder().setTeLspAttributes(builder.build()).build();
+    }
+
+    private static void addObject(final TeLspAttributesBuilder builder, final RsvpTeObject object) {
+        if (object instanceof TspecObject) {
+            builder.setTspecObject((TspecObject) object);
+        } else if (object instanceof FlowSpecObject) {
+            builder.setFlowSpecObject((FlowSpecObject) object);
+        } else if (object instanceof SessionAttributeObject) {
+            builder.setSessionAttributeObject((SessionAttributeObject) object);
+        } else if (object instanceof ExplicitRouteObject) {
+            builder.setExplicitRouteObject((ExplicitRouteObject) object);
+        } else if (object instanceof RecordRouteObject) {
+            builder.setRecordRouteObject((RecordRouteObject) object);
+        } else if (object instanceof FastRerouteObject) {
+            builder.setFastRerouteObject((FastRerouteObject) object);
+        } else if (object instanceof DetourObject) {
+            builder.setDetourObject((DetourObject) object);
+        } else if (object instanceof ExcludeRouteObject) {
+            builder.setExcludeRouteObject((ExcludeRouteObject) object);
+        } else if (object instanceof SecondaryExplicitRouteObject) {
+            builder.setSecondaryExplicitRouteObject((SecondaryExplicitRouteObject) object);
+        } else if (object instanceof SecondaryRecordRouteObject) {
+            builder.setSecondaryRecordRouteObject((SecondaryRecordRouteObject) object);
+        } else if (object instanceof LspAttributesObject) {
+            builder.setLspAttributesObject((LspAttributesObject) object);
+        } else if (object instanceof LspRequiredAttributesObject) {
+            builder.setLspRequiredAttributesObject((LspRequiredAttributesObject) object);
+        } else if (object instanceof ProtectionObject) {
+            builder.setProtectionObject((ProtectionObject) object);
+        } else if (object instanceof AssociationObject) {
+            builder.setAssociationObject((AssociationObject) object);
+        } else if (object instanceof PrimaryPathRouteObject) {
+            builder.setPrimaryPathRouteObject((PrimaryPathRouteObject) object);
+        } else if (object instanceof AdminStatusObject) {
+            builder.setAdminStatusObject((AdminStatusObject) object);
+        } else if (object instanceof BandwidthObject) {
+            builder.setBandwidthObject((BandwidthObject) object);
+        } else if (object instanceof MetricObject) {
+            builder.setMetricObject((MetricObject) object);
+        } else {
+            throw new IllegalStateException("Unhandled TE LSP Object " + object);
+        }
+    }
+
+
+    public static void serializeLspAttributes(final RSVPTeObjectRegistry registry, final TeLspAttributesCase linkState, final ByteBuf output) {
+        LOG.trace("Started serializing TE LSP Objects");
+        final ByteBuf byteBuf = Unpooled.buffer();
+
+        final TeLspAttributes teLspAttribute = linkState.getTeLspAttributes();
+        final TspecObject tSpec = teLspAttribute.getTspecObject();
+        registry.serializeRSPVTe(tSpec, byteBuf);
+
+        final FlowSpecObject flow = teLspAttribute.getFlowSpecObject();
+        registry.serializeRSPVTe(flow, byteBuf);
+
+        final SessionAttributeObject sao = teLspAttribute.getSessionAttributeObject();
+        if (sao instanceof BasicSessionAttributeObject) {
+            registry.serializeRSPVTe((BasicSessionAttributeObject) sao, byteBuf);
+        } else if (sao instanceof SessionAttributeObjectWithResourcesAffinities) {
+            registry.serializeRSPVTe((SessionAttributeObjectWithResourcesAffinities) sao, byteBuf);
+        }
+
+        final ExplicitRouteObject ero = teLspAttribute.getExplicitRouteObject();
+        registry.serializeRSPVTe(ero, byteBuf);
+
+        final RecordRouteObject rro = teLspAttribute.getRecordRouteObject();
+        registry.serializeRSPVTe(rro, byteBuf);
+
+        final FastRerouteObject fro = teLspAttribute.getFastRerouteObject();
+        if (fro instanceof BasicFastRerouteObject) {
+            registry.serializeRSPVTe((BasicFastRerouteObject) fro, byteBuf);
+        } else if (fro instanceof LegacyFastRerouteObject) {
+            registry.serializeRSPVTe((LegacyFastRerouteObject) fro, byteBuf);
+        }
+
+        final DetourObject dto = teLspAttribute.getDetourObject();
+        if (dto instanceof Ipv4DetourObject) {
+            registry.serializeRSPVTe((Ipv4DetourObject) dto, byteBuf);
+        } else if (dto instanceof Ipv6DetourObject) {
+            registry.serializeRSPVTe((Ipv6DetourObject) dto, byteBuf);
+        }
+
+        final ExcludeRouteObject exro = teLspAttribute.getExcludeRouteObject();
+        registry.serializeRSPVTe(exro, byteBuf);
+
+        final SecondaryExplicitRouteObject sero = teLspAttribute.getSecondaryExplicitRouteObject();
+        registry.serializeRSPVTe(sero, byteBuf);
+
+        final SecondaryRecordRouteObject srro = teLspAttribute.getSecondaryRecordRouteObject();
+        registry.serializeRSPVTe(srro, byteBuf);
+
+        final LspAttributesObject lspAtt = teLspAttribute.getLspAttributesObject();
+        registry.serializeRSPVTe(lspAtt, byteBuf);
+
+        final LspRequiredAttributesObject rao = teLspAttribute.getLspRequiredAttributesObject();
+        registry.serializeRSPVTe(rao, byteBuf);
+
+        final ProtectionObject po = teLspAttribute.getProtectionObject();
+        if (po instanceof DynamicControlProtectionObject) {
+            registry.serializeRSPVTe((DynamicControlProtectionObject) po, byteBuf);
+        } else if (po instanceof BasicProtectionObject) {
+            registry.serializeRSPVTe((BasicProtectionObject) po, byteBuf);
+        }
+
+        final AssociationObject aso = teLspAttribute.getAssociationObject();
+        registry.serializeRSPVTe(aso, byteBuf);
+
+        final PrimaryPathRouteObject ppr = teLspAttribute.getPrimaryPathRouteObject();
+        registry.serializeRSPVTe(ppr, byteBuf);
+
+        final AdminStatusObject adso = teLspAttribute.getAdminStatusObject();
+        registry.serializeRSPVTe(adso, byteBuf);
+
+        final BandwidthObject bo = teLspAttribute.getBandwidthObject();
+        if (bo instanceof BasicBandwidthObject) {
+            registry.serializeRSPVTe((BasicBandwidthObject) bo, byteBuf);
+        } else if (bo instanceof ReoptimizationBandwidthObject) {
+            registry.serializeRSPVTe((ReoptimizationBandwidthObject) bo, byteBuf);
+        }
+
+        final MetricObject mo = teLspAttribute.getMetricObject();
+        registry.serializeRSPVTe(mo, byteBuf);
+
+
+        output.writeShort(MAGIC_NUMBER);
+        output.writeShort(byteBuf.readableBytes());
+        output.writeBytes(byteBuf);
+        LOG.trace("Finished serializing TE LSP Objects");
+    }
+}
index a257e2e5425bce993dfffb1da60a5ec280b1dd12..d849317997a28cfe4d0af867170d1e95ef820ea5 100644 (file)
@@ -19,6 +19,8 @@ import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
 import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
+import org.opendaylight.protocol.util.Ipv4Util;
+import org.opendaylight.protocol.util.Ipv6Util;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.Identifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NlriType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.ProtocolId;
@@ -32,12 +34,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.NodeCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.LinkDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.LocalNodeDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.RemoteNodeDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.node._case.NodeDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.AdvertisingNodeDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.PrefixDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv4CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv6CaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.linkstate._case.DestinationLinkstateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCase;
@@ -50,6 +57,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.TunnelId;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
@@ -93,6 +102,8 @@ public final class LinkstateNlriParser implements NlriParser, NlriSerializer {
     @VisibleForTesting
     public static final NodeIdentifier LINK_DESCRIPTORS_NID = new NodeIdentifier(LinkDescriptors.QNAME);
 
+    @VisibleForTesting
+    public static final NodeIdentifier TE_LSP_NID = new NodeIdentifier(TeLspCase.QNAME);
     @VisibleForTesting
     public static final NodeIdentifier DISTINGUISHER_NID = new NodeIdentifier(QName.cachedReference(QName.create(CLinkstateDestination.QNAME, "route-distinguisher")));
     @VisibleForTesting
@@ -154,15 +165,19 @@ public final class LinkstateNlriParser implements NlriParser, NlriSerializer {
 
             // if we are dealing with linkstate nodes/links, parse local node descriptor
             org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NodeIdentifier localDescriptor = null;
-            final int localtype = nlri.readUnsignedShort();
-            final int locallength = nlri.readUnsignedShort();
-            if (localtype == LOCAL_NODE_DESCRIPTORS_TYPE) {
-                localDescriptor = NodeNlriParser.parseNodeDescriptors(nlri.readSlice(locallength), type, true);
+            ByteBuf rest = null;
+            if(!type.equals(NlriType.Ipv4TeLsp) && !type.equals(NlriType.Ipv6TeLsp)) {
+                final int localtype = nlri.readUnsignedShort();
+                final int locallength = nlri.readUnsignedShort();
+                if (localtype == LOCAL_NODE_DESCRIPTORS_TYPE) {
+                    localDescriptor = NodeNlriParser.parseNodeDescriptors(nlri.readSlice(locallength), type, true);
+                }
+                final int restLength = length - (isVpn ? ROUTE_DISTINGUISHER_LENGTH : 0) - PROTOCOL_ID_LENGTH -
+                    IDENTIFIER_LENGTH - TYPE_LENGTH - LENGTH_SIZE - locallength;
+                LOG.trace("Restlength {}", restLength);
+                rest = nlri.readSlice(restLength);
             }
-            final int restLength = length - (isVpn ? ROUTE_DISTINGUISHER_LENGTH : 0) - PROTOCOL_ID_LENGTH - IDENTIFIER_LENGTH
-                - TYPE_LENGTH - LENGTH_SIZE - locallength;
-            LOG.trace("Restlength {}", restLength);
-            final ByteBuf rest = nlri.readSlice(restLength);
+
             switch (type) {
             case Link:
                 parseLink(builder, rest, (LocalNodeDescriptors) localDescriptor);
@@ -181,6 +196,12 @@ public final class LinkstateNlriParser implements NlriParser, NlriSerializer {
                 // node nlri is already parsed as it contains only the common fields for node and link nlri
                 builder.setObjectType(new NodeCaseBuilder().setNodeDescriptors((NodeDescriptors) localDescriptor).build());
                 break;
+            case Ipv4TeLsp:
+                builder.setObjectType(parseIpv4TeLsp(nlri));
+                break;
+            case Ipv6TeLsp:
+                builder.setObjectType(parseIpv6TeLsp(nlri));
+                break;
             default:
                 break;
             }
@@ -189,6 +210,24 @@ public final class LinkstateNlriParser implements NlriParser, NlriSerializer {
         return dests;
     }
 
+    private static TeLspCase parseIpv6TeLsp(final ByteBuf nlri) {
+        final Ipv6CaseBuilder ipv6Builder = new Ipv6CaseBuilder();
+        ipv6Builder.setIpv6TunnelSenderAddress(Ipv6Util.addressForByteBuf(nlri));
+        final TunnelId tunnelId6 = new TunnelId(nlri.readUnsignedShort());
+        final LspId lspId6 = new LspId((long)nlri.readUnsignedShort());
+        ipv6Builder.setIpv6TunnelEndpointAddress(Ipv6Util.addressForByteBuf(nlri));
+        return new TeLspCaseBuilder().setAddressFamily(ipv6Builder.build()).setLspId(lspId6).setTunnelId(tunnelId6).build();
+    }
+
+    private static TeLspCase parseIpv4TeLsp(final ByteBuf nlri) {
+        final Ipv4CaseBuilder ipv4Builder = new Ipv4CaseBuilder();
+        ipv4Builder.setIpv4TunnelSenderAddress(Ipv4Util.addressForByteBuf(nlri));
+        final TunnelId tunnelId = new TunnelId(nlri.readUnsignedShort());
+        final LspId lspId = new LspId((long)nlri.readUnsignedShort());
+        ipv4Builder.setIpv4TunnelEndpointAddress(Ipv4Util.addressForByteBuf(nlri));
+        return new TeLspCaseBuilder().setAddressFamily(ipv4Builder.build()).setLspId(lspId).setTunnelId(tunnelId).build();
+    }
+
     @Override
     public void parseNlri(final ByteBuf nlri, final MpUnreachNlriBuilder builder) throws BGPParsingException {
         if (!nlri.isReadable()) {
@@ -260,6 +299,13 @@ public final class LinkstateNlriParser implements NlriParser, NlriSerializer {
             NodeNlriParser.serializeNodeIdentifier(nCase.getNodeDescriptors(), ldescs);
             TlvUtil.writeTLV(LOCAL_NODE_DESCRIPTORS_TYPE, ldescs, nlriByteBuf);
             nlriType = NlriType.Node;
+        } else if (ot instanceof TeLspCase) {
+            final TeLspCase teLSP = (TeLspCase) destination.getObjectType();
+            final AddressFamily afi = teLSP.getAddressFamily();
+            nlriType = TeLspNlriParser.serializeIpvTSA(afi, ldescs);
+            TeLspNlriParser.serializeTunnelID(teLSP.getTunnelId(), ldescs);
+            TeLspNlriParser.serializeLspID(teLSP.getLspId(), ldescs);
+            TeLspNlriParser.serializeTEA(afi, ldescs);
         } else {
             LOG.warn("Unknown NLRI Type.");
         }
@@ -311,8 +357,12 @@ public final class LinkstateNlriParser implements NlriParser, NlriSerializer {
             return ProtocolId.Direct.getIntValue();
         case "static":
             return ProtocolId.Static.getIntValue();
+        case "rsvpte":
+            return ProtocolId.RsvpTe.getIntValue();
         case "bgp-epe":
             return ProtocolId.BgpEpe.getIntValue();
+        case "segment-routing":
+            return ProtocolId.SegmentRouting.getIntValue();
         default:
             return 0;
         }
@@ -337,41 +387,44 @@ public final class LinkstateNlriParser implements NlriParser, NlriSerializer {
         }
 
         final ChoiceNode objectType = (ChoiceNode) linkstate.getChild(OBJECT_TYPE_NID).get();
-
-        if (objectType.getChild(ADVERTISING_NODE_DESCRIPTORS_NID).isPresent()) {
-            // prefix node descriptors
-            final PrefixCaseBuilder prefixBuilder = new PrefixCaseBuilder();
-            prefixBuilder.setAdvertisingNodeDescriptors(NodeNlriParser.serializeAdvNodeDescriptors((ContainerNode) objectType.getChild(
+        if (!builder.getProtocolId().equals(ProtocolId.RsvpTe)) {
+            if (objectType.getChild(ADVERTISING_NODE_DESCRIPTORS_NID).isPresent()) {
+                // prefix node descriptors
+                final PrefixCaseBuilder prefixBuilder = new PrefixCaseBuilder();
+                prefixBuilder.setAdvertisingNodeDescriptors(NodeNlriParser.serializeAdvNodeDescriptors((ContainerNode) objectType.getChild(
                     ADVERTISING_NODE_DESCRIPTORS_NID).get()));
 
-            // prefix descriptors
-            final Optional<DataContainerChild<? extends PathArgument, ?>> prefixDescriptors = objectType.getChild(PREFIX_DESCRIPTORS_NID);
-            if (prefixDescriptors.isPresent()) {
-                prefixBuilder.setPrefixDescriptors(PrefixNlriParser.serializePrefixDescriptors((ContainerNode) prefixDescriptors.get()));
-            }
-            builder.setObjectType(prefixBuilder.build());
-        } else if (objectType.getChild(LOCAL_NODE_DESCRIPTORS_NID).isPresent()) {
-            // link local node descriptors
-            final LinkCaseBuilder linkBuilder = new LinkCaseBuilder();
+                // prefix descriptors
+                final Optional<DataContainerChild<? extends PathArgument, ?>> prefixDescriptors = objectType.getChild(PREFIX_DESCRIPTORS_NID);
+                if (prefixDescriptors.isPresent()) {
+                    prefixBuilder.setPrefixDescriptors(PrefixNlriParser.serializePrefixDescriptors((ContainerNode) prefixDescriptors.get()));
+                }
+                builder.setObjectType(prefixBuilder.build());
+            } else if (objectType.getChild(LOCAL_NODE_DESCRIPTORS_NID).isPresent()) {
+                // link local node descriptors
+                final LinkCaseBuilder linkBuilder = new LinkCaseBuilder();
 
-            linkBuilder.setLocalNodeDescriptors(NodeNlriParser.serializeLocalNodeDescriptors((ContainerNode) objectType.getChild(LOCAL_NODE_DESCRIPTORS_NID).get()));
-            // link remote node descriptors
-            if (objectType.getChild(REMOTE_NODE_DESCRIPTORS_NID).isPresent()) {
-                linkBuilder.setRemoteNodeDescriptors(NodeNlriParser.serializeRemoteNodeDescriptors((ContainerNode) objectType.getChild(REMOTE_NODE_DESCRIPTORS_NID).get()));
-            }
-            // link descriptors
-            final Optional<DataContainerChild<? extends PathArgument, ?>> linkDescriptors = objectType.getChild(LINK_DESCRIPTORS_NID);
-            if (linkDescriptors.isPresent()) {
-                linkBuilder.setLinkDescriptors(LinkNlriParser.serializeLinkDescriptors((ContainerNode) linkDescriptors.get()));
+                linkBuilder.setLocalNodeDescriptors(NodeNlriParser.serializeLocalNodeDescriptors((ContainerNode) objectType.getChild(LOCAL_NODE_DESCRIPTORS_NID).get()));
+                // link remote node descriptors
+                if (objectType.getChild(REMOTE_NODE_DESCRIPTORS_NID).isPresent()) {
+                    linkBuilder.setRemoteNodeDescriptors(NodeNlriParser.serializeRemoteNodeDescriptors((ContainerNode) objectType.getChild(REMOTE_NODE_DESCRIPTORS_NID).get()));
+                }
+                // link descriptors
+                final Optional<DataContainerChild<? extends PathArgument, ?>> linkDescriptors = objectType.getChild(LINK_DESCRIPTORS_NID);
+                if (linkDescriptors.isPresent()) {
+                    linkBuilder.setLinkDescriptors(LinkNlriParser.serializeLinkDescriptors((ContainerNode) linkDescriptors.get()));
+                }
+                builder.setObjectType(linkBuilder.build());
+            } else if (objectType.getChild(NODE_DESCRIPTORS_NID).isPresent()) {
+                final NodeCaseBuilder nodeBuilder = new NodeCaseBuilder();
+                // node descriptors
+                nodeBuilder.setNodeDescriptors(NodeNlriParser.serializeNodeDescriptors((ContainerNode) objectType.getChild(NODE_DESCRIPTORS_NID).get()));
+                builder.setObjectType(nodeBuilder.build());
+            } else {
+                LOG.warn("Unknown Object Type.");
             }
-            builder.setObjectType(linkBuilder.build());
-        } else if (objectType.getChild(NODE_DESCRIPTORS_NID).isPresent()) {
-            final NodeCaseBuilder nodeBuilder = new NodeCaseBuilder();
-            // node descriptors
-            nodeBuilder.setNodeDescriptors(NodeNlriParser.serializeNodeDescriptors((ContainerNode) objectType.getChild(NODE_DESCRIPTORS_NID).get()));
-            builder.setObjectType(nodeBuilder.build());
-        } else {
-            LOG.warn("Unknown Object Type.");
+        } else if (objectType.getChild(TE_LSP_NID).isPresent()) {
+            builder.setObjectType(TeLspNlriParser.serializeTeLsp((ContainerNode) objectType.getChild(TE_LSP_NID).get()));
         }
         return builder.build();
     }
diff --git a/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/nlri/TeLspNlriParser.java b/bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/nlri/TeLspNlriParser.java
new file mode 100644 (file)
index 0000000..6258f13
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2015 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.bgp.linkstate.nlri;
+
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeIpv4Address;
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeIpv6Address;
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeShort;
+import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedShort;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.NlriType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.CLinkstateDestination;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv4Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv4CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv6Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv6CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.TunnelId;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+
+@VisibleForTesting
+public final class TeLspNlriParser {
+
+    @VisibleForTesting
+    public static final YangInstanceIdentifier.NodeIdentifier LSP_ID = new YangInstanceIdentifier.NodeIdentifier(
+        QName.cachedReference(QName.create(CLinkstateDestination.QNAME, "lsp-id")));
+    @VisibleForTesting
+    public static final YangInstanceIdentifier.NodeIdentifier TUNNEL_ID = new YangInstanceIdentifier.NodeIdentifier(
+        QName.cachedReference(QName.create(CLinkstateDestination.QNAME, "tunnel-id")));
+    @VisibleForTesting
+    public static final YangInstanceIdentifier.NodeIdentifier IPV4_TUNNEL_SENDER_ADDRESS = new YangInstanceIdentifier.NodeIdentifier(
+        QName.cachedReference(QName.create(CLinkstateDestination.QNAME, "ipv4-tunnel-sender-address")));
+    @VisibleForTesting
+    public static final YangInstanceIdentifier.NodeIdentifier IPV4_TUNNEL_ENDPOINT_ADDRESS = new YangInstanceIdentifier
+        .NodeIdentifier(QName.cachedReference(QName.create(CLinkstateDestination.QNAME, "ipv4-tunnel-endpoint-address")));
+    @VisibleForTesting
+    public static final YangInstanceIdentifier.NodeIdentifier IPV6_TUNNEL_SENDER_ADDRESS = new YangInstanceIdentifier
+        .NodeIdentifier( QName.cachedReference(QName.create(CLinkstateDestination.QNAME, "ipv6-tunnel-sender-address")));
+    @VisibleForTesting
+    public static final YangInstanceIdentifier.NodeIdentifier IPV6_TUNNEL_ENDPOINT_ADDRESS = new YangInstanceIdentifier
+        .NodeIdentifier(QName.cachedReference(QName.create(CLinkstateDestination.QNAME, "ipv6-tunnel-endpoint-address")));
+
+    @VisibleForTesting
+    public static final YangInstanceIdentifier.NodeIdentifier IPV4_CASE = new YangInstanceIdentifier.NodeIdentifier(Ipv4Case.QNAME);
+    @VisibleForTesting
+    public static final YangInstanceIdentifier.NodeIdentifier IPV6_CASE = new YangInstanceIdentifier.NodeIdentifier(Ipv6Case.QNAME);
+    @VisibleForTesting
+    public static final YangInstanceIdentifier.NodeIdentifier ADDRESS_FAMILY = new YangInstanceIdentifier.NodeIdentifier(AddressFamily.QNAME);
+
+    private TeLspNlriParser() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static NlriType serializeIpvTSA(final AddressFamily addressFamily, final ByteBuf body) {
+        if (addressFamily.equals(Ipv6Case.class)) {
+            final Ipv6Address ipv6 = ((Ipv6Case) addressFamily).getIpv6TunnelSenderAddress();
+            Preconditions.checkArgument(ipv6 != null, "Ipv6TunnelSenderAddress is mandatory.");
+            writeIpv6Address(ipv6, body);
+            return NlriType.Ipv6TeLsp;
+        }
+
+        final Ipv4Address ipv4 = ((Ipv4Case) addressFamily).getIpv4TunnelSenderAddress();
+        Preconditions.checkArgument(ipv4 != null, "Ipv4TunnelSenderAddress is mandatory.");
+        writeIpv4Address(ipv4, body);
+
+        return NlriType.Ipv4TeLsp;
+    }
+
+    public static void serializeTunnelID(final TunnelId tunnelID, final ByteBuf body) {
+        Preconditions.checkArgument(tunnelID != null, "TunnelId is mandatory.");
+        writeUnsignedShort(tunnelID.getValue(), body);
+    }
+
+    public static void serializeLspID(final LspId lspId, final ByteBuf body) {
+        Preconditions.checkArgument(lspId != null, "LspId is mandatory.");
+        writeShort(lspId.getValue().shortValue(), body);
+    }
+
+    public static void serializeTEA(final AddressFamily addressFamily, final ByteBuf body) {
+        if (addressFamily.equals(Ipv6Case.class)) {
+            final Ipv6Address ipv6 = ((Ipv6Case) addressFamily).getIpv6TunnelEndpointAddress();
+            Preconditions.checkArgument(ipv6 != null, "Ipv6TunnelEndpointAddress is mandatory.");
+            writeIpv6Address(ipv6, body);
+            return;
+        }
+
+        final Ipv4Address ipv4 = ((Ipv4Case) addressFamily).getIpv4TunnelEndpointAddress();
+        Preconditions.checkArgument(ipv4 != null, "Ipv4TunnelEndpointAddress is mandatory.");
+        Preconditions.checkArgument(ipv4 != null, "Ipv4TunnelEndpointAddress is mandatory.");
+        writeIpv4Address(ipv4, body);
+    }
+
+    public static TeLspCase serializeTeLsp(final ContainerNode containerNode) {
+        final TeLspCaseBuilder teLspCase = new TeLspCaseBuilder();
+        teLspCase.setLspId(new LspId((Long) containerNode.getChild(LSP_ID).get().getValue()));
+        teLspCase.setTunnelId(new TunnelId((Integer) containerNode.getChild(TUNNEL_ID).get().getValue()));
+        if(containerNode.getChild(ADDRESS_FAMILY).isPresent()) {
+            final ChoiceNode addressFamily = (ChoiceNode) containerNode.getChild(ADDRESS_FAMILY).get();
+            if(addressFamily.getChild(IPV4_CASE).isPresent()) {
+                teLspCase.setAddressFamily(serializeAddressFamily((ContainerNode) addressFamily.getChild(IPV4_CASE)
+                    .get(), true));
+            }else{
+                teLspCase.setAddressFamily(serializeAddressFamily((ContainerNode) addressFamily.getChild(IPV6_CASE)
+                    .get(), false));
+            }
+        }
+
+        return teLspCase.build();
+    }
+
+    private static AddressFamily serializeAddressFamily(final ContainerNode containerNode, final boolean ipv4Case) {
+        if(ipv4Case) {
+            return new Ipv4CaseBuilder()
+                .setIpv4TunnelSenderAddress(new Ipv4Address((String) containerNode.getChild(IPV4_TUNNEL_SENDER_ADDRESS).get().getValue()))
+                .setIpv4TunnelEndpointAddress(new Ipv4Address((String) containerNode.getChild(IPV4_TUNNEL_ENDPOINT_ADDRESS).get().getValue()))
+                .build();
+        }
+
+        return new Ipv6CaseBuilder()
+            .setIpv6TunnelSenderAddress(new Ipv6Address((String) containerNode.getChild(IPV6_TUNNEL_SENDER_ADDRESS).get().getValue()))
+            .setIpv6TunnelEndpointAddress(new Ipv6Address((String) containerNode.getChild(IPV6_TUNNEL_ENDPOINT_ADDRESS).get().getValue()))
+            .build();
+    }
+}
index 088193dc5249faf9d07c5dd82991d89aa8a29225..b8e6d08fcea26a28a90f5fe30ec235098c33b420 100644 (file)
@@ -72,6 +72,14 @@ module bgp-linkstate {
             enum ipv6-prefix {
                 value 4;
             }
+            enum ipv4-te-lsp {
+                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-4.1";
+                value 5;
+            }
+            enum ipv6-te-lsp {
+                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-4.1";
+                value 6;
+            }
         }
     }
 
@@ -96,10 +104,18 @@ module bgp-linkstate {
             enum static {
                 value 5;
             }
+            enum rsvp-te {
+                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-2.1";
+                value 6;
+            }
             enum bgp-epe {
                 reference "https://tools.ietf.org/html/draft-ietf-idr-bgpls-segment-routing-epe-00#section-4";
                 value 7;
             }
+            enum segment-routing {
+                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-2.1";
+                value 8; // segment-routing protocol-id TBD by IANA
+            }
         }
     }
 
@@ -330,6 +346,36 @@ module bgp-linkstate {
                     uses prefix-identifiers;
                 }
             }
+            case te-lsp-case {
+                choice address-family {
+                    case ipv4-case {
+                        leaf ipv4-tunnel-sender-address {
+                            type inet:ipv4-address;
+                            mandatory true;
+                        }
+                        leaf ipv4-tunnel-endpoint-address {
+                            type inet:ipv4-address;
+                            mandatory true;
+                        }
+                    }
+                    case ipv6-case {
+                        leaf ipv6-tunnel-sender-address {
+                            type inet:ipv6-address;
+                            mandatory true;
+                        }
+                        leaf ipv6-tunnel-endpoint-address {
+                            type inet:ipv6-address;
+                            mandatory true;
+                        }
+                    }
+                }
+                leaf tunnel-id {
+                    type rsvp:tunnel-id;
+                }
+                leaf lsp-id {
+                    type rsvp:lsp-id;
+                }
+            }
         }
     }
 
@@ -599,6 +645,30 @@ module bgp-linkstate {
                     uses prefix-state;
                 }
             }
+            case te-lsp-attributes-case {
+                description "LSP Object";
+                reference "http://tools.ietf.org/html/draft-ietf-idr-te-lsp-distribution-03#section-2.2";
+                container te-lsp-attributes {
+                    uses rsvp:tspec-object;
+                    uses rsvp:flow-spec-object;
+                    uses rsvp:session-attribute-object;
+                    uses rsvp:explicit-route-object;
+                    uses rsvp:secondary-explicit-route-object;
+                    uses rsvp:record-route-object;
+                    uses rsvp:secondary-record-route-object;
+                    uses rsvp:fast-reroute-object;
+                    uses rsvp:detour-object;
+                    uses rsvp:exclude-route-object;
+                    uses rsvp:lsp-attributes-object;
+                    uses rsvp:lsp-required-attributes-object;
+                    uses rsvp:protection-object;
+                    uses rsvp:association-object;
+                    uses rsvp:primary-path-route-object;
+                    uses rsvp:admin-status-object;
+                    uses rsvp:bandwidth-object;
+                    uses rsvp:metric-object;
+                }
+            }
         }
     }
 
index f9c70164ffe8155e4bf75b7a1789ca01a3f40302..08b25d6c0869a94a52fa7162d066c73af11177ae 100644 (file)
@@ -7,6 +7,7 @@ module odl-bgp-linkstate-cfg {
     import config { prefix config; revision-date 2013-04-05; }
     import odl-bgp-parser-spi-cfg { prefix bgpspi; revision-date 2013-11-15; }
     import odl-bgp-rib-spi-cfg { prefix ribspi; revision-date 2013-11-15; }
+    import odl-rsvp-parser-spi-cfg { prefix rsvp-spi; revision-date 2015-08-26; }
 
     organization "Cisco Systems, Inc.";
 
@@ -23,6 +24,11 @@ module odl-bgp-linkstate-cfg {
         accompanies this distribution, and is available at
         http://www.eclipse.org/legal/epl-v10.html";
 
+    revision "2015-08-26" {
+        description
+            "Add rsvp-extensions";
+    }
+
     revision "2013-11-15" {
         description
             "Initial revision";
@@ -45,6 +51,15 @@ module odl-bgp-linkstate-cfg {
                 type boolean;
                 default true;
             }
+
+            container rsvp-extensions {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity rsvp-spi:consumer-extensions;
+                    }
+                }
+            }
         }
     }
 }
index 605c62d14ef87e6cfde2448824d18a10c9e2f1fd..5bed487b1025b2928b6f17da57ea4f7c7de72dff 100644 (file)
@@ -9,9 +9,9 @@
 package org.opendaylight.controller.config.yang.bgp.linkstate;
 
 import static org.junit.Assert.assertTrue;
-
 import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
+import javax.management.InstanceAlreadyExistsException;
 import javax.management.ObjectName;
 import org.junit.Before;
 import org.junit.Test;
@@ -23,22 +23,28 @@ import org.opendaylight.controller.config.yang.bgp.parser.spi.SimpleBGPExtension
 import org.opendaylight.controller.config.yang.bgp.parser.spi.SimpleBGPExtensionProviderContextModuleTest;
 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleFactory;
 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleTest;
+import org.opendaylight.controller.config.yang.rsvp.spi.SimpleRSVPExtensionProviderContextModuleFactory;
+import org.opendaylight.controller.config.yang.rsvp.spi.SimpleRSVPExtensionProviderContextModuleMXBean;
 
 public class LinkstateModuleTest extends AbstractConfigTest {
 
     private static final String FACTORY_NAME = LinkstateModuleFactory.NAME;
     private static final String INSTANCE_NAME = "bgp-linkstate-impl";
+    private static final String RSVP_EXTENSION_INSTANCE_NAME = "extension-impl-rsvp";
+    private ObjectName rspvInstance;
 
     @Before
     public void setUp() {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, new LinkstateModuleFactory(), new SimpleBGPExtensionProviderContextModuleFactory(), new RIBExtensionsImplModuleFactory()));
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, new
+            LinkstateModuleFactory(), new SimpleBGPExtensionProviderContextModuleFactory(), new
+            RIBExtensionsImplModuleFactory(), new SimpleRSVPExtensionProviderContextModuleFactory()));
     }
 
     @Test
     public void testLSTypeDefaultValue() throws Exception {
         final CommitStatus status = createLinkstateModuleInstance(Optional.<Boolean>absent());
         assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 3, 0, 0);
+        assertStatus(status, 4, 0, 0);
         final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
         final LinkstateModuleMXBean mxBean = transaction.newMXBeanProxy(transaction.lookupConfigBean(FACTORY_NAME, INSTANCE_NAME), LinkstateModuleMXBean.class);
         assertTrue(mxBean.getIanaLinkstateAttributeType());
@@ -48,7 +54,7 @@ public class LinkstateModuleTest extends AbstractConfigTest {
     public void testCreateBean() throws Exception {
         final CommitStatus status = createLinkstateModuleInstance(Optional.of(false));
         assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 3, 0, 0);
+        assertStatus(status, 4, 0, 0);
     }
 
     @Test
@@ -58,7 +64,7 @@ public class LinkstateModuleTest extends AbstractConfigTest {
         assertBeanCount(1, FACTORY_NAME);
         final CommitStatus status = transaction.commit();
         assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 0, 3);
+        assertStatus(status, 0, 0, 4);
     }
 
     @Test
@@ -68,21 +74,30 @@ public class LinkstateModuleTest extends AbstractConfigTest {
         assertBeanCount(1, FACTORY_NAME);
         final LinkstateModuleMXBean mxBean = transaction.newMXBeanProxy(transaction.lookupConfigBean(FACTORY_NAME, INSTANCE_NAME), LinkstateModuleMXBean.class);
         mxBean.setIanaLinkstateAttributeType(true);
+        mxBean.setRsvpExtensions(rspvInstance);
         CommitStatus status = transaction.commit();
         assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 3, 0);
+        assertStatus(status, 0, 3, 1);
     }
 
     private CommitStatus createLinkstateModuleInstance(final Optional<Boolean> ianaLSAttributeType) throws Exception {
         final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
         final ObjectName linkstateON = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
+        final LinkstateModuleMXBean mxBean = transaction.newMXBeanProxy(linkstateON, LinkstateModuleMXBean.class);
         if(ianaLSAttributeType.isPresent()) {
-            final LinkstateModuleMXBean mxBean = transaction.newMXBeanProxy(linkstateON, LinkstateModuleMXBean.class);
             mxBean.setIanaLinkstateAttributeType(ianaLSAttributeType.get());
         }
-
+        rspvInstance = createRsvpExtensionsInstance(transaction);
+        mxBean.setRsvpExtensions(rspvInstance);
         SimpleBGPExtensionProviderContextModuleTest.createBGPExtensionsModuleInstance(transaction, Lists.newArrayList(linkstateON));
         RIBExtensionsImplModuleTest.createRIBExtensionsModuleInstance(transaction, Lists.newArrayList(linkstateON));
         return transaction.commit();
     }
+
+    private ObjectName createRsvpExtensionsInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
+        final ObjectName nameCreated = transaction.createModule(SimpleRSVPExtensionProviderContextModuleFactory.NAME,
+            RSVP_EXTENSION_INSTANCE_NAME);
+        transaction.newMXBeanProxy(nameCreated, SimpleRSVPExtensionProviderContextModuleMXBean.class);
+        return nameCreated;
+    }
 }
index 99ab326616af9887b8e23cd6e2db4cb6ecdc26b4..551d09a97a3786d91e31e29a5238eff28cc0a1cc 100644 (file)
@@ -10,12 +10,12 @@ package org.opendaylight.protocol.bgp.linkstate;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-
 import org.junit.Test;
 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
 import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContext;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
 import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext;
+import org.opendaylight.protocol.rsvp.parser.spi.pojo.ServiceLoaderRSVPExtensionProviderContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily;
 
@@ -23,7 +23,7 @@ public class ActivatorTest {
 
     @Test
     public void testActivator() throws Exception {
-        final BGPActivator act = new BGPActivator();
+        final BGPActivator act = new BGPActivator(true, ServiceLoaderRSVPExtensionProviderContext.getSingletonInstance().getRsvpRegistry());
         final BGPExtensionProviderContext context = new SimpleBGPExtensionProviderContext();
 
         assertNull(context.getAddressFamilyRegistry().classForFamily(16388));
index bf5088e947fc2630f3ed88d5d3bbce187aad33be..f62991f99c04905ba3fa5327e6f14e98c810dca5 100644 (file)
@@ -18,13 +18,19 @@ import io.netty.buffer.Unpooled;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Arrays;
+import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.protocol.bgp.linkstate.attribute.LinkAttributesParser;
 import org.opendaylight.protocol.bgp.linkstate.attribute.LinkstateAttributeParser;
 import org.opendaylight.protocol.bgp.linkstate.attribute.NodeAttributesParser;
 import org.opendaylight.protocol.bgp.linkstate.attribute.PrefixAttributesParser;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
+import org.opendaylight.protocol.rsvp.parser.impl.RSVPActivator;
+import org.opendaylight.protocol.rsvp.parser.spi.RSVPExtensionProviderContext;
+import org.opendaylight.protocol.rsvp.parser.spi.pojo.SimpleRSVPExtensionProviderContext;
 import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.protocol.util.Ipv4Util;
+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.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationIpv4CaseBuilder;
@@ -37,13 +43,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.NodeCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.PrefixDescriptorsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.LinkAttributesCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.PrefixAttributesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.TeLspAttributesCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.link.attributes._case.LinkAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.prefix.attributes._case.PrefixAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.path.attribute.link.state.attribute.te.lsp.attributes._case.TeLspAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.linkstate._case.DestinationLinkstateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
@@ -54,10 +63,27 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+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.rsvp.rev150820.AssociationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.association.object.AssociationObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.tspec.object.TspecObject;
 
 public class LinkstateAttributeParserTest {
 
-    private static final byte[] LINK_ATTR =  { 0x04, 0x04, 0, 0x04, 0x2a, 0x2a, 0x2a, 0x2a, 0x04, 0x06, 0, 0x04, 0x2b, 0x2b, 0x2b, 0x2b,
+    static final byte[] TE_LSP_ATTR = {0x00, (byte) 0x63, 0x00, (byte) 0x30, // TE LSP Attribute Type, lenght, value
+        0x00, (byte) 0x20, (byte) 0x0c, 0x02,  // Lenght, Class, Ctype
+        0x00, 0x00, 0x00, 0x07,
+        0x01, 0x00, 0x00, 0x06,
+        (byte) 0x7f, 0x00, 0x00, 0x05,
+        0x00, 0x00, 0x00, 0x01, //Token Bucket Rate
+        0x00, 0x00, 0x00, 0x02, //Token Bucket Size
+        0x00, 0x00, 0x00, 0x03, //Peak Data Rate
+        0x00, 0x00, 0x00, 0x04, //Minimum Policed Unit
+        0x00, 0x00, 0x00, 0x05, //Maximum Packet Size
+        0x00, (byte) 0x08, (byte) 0xc7, 0x01,  // Lenght, Class, Ctype
+        0x00, 0x01, 0x00, 0x02,
+        0x01, 0x02, 0x03, 0x04,};
+    private static final byte[] LINK_ATTR = {0x04, 0x04, 0, 0x04, 0x2a, 0x2a, 0x2a, 0x2a, 0x04, 0x06, 0, 0x04, 0x2b, 0x2b, 0x2b, 0x2b,
         0x04, 0x40, 0, 0x04, 0, 0, 0, 0, 0x04, 0x41, 0, 0x04, 0x49, (byte) 0x98, (byte) 0x96, (byte) 0x80, 0x04, 0x42, 0, 0x04,
         0x46, 0x43, 0x50, 0, 0x04, 0x43, 0, 0x20, 0x46, 0x43, 0x50, 0, 0x46, 0x43, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x04, 0x44, 0, 0x08, 0, 0, 0, 0, 0, 0, 0, 0, 0x04, 0x45, 0, 0x02, 0, 0x08, 0x04, 0x46, 0, 0x01,
@@ -79,8 +105,17 @@ public class LinkstateAttributeParserTest {
         0x10, 0x30, 0x50, 0x70, 0x04, (byte) 0x82, 0, 0x08, 0x12, 0x34, 0x56, 0x78, 0x10, 0x30, 0x50, 0x70,
         0x04, (byte) 0x83, 0, 0x04, 0, 0, 0, 0x0a, 0x04, (byte) 0x84, 0, 0x04, 0x0a, 0x19, 0x02, 0x1b, 0x04, (byte) 0x88, 0, 0x01, 0x0a };
 
-    private final LinkstateAttributeParser parser = new LinkstateAttributeParser(false);
+    private RSVPExtensionProviderContext context;
+    private RSVPActivator rsvpActivator;
+    private LinkstateAttributeParser parser;
 
+    @Before
+    public final void setUp() {
+        context = new SimpleRSVPExtensionProviderContext();
+        rsvpActivator = new RSVPActivator();
+        rsvpActivator.start(context);
+        parser = new LinkstateAttributeParser(false,context.getRsvpRegistry());
+    }
     private static AttributesBuilder createBuilder(final ObjectType type) {
         return new AttributesBuilder().addAugmentation(
             org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1.class,
@@ -228,6 +263,36 @@ public class LinkstateAttributeParserTest {
         assertArrayEquals(ByteArray.subByte(P4_ATTR, 0, P4_ATTR.length -5), ByteArray.getAllBytes(buff));
     }
 
+    @Test
+    public void testPositiveTELspAttribute() throws BGPParsingException {
+        final AttributesBuilder builder = createBuilder(new TeLspCaseBuilder().build());
+        this.parser.parseAttribute(Unpooled.copiedBuffer(TE_LSP_ATTR), builder);
+
+        final Attributes1 attrs = builder.getAugmentation(Attributes1.class);
+        final TeLspAttributes teLspAttributes = ((TeLspAttributesCase) attrs.getLinkStateAttribute()).getTeLspAttributes();
+        assertNotNull(teLspAttributes);
+        final TspecObject tSpec = teLspAttributes.getTspecObject();
+        assertNotNull(tSpec);
+        assertEquals(new Float32(new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01}), tSpec.getTokenBucketRate());
+        assertEquals(new Float32(new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02}), teLspAttributes.getTspecObject().getTokenBucketSize());
+        assertEquals(new Float32(new byte[]{(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03}), tSpec.getPeakDataRate());
+        assertEquals(new Long("4"), tSpec.getMinimumPolicedUnit());
+        assertEquals(new Long("5"), tSpec.getMaximumPacketSize());
+
+        AssociationObject associationObject = teLspAttributes.getAssociationObject();
+        assertEquals(AssociationType.Recovery, associationObject.getAssociationType());
+        final IpAddress ipv4 = new IpAddress(Ipv4Util.addressForByteBuf(Unpooled.copiedBuffer(new byte[]{0x01, 0x02, 0x03, 0x04})));
+        assertEquals(ipv4, associationObject.getIpAddress());
+        final short associationId = 2;
+        assertEquals(associationId, associationObject.getAssociationId().shortValue());
+
+        //serialization
+        final ByteBuf buff = Unpooled.buffer();
+        this.parser.serializeAttribute(builder.build(), buff);
+        assertArrayEquals(TE_LSP_ATTR, ByteArray.getAllBytes(buff));
+        assertTrue(Arrays.equals(TE_LSP_ATTR, ByteArray.getAllBytes(buff)));
+    }
+
     @Test(expected=UnsupportedOperationException.class)
     public void testLinkAttributesPrivateConstructor() throws Throwable {
         final Constructor<LinkAttributesParser> c = LinkAttributesParser.class.getDeclaredConstructor();
index 7b33ee757bc0cfa2710a8b0046683bfb12032371..67c9ff68016a5ce83529ab9d02c77d99cff6ffa3 100644 (file)
@@ -22,10 +22,12 @@ import org.opendaylight.protocol.bgp.linkstate.nlri.LinkNlriParser;
 import org.opendaylight.protocol.bgp.linkstate.nlri.LinkstateNlriParser;
 import org.opendaylight.protocol.bgp.linkstate.nlri.NodeNlriParser;
 import org.opendaylight.protocol.bgp.linkstate.nlri.PrefixNlriParser;
+import org.opendaylight.protocol.bgp.linkstate.nlri.TeLspNlriParser;
 import org.opendaylight.protocol.bgp.linkstate.spi.TlvUtil;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.DomainIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.OspfRouteType;
@@ -36,12 +38,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.LinkCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.NodeCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.PrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.TeLspCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.LinkDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.LocalNodeDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.link._case.RemoteNodeDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.node._case.NodeDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.AdvertisingNodeDescriptors;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.prefix._case.PrefixDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.te.lsp._case.address.family.Ipv4Case;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.node.identifier.CRouterIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.node.identifier.c.router.identifier.IsisNodeCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.node.identifier.c.router.identifier.IsisPseudonodeCaseBuilder;
@@ -66,6 +70,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.TunnelId;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
@@ -119,6 +125,15 @@ public class LinkstateNlriParserTest {
         (byte) 0x02, (byte) 0x00, (byte) 0x0F, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x03, (byte) 0x01, (byte) 0x09,
         (byte) 0x00, (byte) 0x03, (byte) 0x10, (byte) 0xFF, (byte) 0xFF };
 
+    private final byte[] teLspNlri = new byte[] { (byte) 0x00, (byte) 0x05, //NLRI Type Te-IPV4
+        (byte) 0x00, (byte) 0x12, // length
+        (byte) 0x06,    //Protocol-ID
+        (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, // Identifier
+        (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04, //IPv4 Tunnel Sender Address
+        (byte) 0x00, (byte) 0x01, //Tunnel ID
+        (byte) 0x00, (byte) 0x01, //LSP ID
+        (byte) 0x04, (byte) 0x03, (byte) 0x02, (byte) 0x01 }; // IPv4 Tunnel End-point Address
+
     private CLinkstateDestination dest;
 
     private void setUp(final byte[] data) throws BGPParsingException {
@@ -473,6 +488,77 @@ public class LinkstateNlriParserTest {
         assertEquals(this.dest, LinkstateNlriParser.extractLinkstateDestination(linkstateBI.build()));
     }
 
+    @Test
+    public void testTELspNlri() throws BGPParsingException {
+        setUp(this.teLspNlri);
+        // test BA form
+        assertNull(this.dest.getDistinguisher());
+        assertEquals(ProtocolId.RsvpTe, this.dest.getProtocolId());
+        assertEquals(BigInteger.ONE, this.dest.getIdentifier().getValue());
+        final TeLspCase teCase = ((TeLspCase) this.dest.getObjectType());
+
+        assertEquals(new LspId(1L), teCase.getLspId());
+        assertEquals(new TunnelId(1), teCase.getTunnelId());
+        assertEquals(new Ipv4Address("1.2.3.4"), ((Ipv4Case) teCase.getAddressFamily()).getIpv4TunnelSenderAddress());
+        assertEquals(new Ipv4Address("4.3.2.1"), ((Ipv4Case) teCase.getAddressFamily()).getIpv4TunnelEndpointAddress());
+
+        // test BI form
+        final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, UnkeyedListEntryNode> linkstateBI = ImmutableUnkeyedListEntryNodeBuilder.create();
+        linkstateBI.withNodeIdentifier(C_LINKSTATE_NID);
+
+        final ImmutableLeafNodeBuilder<String> protocolId = new ImmutableLeafNodeBuilder<>();
+        protocolId.withNodeIdentifier(LinkstateNlriParser.PROTOCOL_ID_NID);
+        protocolId.withValue("rsvpte");
+        linkstateBI.addChild(protocolId.build());
+
+        final ImmutableLeafNodeBuilder<BigInteger> identifier = new ImmutableLeafNodeBuilder<>();
+        identifier.withNodeIdentifier(LinkstateNlriParser.IDENTIFIER_NID);
+        identifier.withValue(BigInteger.ONE);
+        linkstateBI.addChild(identifier.build());
+
+        final DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> objectType = Builders.choiceBuilder();
+        objectType.withNodeIdentifier(LinkstateNlriParser.OBJECT_TYPE_NID);
+
+        // advertising node descriptors
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> teLspCase = Builders.containerBuilder();
+        teLspCase.withNodeIdentifier(LinkstateNlriParser.TE_LSP_NID);
+        objectType.addChild(teLspCase.build());
+
+        final ImmutableLeafNodeBuilder<Long> lspId = new ImmutableLeafNodeBuilder<>();
+        lspId.withNodeIdentifier(TeLspNlriParser.LSP_ID);
+        lspId.withValue(1L);
+
+        final ImmutableLeafNodeBuilder<Integer> tunnelId = new ImmutableLeafNodeBuilder<>();
+        tunnelId.withNodeIdentifier(TeLspNlriParser.TUNNEL_ID);
+        tunnelId.withValue(1);
+
+        final DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> addressFamily = Builders.choiceBuilder();
+        addressFamily.withNodeIdentifier(TeLspNlriParser.ADDRESS_FAMILY);
+
+        final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> ipv4Case = Builders.containerBuilder();
+        ipv4Case.withNodeIdentifier(TeLspNlriParser.IPV4_CASE);
+
+        final ImmutableLeafNodeBuilder<String> ipv4TunnelSenderAddress = new ImmutableLeafNodeBuilder<>();
+        ipv4TunnelSenderAddress.withNodeIdentifier(TeLspNlriParser.IPV4_TUNNEL_SENDER_ADDRESS);
+        ipv4TunnelSenderAddress.withValue("1.2.3.4");
+
+        final ImmutableLeafNodeBuilder<String> ipv4TunnelEndPointAddress = new ImmutableLeafNodeBuilder<>();
+        ipv4TunnelEndPointAddress.withNodeIdentifier(TeLspNlriParser.IPV4_TUNNEL_ENDPOINT_ADDRESS);
+        ipv4TunnelEndPointAddress.withValue("4.3.2.1");
+
+        ipv4Case.addChild(ipv4TunnelSenderAddress.build());
+        ipv4Case.addChild(ipv4TunnelEndPointAddress.build());
+
+        addressFamily.addChild(ipv4Case.build());
+
+        teLspCase.addChild(lspId.build());
+        teLspCase.addChild(tunnelId.build());
+        teLspCase.addChild(addressFamily.build());
+
+        objectType.addChild(teLspCase.build());
+        linkstateBI.addChild(objectType.build());
+        assertEquals(this.dest, LinkstateNlriParser.extractLinkstateDestination(linkstateBI.build()));
+    }
     @Test
     public void testSerializeAttribute() throws BGPParsingException {
         final LinkstateNlriParser parser = new LinkstateNlriParser(true);
@@ -535,4 +621,15 @@ public class LinkstateNlriParserTest {
             throw e.getCause();
         }
     }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testTeLspNlriPrivateConstructor() throws Throwable {
+        final Constructor<TeLspNlriParser> c = TeLspNlriParser.class.getDeclaredConstructor();
+        c.setAccessible(true);
+        try {
+            c.newInstance();
+        } catch (final InvocationTargetException e) {
+            throw e.getCause();
+        }
+    }
 }
index 1834b00f49275465bf4199cd1d5d6228d9c28857..d593edfe30c20b60b51bf873fc1933141174ceaa 100644 (file)
                 <artifactId>protocol-framework</artifactId>
                 <version>${protocol-framework.version}</version>
             </dependency>
+
+            <!-- RSVP -->
+            <dependency>
+                <groupId>org.opendaylight.bgpcep</groupId>
+                <artifactId>features-rsvp</artifactId>
+                <version>${project.version}</version>
+                <scope>import</scope>
+                <type>pom</type>
+            </dependency>
         </dependencies>
     </dependencyManagement>
 
             <type>xml</type>
               <scope>runtime</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>features-rsvp</artifactId>
+            <classifier>features</classifier>
+            <type>xml</type>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>features-mdsal</artifactId>
           <groupId>${project.groupId}</groupId>
           <artifactId>rsvp-api</artifactId>
       </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>rsvp-spi</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>${project.groupId}</groupId>
+          <artifactId>rsvp-impl</artifactId>
+      </dependency>
       <dependency>
           <groupId>${project.groupId}</groupId>
           <artifactId>topology-api</artifactId>
index 1538a12a2d060f423687ef6596fb3a2e7d2b6e9f..609fcfc8efae06206fdc581533495d9d09d3934f 100644 (file)
@@ -18,6 +18,7 @@
     <repository>mvn:org.opendaylight.yangtools/features-yangtools/{{VERSION}}/xml/features</repository>
     <repository>mvn:org.opendaylight.tcpmd5/features-tcpmd5/{{VERSION}}/xml/features</repository>
     <repository>mvn:org.opendaylight.mdsal.model/features-mdsal-model/{{VERSION}}/xml/features</repository>
+    <repository>mvn:org.opendaylight.bgpcep/features-rsvp/{{VERSION}}/xml/features</repository>
 
 
     <feature name='odl-bgpcep-bgp-all' version='${project.version}'>
@@ -79,7 +80,7 @@
     <feature name='odl-bgpcep-bgp-linkstate' version='${project.version}'>
         <feature version='${project.version}'>odl-bgpcep-bgp-parser</feature>
         <feature version='${project.version}'>odl-bgpcep-bgp-rib-api</feature>
-        <bundle>mvn:org.opendaylight.bgpcep/rsvp-api/{{VERSION}}</bundle>
+        <feature version='${project.version}'>odl-bgpcep-rsvp</feature>
         <bundle>mvn:org.opendaylight.bgpcep/bgp-linkstate/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.bgpcep/bgp-bmp-api/{{VERSION}}</bundle>
     </feature>