Path Computation Server 12/87712/13
authorOlivier Dugeon <olivier.dugeon@orange.com>
Thu, 16 Jan 2020 14:53:43 +0000 (15:53 +0100)
committerOlivier Dugeon <olivier.dugeon@orange.com>
Wed, 26 Feb 2020 12:45:41 +0000 (13:45 +0100)
Initial commit of Path Computation Server.

This is the 3/3 Patch Set to provide Path Computation Element (PCE)
conform to RFC5440. This integrates the Graph model and Algorithms
features. Graph is fulfilled from BGP-LinkState if available otherwise
a graph must be provided.

Details information about how to use the PCE server will be provided
in docs/pcep/pcep-user-guide-pce-server.rst

JIRA: BGPCEP-858

Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
Change-Id: Ic0552b4c7ad856fe7a7cca214bbaf81f659d876c

32 files changed:
bgp/topology-provider/pom.xml
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/AbstractTopologyBuilder.java
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/LinkstateGraphBuilder.java [new file with mode: 0644]
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/config/LinkstateGraphProvider.java [new file with mode: 0644]
bgp/topology-provider/src/main/resources/OSGI-INF/blueprint/bgp-topology-provider.xml
features/algo/features-algo/pom.xml
features/bgp/odl-bgpcep-bgp-topology/pom.xml
features/pcep/features-pcep/pom.xml
features/pcep/odl-bgpcep-pcep-server-provider/pom.xml [new file with mode: 0644]
features/pcep/odl-bgpcep-pcep-server/pom.xml [new file with mode: 0644]
features/pcep/odl-bgpcep-pcep-topology-provider/pom.xml
features/pcep/pom.xml
features/pom.xml
pcep/pcep-artifacts/pom.xml
pcep/pom.xml
pcep/server/pom.xml [new file with mode: 0644]
pcep/server/server-api/pom.xml [new file with mode: 0644]
pcep/server/server-api/src/main/java/org/opendaylight/bgpcep/pcep/server/PathComputation.java [new file with mode: 0644]
pcep/server/server-api/src/main/java/org/opendaylight/bgpcep/pcep/server/PceServerProvider.java [new file with mode: 0644]
pcep/server/server-provider/pom.xml [new file with mode: 0644]
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/MessagesUtil.java [new file with mode: 0644]
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PathComputationImpl.java [new file with mode: 0644]
pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PceServerFactory.java [new file with mode: 0644]
pcep/server/server-provider/src/main/resources/OSGI-INF/blueprint/pce-server.xml [new file with mode: 0644]
pcep/topology/topology-provider/pom.xml
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderBean.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderDependencies.java
pcep/topology/topology-provider/src/main/resources/OSGI-INF/blueprint/pcep-topology.xml
pcep/topology/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractPCEPSessionTest.java
pom.xml

index fa94ae759de557a2b734c8b94076eaf7b26b78e0..3524f14e6c9563e7dc928ce9cae3d6893c0e242c 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>topology-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>graph-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>odl-uint24</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>concepts</artifactId>
index 8e0149c2c52a9acb53ea3e54ce026f52903d38b6..746f7f86a0fb965f15cde9fd986013f21b1bdc7c 100644 (file)
@@ -76,6 +76,7 @@ public abstract class AbstractTopologyBuilder<T extends Route> implements Cluste
     @GuardedBy("this")
     @VisibleForTesting
     protected int listenerScheduledRestartEnforceCounter = 0;
+    protected boolean networkTopologyTransaction = true;
 
     protected AbstractTopologyBuilder(final DataBroker dataProvider, final RibReference locRibReference,
             final TopologyId topologyId, final TopologyTypes types, final Class<? extends AddressFamily> afi,
@@ -164,56 +165,63 @@ public abstract class AbstractTopologyBuilder<T extends Route> implements Cluste
     @Override
     @SuppressWarnings("checkstyle:IllegalCatch")
     public synchronized void onDataTreeChanged(final Collection<DataTreeModification<T>> changes) {
-        if (this.closed.get()) {
-            LOG.trace("Transaction chain was already closed, skipping update.");
-            return;
-        }
-        // check if the transaction chain needed to be restarted due to a previous error
-        if (restartTransactionChainOnDemand()) {
-            LOG.debug("The data change {} is disregarded due to restart of listener {}", changes, this);
-            return;
-        }
-        final ReadWriteTransaction trans = this.chain.newReadWriteTransaction();
-        LOG.trace("Received data change {} event with transaction {}", changes, trans.getIdentifier());
-        final AtomicBoolean transactionInError = new AtomicBoolean(false);
-        for (final DataTreeModification<T> change : changes) {
-            try {
-                routeChanged(change, trans);
-            } catch (final RuntimeException exc) {
-                LOG.warn("Data change {} (transaction {}) was not completely propagated to listener {}", change,
-                        trans.getIdentifier(), this, exc);
-                // trans.cancel() is not supported by PingPongTransactionChain, so we just skip the problematic change
-                // trans.commit() must be called first to unlock the current transaction chain, to make the chain
-                // closable so we cannot exit the #onDataTreeChanged() yet
-                transactionInError.set(true);
-                break;
+        if (networkTopologyTransaction) {
+            if (this.closed.get()) {
+                LOG.trace("Transaction chain was already closed, skipping update.");
+                return;
             }
-        }
-        trans.commit().addCallback(new FutureCallback<CommitInfo>() {
-            @Override
-            public void onSuccess(final CommitInfo result) {
-                // as we are enforcing trans.commit(), in some cases the transaction execution actually could be
-                // successfully even when an exception is captured, thus #onTransactionChainFailed() never get invoked.
-                // Though the transaction chain remains usable,
-                // the data loss will not be able to be recovered. Thus we schedule a listener restart here
-                if (transactionInError.get()) {
-                    LOG.warn("Transaction {} committed successfully while exception captured. Rescheduling a restart"
-                            + " of listener {}", trans
-                        .getIdentifier(), AbstractTopologyBuilder.this);
-                    scheduleListenerRestart();
-                } else {
-                    LOG.trace("Transaction {} committed successfully", trans.getIdentifier());
+            // check if the transaction chain needed to be restarted due to a previous error
+            if (restartTransactionChainOnDemand()) {
+                LOG.debug("The data change {} is disregarded due to restart of listener {}", changes, this);
+                return;
+            }
+            final ReadWriteTransaction trans = this.chain.newReadWriteTransaction();
+            LOG.trace("Received data change {} event with transaction {}", changes, trans.getIdentifier());
+            final AtomicBoolean transactionInError = new AtomicBoolean(false);
+            for (final DataTreeModification<T> change : changes) {
+                try {
+                    routeChanged(change, trans);
+                } catch (final RuntimeException exc) {
+                    LOG.warn("Data change {} (transaction {}) was not completely propagated to listener {}", change,
+                            trans.getIdentifier(), this, exc);
+                    // trans.cancel() is not supported by PingPongTransactionChain, so we just skip the problematic
+                    // change.
+                    // trans.commit() must be called first to unlock the current transaction chain, to make the chain
+                    // closable so we cannot exit the #onDataTreeChanged() yet
+                    transactionInError.set(true);
+                    break;
                 }
             }
+            trans.commit().addCallback(new FutureCallback<CommitInfo>() {
+                @Override
+                public void onSuccess(final CommitInfo result) {
+                    // as we are enforcing trans.commit(), in some cases the transaction execution actually could be
+                    // successfully even when an exception is captured, thus #onTransactionChainFailed() never get
+                    // invoked. Though the transaction chain remains usable,
+                    // the data loss will not be able to be recovered. Thus we schedule a listener restart here
+                    if (transactionInError.get()) {
+                        LOG.warn("Transaction {} committed successfully while exception captured. Rescheduling a"
+                                + " restart of listener {}", trans
+                            .getIdentifier(), AbstractTopologyBuilder.this);
+                        scheduleListenerRestart();
+                    } else {
+                        LOG.trace("Transaction {} committed successfully", trans.getIdentifier());
+                    }
+                }
 
-            @Override
-            public void onFailure(final Throwable throwable) {
-                // we do nothing but print out the log. Transaction chain restart will be done in
-                // #onTransactionChainFailed()
-                LOG.error("Failed to propagate change (transaction {}) by listener {}", trans.getIdentifier(),
-                        AbstractTopologyBuilder.this, throwable);
+                @Override
+                public void onFailure(final Throwable throwable) {
+                    // we do nothing but print out the log. Transaction chain restart will be done in
+                    // #onTransactionChainFailed()
+                    LOG.error("Failed to propagate change (transaction {}) by listener {}", trans.getIdentifier(),
+                            AbstractTopologyBuilder.this, throwable);
+                }
+            }, MoreExecutors.directExecutor());
+        } else {
+            for (final DataTreeModification<T> change : changes) {
+                routeChanged(change, null);
             }
-        }, MoreExecutors.directExecutor());
+        }
     }
 
     @VisibleForTesting
diff --git a/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/LinkstateGraphBuilder.java b/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/LinkstateGraphBuilder.java
new file mode 100644 (file)
index 0000000..cc268d4
--- /dev/null
@@ -0,0 +1,685 @@
+/*
+ * Copyright (c) 2020 Orange. 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.bgpcep.bgp.topology.provider;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import java.math.BigDecimal;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.graph.ConnectedGraph;
+import org.opendaylight.graph.ConnectedGraphProvider;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
+import org.opendaylight.protocol.bgp.rib.RibReference;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateSubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.bgp.rib.rib.loc.rib.tables.routes.LinkstateRoutesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.ObjectType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.SrAdjIds;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.LinkCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.NodeCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.PrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.LinkDescriptors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.LinkStateAttribute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.LinkAttributesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.PrefixAttributesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.link.attributes._case.LinkAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.prefix.attributes._case.PrefixAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.LinkstateRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRoute;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.linkstate.route.Attributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.CRouterIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.IsisNodeCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.OspfNodeCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.adj.flags.flags.isis.adj.flags._case.IsisAdjFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.adj.flags.flags.ospf.adj.flags._case.OspfAdjFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.prefix.sid.tlv.flags.IsisPrefixFlagsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.LocalLabelCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.SidCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.DecimalBandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Delay;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Loss;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Vertex.VertexType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.EdgeAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.EdgeAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.MinMaxDelay;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.MinMaxDelayBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidthBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidthKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.Graph.DomainScope;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Edge;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.EdgeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.EdgeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.PrefixBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Vertex;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.vertex.SrgbBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.types.rev160524.TopologyTypes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.types.rev160524.TopologyTypes1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.types.rev160524.bgp.linkstate.topology.type.BgpLinkstateTopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.SrlgId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This Class build the Traffic Engineering Database as a Connected Graph
+ * suitable to be used latter by Path Computation algorithms to compute end to
+ * end path.
+ *
+ * @author Olivier Dugeon
+ * @author Philippe Niger
+ *
+ */
+
+public class LinkstateGraphBuilder extends AbstractTopologyBuilder<LinkstateRoute> {
+    private static final TopologyTypes LINKSTATE_TOPOLOGY_TYPE = new TopologyTypesBuilder().addAugmentation(
+            TopologyTypes1.class,
+            new TopologyTypes1Builder().setBgpLinkstateTopology(new BgpLinkstateTopologyBuilder().build()).build())
+            .build();
+
+    private static final String UNHANDLED_OBJECT_CLASS = "Unhandled object class {}";
+
+    private static final Logger LOG = LoggerFactory.getLogger(LinkstateGraphBuilder.class);
+
+    private ConnectedGraphProvider graphProvider;
+    private ConnectedGraph cgraph;
+
+    public LinkstateGraphBuilder(final DataBroker dataProvider, final RibReference locRibReference,
+            final TopologyId topologyId, ConnectedGraphProvider provider) {
+        super(dataProvider, locRibReference, topologyId, LINKSTATE_TOPOLOGY_TYPE, LinkstateAddressFamily.class,
+                LinkstateSubsequentAddressFamily.class);
+        this.graphProvider = requireNonNull(provider);
+        this.cgraph = provider.createConnectedGraph("ted://" + topologyId.getValue(),
+                DomainScope.IntraDomain);
+        /* LinkStateGraphBuilder doesn't write information in the Network Topology tree of the Data Store.
+         * This is performed by ConnectedGraphProvider which write element in Graph tree of the Data Store */
+        this.networkTopologyTransaction = false;
+        LOG.info("Started Traffic Engineering Graph Builder");
+    }
+
+    @VisibleForTesting
+    LinkstateGraphBuilder(final DataBroker dataProvider, final RibReference locRibReference,
+            final TopologyId topologyId, ConnectedGraphProvider provider, final long listenerResetLimitInMillsec,
+            final int listenerResetEnforceCounter) {
+        super(dataProvider, locRibReference, topologyId, LINKSTATE_TOPOLOGY_TYPE, LinkstateAddressFamily.class,
+                LinkstateSubsequentAddressFamily.class, listenerResetLimitInMillsec, listenerResetEnforceCounter);
+        this.graphProvider = requireNonNull(provider);
+        this.cgraph = provider.createConnectedGraph("ted://" + topologyId.getValue(),
+                DomainScope.IntraDomain);
+        /* LinkStateGraphBuilder doesn't write information in the Network Topology tree of the Data Store.
+         * This is performed by ConnectedGraphProvider which write element in Graph tree of the Data Store */
+        this.networkTopologyTransaction = false;
+        LOG.info("Started Traffic Engineering Graph Builder");
+    }
+
+    @Override
+    protected void createObject(final ReadWriteTransaction trans, final InstanceIdentifier<LinkstateRoute> id,
+            final LinkstateRoute value) {
+        final ObjectType t = value.getObjectType();
+        Preconditions.checkArgument(t != null, "Route %s value %s has null object type", id, value);
+
+        if (t instanceof LinkCase) {
+            createEdge(value, (LinkCase) t, value.getAttributes());
+        } else if (t instanceof NodeCase) {
+            createVertex(value, (NodeCase) t, value.getAttributes());
+        } else if (t instanceof PrefixCase) {
+            createPrefix(value, (PrefixCase) t, value.getAttributes());
+        } else {
+            LOG.debug(UNHANDLED_OBJECT_CLASS, t.implementedInterface());
+        }
+    }
+
+    /**
+     * Verify that mandatory information (Local & Remote Node and Link
+     * descriptors) are present in the link.
+     *
+     * @param linkCase  The Link part of the Linkstate route
+     *
+     * @return True if all information are present, false otherwise
+     */
+    private boolean checkLinkState(final LinkCase linkCase) {
+        if (linkCase.getLocalNodeDescriptors() == null || linkCase.getRemoteNodeDescriptors() == null) {
+            LOG.warn("Missing Local or Remote Node descriptor in link {}, skipping it", linkCase);
+            return false;
+        }
+        if (linkCase.getLinkDescriptors() == null) {
+            LOG.warn("Missing Link descriptor in link {}, skipping it", linkCase);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Get Link attributes from the Link State route.
+     *
+     * @param attributes  Link State Route Attributes
+     *
+     * @return Link Attributes
+     */
+    private LinkAttributes getLinkAttributes(final Attributes attributes) {
+        final LinkAttributes la;
+        final Attributes1 attr = attributes.augmentation(Attributes1.class);
+        if (attr != null) {
+            final LinkStateAttribute attrType = attr.getLinkStateAttribute();
+            if (attrType != null) {
+                la = ((LinkAttributesCase) attrType).getLinkAttributes();
+            } else {
+                return null;
+            }
+        } else {
+            return null;
+        }
+        return la;
+    }
+
+    /**
+     * Determine the Source Edge Key from the link descriptor.
+     * There is several case: IPv4, IPv6 address or Unnumbered Interface.
+     *
+     * @param linkCase The Link part of the Linkstate route
+     *
+     * @return Unique key
+     */
+    private Uint64 getEdgeId(LinkCase linkCase) {
+        long key = 0;
+        if (linkCase.getLinkDescriptors().getIpv4InterfaceAddress() != null) {
+            key = ipv4ToKey(linkCase.getLinkDescriptors().getIpv4InterfaceAddress().getValue());
+        }
+        if (linkCase.getLinkDescriptors().getIpv6InterfaceAddress() != null) {
+            key = ipv6ToKey(linkCase.getLinkDescriptors().getIpv6InterfaceAddress().getValue());
+        }
+        if (linkCase.getLinkDescriptors().getLinkLocalIdentifier() != null) {
+            key = linkCase.getLinkDescriptors().getLinkLocalIdentifier().longValue();
+        }
+        return Uint64.valueOf(key);
+    }
+
+    /**
+     * Create new Connected Edge in the Connected Graph.
+     *
+     * @param value       The complete Linkstate route information
+     * @param linkCase    The Link part of the Linkstate route
+     * @param attributes  The Link attributes
+     *
+     */
+    private void createEdge(final LinkstateRoute value, final LinkCase linkCase, final Attributes attributes) {
+        Preconditions.checkArgument(checkLinkState(linkCase), "Missing mandatory information in link {}", linkCase);
+
+        final LinkAttributes la = getLinkAttributes(attributes);
+        if (la == null) {
+            LOG.warn("Missing attributes in link {} route {}, skipping it", linkCase, value);
+            return;
+        }
+
+        /* Get Source and Destination Vertex from the graph */
+        Uint64 srcId = getVertexId(linkCase.getLocalNodeDescriptors().getCRouterIdentifier());
+        Uint64 dstId = getVertexId(linkCase.getRemoteNodeDescriptors().getCRouterIdentifier());
+        if (srcId == Uint64.ZERO || dstId == Uint64.ZERO) {
+            LOG.warn("Unable to get the Source or Destination Vertex Identifier from link {}, skipping it", linkCase);
+            return;
+        }
+
+        /* Get Source and Destination Key for the corresponding Edge */
+        Uint64 edgeId = getEdgeId(linkCase);
+        if (edgeId == Uint64.ZERO) {
+            LOG.warn("Unable to get the Edge Identifier from link {}, skipping it", linkCase);
+            return;
+        }
+
+        /* Add associated Edge */
+        Edge edge = new EdgeBuilder().setEdgeId(edgeId).setLocalVertexId(srcId).setRemoteVertexId(dstId)
+                .setName(srcId + " - " + dstId)
+                .setEdgeAttributes(createEdgeAttributes(la, linkCase.getLinkDescriptors())).build();
+
+        /*
+         * Add corresponding Prefix for the Local Address. Remote address will be added with the remote Edge */
+        PrefixBuilder prefBuilder = new PrefixBuilder().setVertexId(srcId);
+        if (edge.getEdgeAttributes().getLocalAddress().getIpv4Address() != null) {
+            prefBuilder.setPrefix(new IpPrefix(
+                    new Ipv4Prefix(edge.getEdgeAttributes().getLocalAddress().getIpv4Address().getValue() + "/32")));
+        }
+        if (edge.getEdgeAttributes().getLocalAddress().getIpv6Address() != null) {
+            prefBuilder.setPrefix(new IpPrefix(
+                    new Ipv6Prefix(edge.getEdgeAttributes().getLocalAddress().getIpv6Address().getValue() + "/128")));
+        }
+        Prefix prefix = prefBuilder.build();
+
+        /* Add the Edge in the Connected Graph */
+        LOG.info("Add Edge {} and associated Prefix {} in TED[{}]", edge.getName(), prefix.getPrefix(), cgraph);
+        cgraph.addEdge(edge);
+        cgraph.addPrefix(prefix);
+    }
+
+    /**
+     * Create Edge Attributes from Link attributes.
+     *
+     * @param la         Linkstate Attributes
+     * @param linkDesc   Linkstate Descriptors
+     *
+     * @return EdgeAttributes
+     */
+    private static final int MAX_PRIORITY = 8;
+
+    private EdgeAttributes createEdgeAttributes(LinkAttributes la, final LinkDescriptors linkDesc) {
+        EdgeAttributesBuilder builder = new EdgeAttributesBuilder();
+
+        if (linkDesc.getIpv4InterfaceAddress() != null) {
+            builder.setLocalAddress(new IpAddress(new Ipv4Address(linkDesc.getIpv4InterfaceAddress())));
+        }
+        if (linkDesc.getIpv6InterfaceAddress() != null) {
+            builder.setLocalAddress(new IpAddress(new Ipv6Address(linkDesc.getIpv6InterfaceAddress())));
+        }
+        if (linkDesc.getIpv4NeighborAddress() != null) {
+            builder.setRemoteAddress(new IpAddress(new Ipv4Address(linkDesc.getIpv4NeighborAddress())));
+        }
+        if (linkDesc.getIpv6NeighborAddress() != null) {
+            builder.setRemoteAddress(new IpAddress(new Ipv6Address(linkDesc.getIpv6NeighborAddress())));
+        }
+        if (linkDesc.getLinkLocalIdentifier() != null) {
+            builder.setLocalIdentifier(linkDesc.getLinkLocalIdentifier());
+        }
+        if (linkDesc.getLinkRemoteIdentifier() != null) {
+            builder.setRemoteIdentifier(linkDesc.getLinkRemoteIdentifier());
+        }
+        if (la.getMetric() != null) {
+            builder.setMetric(la.getMetric().getValue());
+        }
+        if (la.getTeMetric() != null) {
+            builder.setTeMetric(la.getTeMetric().getValue());
+        }
+        if (la.getMaxLinkBandwidth() != null) {
+            builder.setMaxLinkBandwidth(bandwithToDecimalBandwidth(la.getMaxLinkBandwidth()));
+        }
+        if (la.getMaxReservableBandwidth() != null) {
+            builder.setMaxResvLinkBandwidth(bandwithToDecimalBandwidth(la.getMaxReservableBandwidth()));
+        }
+        if (la.getUnreservedBandwidth() != null) {
+            int upperBound = Math.min(la.getUnreservedBandwidth().size(), MAX_PRIORITY);
+            final List<UnreservedBandwidth> unRsvBw = new ArrayList<>(upperBound);
+
+            for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120
+                    .UnreservedBandwidth bandwidth : la.getUnreservedBandwidth()) {
+                unRsvBw.add(new UnreservedBandwidthBuilder()
+                        .setBandwidth(bandwithToDecimalBandwidth(bandwidth.getBandwidth()))
+                        .withKey(new UnreservedBandwidthKey(bandwidth.getPriority())).build());
+            }
+            builder.setUnreservedBandwidth(unRsvBw);
+        }
+        if (la.getAdminGroup() != null) {
+            builder.setAdminGroup(la.getAdminGroup().getValue());
+        }
+        if (la.getLinkDelay() != null) {
+            builder.setDelay(new Delay(la.getLinkDelay().getValue()));
+        }
+        if (la.getLinkMinMaxDelay() != null && la.getLinkMinMaxDelay() != null) {
+            MinMaxDelay mmDelay = new MinMaxDelayBuilder()
+                    .setMaxDelay(new Delay(la.getLinkMinMaxDelay().getMaxDelay().getValue()))
+                    .setMinDelay(new Delay(la.getLinkMinMaxDelay().getMinDelay().getValue())).build();
+            builder.setMinMaxDelay(mmDelay);
+        }
+        if (la.getDelayVariation() != null) {
+            builder.setJitter(new Delay(la.getDelayVariation().getValue()));
+        }
+        if (la.getLinkLoss() != null) {
+            builder.setLoss(new Loss(la.getLinkLoss().getValue()));
+        }
+        if (la.getAvailableBandwidth() != null) {
+            builder.setAvailableBandwidth(bandwithToDecimalBandwidth(la.getAvailableBandwidth()));
+        }
+        if (la.getResidualBandwidth() != null) {
+            builder.setResidualBandwidth(bandwithToDecimalBandwidth(la.getResidualBandwidth()));
+        }
+        if (la.getUtilizedBandwidth() != null) {
+            builder.setUtilizedBandwidth(bandwithToDecimalBandwidth(la.getUtilizedBandwidth()));
+        }
+        if (la.getSharedRiskLinkGroups() != null) {
+            List<Uint32> srlgs = new ArrayList<Uint32>();
+            for (SrlgId srlg : la.getSharedRiskLinkGroups()) {
+                srlgs.add(srlg.getValue());
+            }
+            builder.setSrlgs(srlgs);
+        }
+        if (la.getSrAdjIds() != null) {
+            for (SrAdjIds adj : la.getSrAdjIds()) {
+                if (adj.getSidLabelIndex() instanceof LocalLabelCase) {
+                    boolean backup = false;
+                    if (adj.getFlags() instanceof OspfAdjFlags) {
+                        backup = ((OspfAdjFlags) adj.getFlags()).isBackup();
+                    }
+                    if (adj.getFlags() instanceof IsisAdjFlags) {
+                        backup = ((IsisAdjFlags) adj.getFlags()).isBackup();
+                    }
+                    if (!backup) {
+                        builder.setAdjSid(((LocalLabelCase) adj.getSidLabelIndex()).getLocalLabel().getValue());
+                    } else {
+                        builder.setBackupAdjSid(((LocalLabelCase) adj.getSidLabelIndex()).getLocalLabel().getValue());
+                    }
+                }
+            }
+        }
+        return builder.build();
+    }
+
+    /**
+     * Get Node Attributes from Link State Route attributes.
+     *
+     * @param attributes  The attribute part from the Link State route
+     *
+     * @return Node Attributes
+     */
+    private NodeAttributes getNodeAttributes(final Attributes attributes) {
+        final NodeAttributes na;
+        final Attributes1 attr = attributes.augmentation(Attributes1.class);
+        if (attr != null) {
+            final LinkStateAttribute attrType = attr.getLinkStateAttribute();
+            if (attrType != null) {
+                na = ((NodeAttributesCase) attrType).getNodeAttributes();
+            } else {
+                return null;
+            }
+        } else {
+            return null;
+        }
+        return na;
+    }
+
+    /**
+     * Create Vertex from the Node Attributes.
+     *
+     * @param na       Node Attributes
+     * @param cvertex  Connected Vertex associated to this Vertex
+     * @param as       As number
+     *
+     * @return New Vertex
+     */
+    private Vertex getVertex(NodeAttributes na, Uint64 id, int as) {
+        VertexBuilder builder = new VertexBuilder().setVertexId(id).setAsn(Uint32.valueOf(as));
+        if (na.getIpv4RouterId() != null) {
+            builder.setRouterId(new IpAddress(new Ipv4Address(na.getIpv4RouterId().getValue())));
+        }
+        if (na.getIpv6RouterId() != null) {
+            builder.setRouterId(new IpAddress(new Ipv6Address(na.getIpv6RouterId().getValue())));
+        }
+        /*
+         * Set Router Name with dynamic hostname (IS-IS) or IPv4 address in dot decimal format (OSPF)
+         */
+        if (na.getDynamicHostname() != null) {
+            builder.setName(na.getDynamicHostname());
+        } else {
+            int key = id.intValue();
+            builder.setName(
+                    ((key << 24) & 0xFF) + "." + ((key << 16) & 0xFF) + "." + ((key << 8) & 0xFF) + "." + (key & 0xFF));
+        }
+        if (na.getSrCapabilities() != null) {
+            builder.setSrgb(new SrgbBuilder()
+                    .setLowerBound(
+                            ((LocalLabelCase) na.getSrCapabilities().getSidLabelIndex()).getLocalLabel().getValue())
+                    .setRangeSize(na.getSrCapabilities().getRangeSize().getValue())
+                    .build());
+        }
+        if (na.getNodeFlags() != null) {
+            if (na.getNodeFlags().isAbr()) {
+                builder.setVertexType(VertexType.Abr);
+            }
+            if (na.getNodeFlags().isExternal()) {
+                builder.setVertexType(VertexType.AsbrOut);
+            }
+        } else {
+            builder.setVertexType(VertexType.Standard);
+        }
+        return builder.build();
+    }
+
+    /**
+     * Create new Connected Vertex in the Connected Graph.
+     *
+     * @param value       The complete Linkstate route information
+     * @param nodeCase    The node part of the Linkstate route
+     * @param attributes  The node attributes
+     */
+    private void createVertex(final LinkstateRoute value, final NodeCase nodeCase, final Attributes attributes) {
+        Preconditions.checkArgument(nodeCase != null, "Missing Node Case. Skip this Node");
+        Preconditions.checkArgument(nodeCase.getNodeDescriptors() != null, "Missing Node Descriptors. Skip this Node");
+
+        Uint64 vertexId = getVertexId(nodeCase.getNodeDescriptors().getCRouterIdentifier());
+        if (vertexId == Uint64.ZERO) {
+            LOG.warn("Unable to get Vertex Identifier from descriptor {}, skipping it", nodeCase.getNodeDescriptors());
+            return;
+        }
+
+        NodeAttributes na = getNodeAttributes(attributes);
+        if (na == null) {
+            LOG.warn("Missing attributes in node {} route {}, skipping it", nodeCase, value);
+            return;
+        }
+
+        int asNumber = 0;
+        if (nodeCase.getNodeDescriptors() != null) {
+            asNumber = nodeCase.getNodeDescriptors().getAsNumber().getValue().intValue();
+        }
+        Vertex vertex = getVertex(na, vertexId, asNumber);
+
+        /* Add the Connected Vertex and associated Vertex in the Graph */
+        LOG.info("Add Vertex {} in TED[{}]", vertex.getName(), cgraph);
+        cgraph.addVertex(vertex);
+    }
+
+    /**
+     * Create new Prefix in the Connected Graph.
+     *
+     * @param value       The complete Linkstate route information
+     * @param prefixCase  The Prefix part of the Linkstate route
+     * @param attributes  The Prefix attributes
+     */
+    private void createPrefix(final LinkstateRoute value, final PrefixCase prefixCase, final Attributes attributes) {
+        final IpPrefix ippfx = prefixCase.getPrefixDescriptors().getIpReachabilityInformation();
+        if (ippfx == null) {
+            LOG.warn("IP reachability not present in prefix {} route {}, skipping it", prefixCase, value);
+            return;
+        }
+
+        /* Verify that all mandatory information are present */
+        final PrefixAttributes pa;
+        final Attributes1 attr = attributes.augmentation(Attributes1.class);
+        if (attr != null) {
+            final LinkStateAttribute attrType = attr.getLinkStateAttribute();
+            if (attrType != null) {
+                pa = ((PrefixAttributesCase) attrType).getPrefixAttributes();
+            } else {
+                LOG.warn("Missing attribute type in IP {} prefix {} route {}, skipping it", ippfx, prefixCase, value);
+                return;
+            }
+        } else {
+            LOG.warn("Missing attributes in IP {} prefix {} route {}, skipping it", ippfx, prefixCase, value);
+            return;
+        }
+
+        /*
+         * Get Connected Vertex from Connected Graph corresponding to the
+         * Advertising Node Descriptor
+         */
+        Uint64 vertexId = getVertexId(prefixCase.getAdvertisingNodeDescriptors().getCRouterIdentifier());
+        if (vertexId == Uint64.ZERO) {
+            LOG.warn("Unable to get the Vertex Identifier from descriptor {}, skipping it",
+                    prefixCase.getAdvertisingNodeDescriptors());
+            return;
+        }
+
+        /* Create Prefix */
+        PrefixBuilder builder = new PrefixBuilder().setVertexId(vertexId);
+        if (pa.getSrPrefix() != null && pa.getSrPrefix().getSidLabelIndex() instanceof SidCase) {
+            builder.setPrefixSid(((SidCase) pa.getSrPrefix().getSidLabelIndex()).getSid());
+            if (pa.getSrPrefix().getFlags() instanceof IsisPrefixFlagsCase) {
+                builder.setNodeSid(
+                        ((IsisPrefixFlagsCase) pa.getSrPrefix().getFlags()).getIsisPrefixFlags().isNodeSid());
+            } else {
+                /*
+                 * Seems that OSPF Flags are not accessible. Assuming that the
+                 * Prefix is a Node SID
+                 */
+                builder.setNodeSid(true);
+            }
+        }
+        if (ippfx.getIpv4Prefix() != null) {
+            builder.setPrefix(new IpPrefix(ippfx.getIpv4Prefix()));
+        }
+        if (ippfx.getIpv6Prefix() != null) {
+            builder.setPrefix(new IpPrefix(ippfx.getIpv6Prefix()));
+        }
+        Prefix prefix = builder.build();
+
+        /* Add the Prefix to the Connected Vertex within the Connected Graph */
+        LOG.info("Add prefix {} in TED[{}]", builder.getPrefix(), cgraph);
+        cgraph.addPrefix(prefix);
+    }
+
+    @Override
+    protected void removeObject(final ReadWriteTransaction trans, final InstanceIdentifier<LinkstateRoute> id,
+            final LinkstateRoute value) {
+        if (value == null) {
+            LOG.error("Empty before-data received in delete data change notification for instance id {}", id);
+            return;
+        }
+
+        final ObjectType t = value.getObjectType();
+        if (t instanceof LinkCase) {
+            removeEdge((LinkCase) t);
+        } else if (t instanceof NodeCase) {
+            removeVertex((NodeCase) t);
+        } else if (t instanceof PrefixCase) {
+            removePrefix((PrefixCase) t);
+        } else {
+            LOG.debug(UNHANDLED_OBJECT_CLASS, t.implementedInterface());
+        }
+    }
+
+    private void removeEdge(LinkCase linkCase) {
+        /* Get Source and Destination Connected Vertex */
+        if (linkCase.getLinkDescriptors() == null) {
+            LOG.warn("Missing Link descriptor in link {}, skipping it", linkCase);
+            return;
+        }
+        EdgeKey edgeKey = new EdgeKey(getEdgeId(linkCase));
+        if ((edgeKey == null) || (edgeKey.getEdgeId() == Uint64.ZERO)) {
+            LOG.warn("Unable to get the Edge Key from link {}, skipping it", linkCase);
+            return;
+        }
+
+        LOG.info("Deleted Edge {} from TED[{}]", edgeKey, cgraph);
+        cgraph.deleteEdge(edgeKey);
+    }
+
+    private void removeVertex(NodeCase nodeCase) {
+        VertexKey vertexKey = new VertexKey(getVertexId(nodeCase.getNodeDescriptors().getCRouterIdentifier()));
+        if ((vertexKey == null) || (vertexKey.getVertexId() == Uint64.ZERO)) {
+            LOG.warn("Unable to get Vertex Key from descriptor {}, skipping it", nodeCase.getNodeDescriptors());
+            return;
+        }
+
+        LOG.info("Deleted Vertex {} in TED[{}]", vertexKey, cgraph);
+        cgraph.deleteVertex(vertexKey);
+    }
+
+    private void removePrefix(PrefixCase prefixCase) {
+        final IpPrefix ippfx = prefixCase.getPrefixDescriptors().getIpReachabilityInformation();
+        if (ippfx == null) {
+            LOG.warn("IP reachability not present in prefix {}, skipping it", prefixCase);
+            return;
+        }
+
+        LOG.info("Deleted prefix {} in TED[{}]", ippfx, cgraph);
+        cgraph.deletePrefix(ippfx);
+    }
+
+    /**
+     * Get Vertex in the Graph by the OSPF Router ID or IS-IS-System ID.
+     *
+     * @param routerID  The Router Identifier entry
+     *
+     * @return Vertex in the Connected Graph that corresponds to this Router ID. Vertex is created if not found.
+     */
+    private Uint64 getVertexId(CRouterIdentifier routerID) {
+        Long rid = 0L;
+
+        if (routerID instanceof IsisNodeCase) {
+            byte[] isoId = ((IsisNodeCase) routerID).getIsisNode().getIsoSystemId().getValue();
+            final byte[] convert =  {0, 0, isoId[0], isoId[1], isoId[2], isoId[3], isoId[4], isoId[5]};
+            rid = ByteBuffer.wrap(convert).getLong();
+        }
+        if (routerID instanceof OspfNodeCase) {
+            rid = ((OspfNodeCase) routerID).getOspfNode().getOspfRouterId().longValue();
+        }
+
+        LOG.debug("Get Vertex Identifier {}", rid);
+        return Uint64.valueOf(rid);
+    }
+
+    private DecimalBandwidth bandwithToDecimalBandwidth(Bandwidth bw) {
+        return new DecimalBandwidth(BigDecimal.valueOf(ByteBuffer.wrap(bw.getValue()).getFloat()));
+    }
+
+    private long ipv4ToKey(String str) {
+        byte[] ip;
+        try {
+            ip = ((Inet4Address) Inet4Address.getByName(str)).getAddress();
+        } catch (UnknownHostException e) {
+            return 0;
+        }
+        return (((0xFF & ip[0]) << 24) | ((0xFF & ip[1]) << 16) | ((0xFF & ip[2]) << 8) | (0xFF & ip[3]));
+    }
+
+    private Long ipv6ToKey(String str) {
+        byte[] ip;
+        try {
+            ip = ((Inet6Address) Inet6Address.getByName(str)).getAddress();
+        } catch (UnknownHostException e) {
+            return 0L;
+        }
+        /* Keep only the lower 64bits from the IP address */
+        byte[] lowerIP = {ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]};
+        return ByteBuffer.wrap(lowerIP).getLong();
+    }
+
+    @Override
+    protected InstanceIdentifier<LinkstateRoute> getRouteWildcard(final InstanceIdentifier<Tables> tablesId) {
+        return tablesId.child(LinkstateRoutesCase.class, LinkstateRoutes.class).child(LinkstateRoute.class);
+    }
+
+    @Override
+    protected void clearTopology() {
+        cgraph.clear();
+    }
+
+}
diff --git a/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/config/LinkstateGraphProvider.java b/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/bgp/topology/provider/config/LinkstateGraphProvider.java
new file mode 100644 (file)
index 0000000..1d1e3a0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2020 Orange. 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.bgpcep.bgp.topology.provider.config;
+
+import org.opendaylight.bgpcep.bgp.topology.provider.AbstractTopologyBuilder;
+import org.opendaylight.bgpcep.bgp.topology.provider.LinkstateGraphBuilder;
+import org.opendaylight.bgpcep.bgp.topology.provider.spi.BgpTopologyDeployer;
+import org.opendaylight.graph.ConnectedGraphProvider;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.protocol.bgp.rib.RibReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.types.rev160524.TopologyTypes1;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+
+public final class LinkstateGraphProvider extends AbstractBgpTopologyProvider {
+
+    ConnectedGraphProvider graphProvider;
+
+    public LinkstateGraphProvider(final BgpTopologyDeployer deployer, final ConnectedGraphProvider graphProvider) {
+        super(deployer);
+        this.graphProvider = graphProvider;
+    }
+
+    @Override
+    AbstractTopologyBuilder<?> createTopologyBuilder(final DataBroker dataProvider, final RibReference locRibReference,
+            final TopologyId topologyId) {
+        return new LinkstateGraphBuilder(dataProvider, locRibReference, topologyId, this.graphProvider);
+    }
+
+    @Override
+    public boolean topologyTypeFilter(final Topology topology) {
+        final TopologyTypes1 topoAug = getTopologyAug(topology);
+        return topoAug != null && topoAug.getBgpLinkstateTopology() != null;
+    }
+}
index d98416b4488dfa0c76f2c447896306bc13ca5589..85a96dbc4ed56bf4f76b458c2831838cf9b7b24d 100644 (file)
   <bean id="linkstateTopologyProvider" class="org.opendaylight.bgpcep.bgp.topology.provider.config.LinkstateTopologyProvider" destroy-method="close">
     <argument ref="bgpTopologyDeployer"/>
   </bean>
+
+  <reference id="connectedGraphProvider" interface="org.opendaylight.graph.ConnectedGraphProvider"/>
+  <bean id="linkstateGraphProvider" class="org.opendaylight.bgpcep.bgp.topology.provider.config.LinkstateGraphProvider" destroy-method="close">
+    <argument ref="bgpTopologyDeployer"/>
+    <argument ref="connectedGraphProvider"/>
+  </bean>
 </blueprint>
index b859177d91f443f2608856bcac909de2eafe7493..8ad966221c4988cd50f9becca9903585dfa9b08a 100644 (file)
     <dependencies>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>odl-bgpcep-algo</artifactId>
+            <artifactId>odl-bgpcep-algo-api</artifactId>
             <type>xml</type>
             <classifier>features</classifier>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
-            <artifactId>odl-bgpcep-algo-api</artifactId>
+            <artifactId>odl-bgpcep-algo</artifactId>
             <type>xml</type>
             <classifier>features</classifier>
         </dependency>
index 46db6c5e9c50096e252c92231a16f9f59306e45a..f847a6de8da7b355810400ecb43110bab3a9cc28 100644 (file)
             <type>xml</type>
             <classifier>features</classifier>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl-bgpcep-graph</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.mdsal.model</groupId>
             <artifactId>odl-mdsal-model-draft-clemm-netmod-yang-network-topo-01</artifactId>
index a3157b51ce45d7a5d97f8a027553fc698401e8dd..fbf5d7b080d4897c705200fbcccd0f4133e50fd3 100644 (file)
             <type>xml</type>
             <classifier>features</classifier>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl-bgpcep-pcep-server</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>odl-bgpcep-pcep-topology</artifactId>
             <type>xml</type>
             <classifier>features</classifier>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl-bgpcep-pcep-server-provider</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>odl-bgpcep-pcep-p2mp-te-lsp</artifactId>
diff --git a/features/pcep/odl-bgpcep-pcep-server-provider/pom.xml b/features/pcep/odl-bgpcep-pcep-server-provider/pom.xml
new file mode 100644 (file)
index 0000000..d774ecc
--- /dev/null
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2020 Orange.  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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.bgpcep</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>0.14.0-SNAPSHOT</version>
+        <relativePath>../../../single-feature-parent</relativePath>
+    </parent>
+
+    <artifactId>odl-bgpcep-pcep-server-provider</artifactId>
+    <packaging>feature</packaging>
+
+    <name>OpenDaylight :: PCEP :: PCE Server Provider</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>pcep-server-provider</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl-bgpcep-pcep-server</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl-bgpcep-algo</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/features/pcep/odl-bgpcep-pcep-server/pom.xml b/features/pcep/odl-bgpcep-pcep-server/pom.xml
new file mode 100644 (file)
index 0000000..e69d9ea
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2020 Orange.  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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.bgpcep</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>0.14.0-SNAPSHOT</version>
+        <relativePath>../../../single-feature-parent</relativePath>
+    </parent>
+
+    <artifactId>odl-bgpcep-pcep-server</artifactId>
+    <packaging>feature</packaging>
+
+    <name>OpenDaylight :: PCEP :: PCE Server API</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>pcep-server-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl-bgpcep-algo-api</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+    </dependencies>
+</project>
index 16c9aee524ae02c66f7a7aada0b908c7e88a5f58..65a603c6694b9fc1d400d7b1815f3a381262e59e 100644 (file)
             <type>xml</type>
             <classifier>features</classifier>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>odl-bgpcep-pcep-server-provider</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.mdsal</groupId>
             <artifactId>odl-mdsal-dom-broker</artifactId>
index 7c128fcf706470d9354c27c8b3a4f0cd399e3fce..743df9beff50ec5bd709f2f9871354d4ffd1fcb0 100644 (file)
         <module>odl-bgpcep-pcep-impl</module>
         <module>odl-bgpcep-programming-api</module>
         <module>odl-bgpcep-programming-impl</module>
+        <module>odl-bgpcep-pcep-server</module>
         <module>odl-bgpcep-pcep-topology</module>
         <module>odl-bgpcep-pcep-stateful07</module>
+        <module>odl-bgpcep-pcep-server-provider</module>
         <module>odl-bgpcep-pcep-topology-provider</module>
         <module>odl-bgpcep-pcep-tunnel-provider</module>
         <module>odl-bgpcep-pcep-segment-routing</module>
index a37209546fce48f475d07af979209e53fe1b728e..a1faa69cad3189027af34acdfd4bbda2305a3cb3 100644 (file)
     <packaging>pom</packaging>
 
     <modules>
-        <module>bgp</module>
-        <module>pcep</module>
         <module>graph</module>
+        <module>bgp</module>
         <module>algo</module>
+        <module>pcep</module>
         <module>bgpcep-extras</module>
         <module>bmp</module>
         <module>rsvp</module>
index fd3d4a70988f71109b0a08a3537d5812fadfd104..efe76288e464666521664868b3b87108f3c613c8 100644 (file)
                 <artifactId>pcep-segment-routing</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>pcep-server-api</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>pcep-server-provider</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>pcep-topology-api</artifactId>
                 <type>xml</type>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>odl-bgpcep-pcep-server</artifactId>
+                <classifier>features</classifier>
+                <type>xml</type>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>odl-bgpcep-pcep-topology</artifactId>
                 <type>xml</type>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>odl-bgpcep-pcep-server-provider</artifactId>
+                <classifier>features</classifier>
+                <type>xml</type>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>odl-bgpcep-pcep-topology-provider</artifactId>
index afa4aa2779de398064a8a15546ddc06fda06b4ce..6c2856711c0b23d9b7c37ec1b2071577b9659cc2 100644 (file)
@@ -32,6 +32,7 @@
         <module>ietf-stateful07</module>
         <module>ietf-p2mp-te-lsp</module>
         <module>testtool</module>
+        <module>server</module>
         <module>topology</module>
         <module>segment-routing</module>
         <module>pcc-mock</module>
diff --git a/pcep/server/pom.xml b/pcep/server/pom.xml
new file mode 100644 (file)
index 0000000..62df503
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2020 Orange. 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>odlparent-lite</artifactId>
+        <version>6.0.4</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.opendaylight.bgpcep</groupId>
+    <artifactId>pcep-server-parent</artifactId>
+    <version>0.14.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <description>Path Computation Element Server</description>
+    <name>${project.artifactId}</name>
+
+    <modules>
+        <module>server-api</module>
+        <module>server-provider</module>
+    </modules>
+
+    <properties>
+        <maven.deploy.skip>true</maven.deploy.skip>
+        <maven.install.skip>true</maven.install.skip>
+    </properties>
+</project>
diff --git a/pcep/server/server-api/pom.xml b/pcep/server/server-api/pom.xml
new file mode 100644 (file)
index 0000000..4e17c80
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+  Copyright (c) 2019 Orange Labs. 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.bgpcep</groupId>
+        <artifactId>binding-parent</artifactId>
+        <version>0.14.0-SNAPSHOT</version>
+        <relativePath>../../../binding-parent</relativePath>
+    </parent>
+
+    <artifactId>pcep-server-api</artifactId>
+    <description>Path Computation Server API</description>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>pcep-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>graph-api</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/pcep/server/server-api/src/main/java/org/opendaylight/bgpcep/pcep/server/PathComputation.java b/pcep/server/server-api/src/main/java/org/opendaylight/bgpcep/pcep/server/PathComputation.java
new file mode 100644 (file)
index 0000000..ad8e761
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2020 Orange. 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.bgpcep.pcep.server;
+
+import java.util.List;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.Bandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.classtype.object.ClassType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.object.EndpointsObj;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.Requests;
+
+public interface PathComputation {
+
+    Message computePath(Requests req);
+
+    Ero computeEro(EndpointsObj endpoints, Bandwidth bandwidth, ClassType classType, List<Metrics> metrics,
+            boolean segmentRouting);
+
+}
diff --git a/pcep/server/server-api/src/main/java/org/opendaylight/bgpcep/pcep/server/PceServerProvider.java b/pcep/server/server-api/src/main/java/org/opendaylight/bgpcep/pcep/server/PceServerProvider.java
new file mode 100644 (file)
index 0000000..ee856c6
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2020 Orange. 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.bgpcep.pcep.server;
+
+import org.opendaylight.graph.ConnectedGraph;
+
+public interface PceServerProvider {
+
+    PathComputation getPathComputation();
+
+    ConnectedGraph getTedGraph();
+}
diff --git a/pcep/server/server-provider/pom.xml b/pcep/server/server-provider/pom.xml
new file mode 100644 (file)
index 0000000..2dcf643
--- /dev/null
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2019 Orange Labs 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
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.bgpcep</groupId>
+        <artifactId>bgpcep-parent</artifactId>
+        <version>0.14.0-SNAPSHOT</version>
+        <relativePath>../../../parent</relativePath>
+    </parent>
+
+    <artifactId>pcep-server-provider</artifactId>
+    <description>PCE Server Provider</description>
+    <packaging>bundle</packaging>
+    <name>${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>pcep-server-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>graph-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>algo-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>concepts</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>pcep-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>pcep-spi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>pcep-segment-routing</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>rsvp-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.binding.model.ietf</groupId>
+            <artifactId>rfc6991-ietf-inet-types</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/MessagesUtil.java b/pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/MessagesUtil.java
new file mode 100644 (file)
index 0000000..1bd4446
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2020 Orange.  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.bgpcep.pcep.server.provider;
+
+import com.google.common.collect.Lists;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+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.network.concepts.rev131125.Bandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.path.descriptions.PathDescription;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcerr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcerrBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcrep;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.PcrepBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.SidType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.pcrep.pcrep.message.replies.result.success._case.success.paths.ero.subobject.subobject.type.SrEroType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.pcrep.pcrep.message.replies.result.success._case.success.paths.ero.subobject.subobject.type.SrEroTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.segment.routing.rev181109.sr.subobject.nai.IpNodeIdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.NoPathVectorTlv.Flags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.RequestId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.BandwidthBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.classtype.object.ClassTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.EroBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.ero.Subobject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.ero.SubobjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.MetricsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.metric.object.MetricBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcep.error.object.ErrorObjectBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.PcerrMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.ErrorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.RequestCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.request._case.RequestBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcerr.message.pcerr.message.error.type.request._case.request.RpsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.PcrepMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.RepliesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.FailureCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.SuccessCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.failure._case.NoPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.failure._case.no.path.TlvsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.failure._case.no.path.tlvs.NoPathVectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.SuccessBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.success.Paths;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcrep.message.pcrep.message.replies.result.success._case.success.PathsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.P2p;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.Rp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.rp.object.RpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint8;
+
+public final class MessagesUtil {
+
+    public static final byte NO_PATH = 0x0;
+    public static final byte UNKNOWN_SOURCE = 0x1;
+    public static final byte UNKNOWN_DESTINATION = 0x0;
+
+    /*
+     * See
+     * https://www.iana.org/assignments/pcep/pcep.xhtml#metric-object-ni-field
+     */
+    public static final int IGP_METRIC = 1;
+    public static final int TE_METRIC = 2;
+    public static final int PATH_DELAY = 12;
+
+    private MessagesUtil() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static Ero getEro(List<PathDescription> pathDescriptions) {
+        /* Prepare ERO */
+        final EroBuilder eroBuilder = new EroBuilder();
+        eroBuilder.setIgnore(false);
+        eroBuilder.setProcessingRule(true);
+        final List<Subobject> eroSubs = new ArrayList<>();
+
+        /* Fulfill ERO sublist */
+        for (PathDescription path : pathDescriptions) {
+            Subobject sb = null;
+            if (path.getLabel() == null) {
+                IpPrefix ipPref = null;
+                /* Prepare SubObject for IPv4 or IPv6 address */
+                if (path.getIpv4() != null) {
+                    final Ipv4Prefix ipv4Pref = new Ipv4Prefix(path.getIpv4().getValue() + "/32");
+                    ipPref = new IpPrefixBuilder().setIpPrefix(
+                            new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715
+                                    .IpPrefix(ipv4Pref))
+                            .build();
+                }
+                if (path.getIpv6() != null) {
+                    final Ipv6Prefix ipv6Pref = new Ipv6Prefix(path.getIpv6().getValue() + "/128");
+                    ipPref = new IpPrefixBuilder().setIpPrefix(
+                            new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715
+                                    .IpPrefix(ipv6Pref))
+                            .build();
+                }
+                if (ipPref != null) {
+                    final IpPrefixCase ipPrefCase = new IpPrefixCaseBuilder().setIpPrefix(ipPref).build();
+                    sb = new SubobjectBuilder().setSubobjectType(ipPrefCase).setLoose(false).build();
+                }
+            } else {
+                /* Prepare SubObject for Segment Routing */
+                SrEroType srEro = null;
+                if (path.getIpv4() != null) {
+                    srEro = new SrEroTypeBuilder()
+                            .setSidType(SidType.Ipv4NodeId)
+                            .setSid(path.getLabel().getValue())
+                            .setCFlag(false)
+                            .setMFlag(false)
+                            .setNai(new IpNodeIdBuilder()
+                                    .setIpAddress(new IpAddressNoZone(new Ipv4AddressNoZone(path.getIpv4().getValue())))
+                                    .build())
+                            .build();
+                }
+                if (path.getIpv6() != null) {
+                    srEro = new SrEroTypeBuilder()
+                            .setSidType(SidType.Ipv6NodeId)
+                            .setSid(path.getLabel().getValue())
+                            .setCFlag(false)
+                            .setMFlag(false)
+                            .setNai(new IpNodeIdBuilder()
+                                    .setIpAddress(new IpAddressNoZone(new Ipv6AddressNoZone(path.getIpv6().getValue())))
+                                    .build())
+                            .build();
+                }
+                if (srEro != null) {
+                    sb = new SubobjectBuilder().setSubobjectType(srEro).setLoose(false).build();
+                }
+            }
+
+            /* Add corresponding SubObject to the ERO List */
+            if (sb != null) {
+                eroSubs.add(sb);
+            }
+        }
+        /* Set ERO sublist */
+        eroBuilder.setSubobject(eroSubs);
+
+        return eroBuilder.build();
+    }
+
+    private static PathsBuilder buildPath(ConstrainedPath cpath) {
+        final PathsBuilder pathBuilder = new PathsBuilder();
+
+        /* Get ERO from Path Description */
+        pathBuilder.setEro(getEro(cpath.getPathDescription()));
+
+        /* Fulfill Computed Metrics if available */
+        final ArrayList<Metrics> metrics = new ArrayList<Metrics>();
+        if (cpath.getMetric() != null) {
+            final MetricBuilder metricBuilder = new MetricBuilder().setComputed(true)
+                    .setMetricType(Uint8.valueOf(IGP_METRIC)).setValue(new Float32(
+                            ByteBuffer.allocate(4).putFloat(Float.valueOf(cpath.getMetric().floatValue())).array()));
+            metrics.add(new MetricsBuilder().setMetric(metricBuilder.build()).build());
+        }
+        if (cpath.getTeMetric() != null) {
+            final MetricBuilder metricBuilder = new MetricBuilder().setComputed(true)
+                    .setMetricType(Uint8.valueOf(TE_METRIC)).setValue(new Float32(
+                            ByteBuffer.allocate(4).putFloat(Float.valueOf(cpath.getTeMetric().floatValue())).array()));
+            metrics.add(new MetricsBuilder().setMetric(metricBuilder.build()).build());
+        }
+        if (cpath.getDelay() != null) {
+            final MetricBuilder metricBuilder = new MetricBuilder().setComputed(true)
+                    .setMetricType(Uint8.valueOf(PATH_DELAY)).setValue(new Float32(ByteBuffer.allocate(4)
+                            .putFloat(Float.valueOf(cpath.getDelay().getValue().floatValue())).array()));
+            metrics.add(new MetricsBuilder().setMetric(metricBuilder.build()).build());
+        }
+        if (!metrics.isEmpty()) {
+            pathBuilder.setMetrics(metrics);
+        }
+        /* Fulfill Bandwidth and ClassType if set */
+        if (cpath.getBandwidth() != null) {
+            final BandwidthBuilder bwBuilder = new BandwidthBuilder();
+            bwBuilder.setBandwidth(new Bandwidth(new Float32(ByteBuffer.allocate(4)
+                    .putFloat(Float.valueOf(cpath.getBandwidth().getValue().floatValue())).array())));
+            pathBuilder.setBandwidth(bwBuilder.build());
+            if (cpath.getClassType() != null) {
+                pathBuilder.setClassType(new ClassTypeBuilder().setClassType(
+                        new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109
+                                .ClassType(cpath.getClassType()))
+                        .build());
+            }
+        }
+        return pathBuilder;
+    }
+
+    public static Pcrep createPcRepMessage(Rp rp, P2p p2p, ConstrainedPath cpath) {
+
+        /* Prepare Path Object with ERO and Object from the Request */
+        final ArrayList<Paths> paths = new ArrayList<Paths>();
+        PathsBuilder pathBuilder = buildPath(cpath);
+
+        if (p2p.getLspa() != null) {
+            pathBuilder.setLspa(p2p.getLspa());
+        }
+        if (p2p.getIro() != null) {
+            pathBuilder.setIro(p2p.getIro());
+        }
+        if (p2p.getXro() != null) {
+            pathBuilder.setXro(p2p.getXro());
+        }
+        paths.add(pathBuilder.build());
+
+        /* Prepare Reply with Path Object */
+        final RepliesBuilder replyBuilder = new RepliesBuilder()
+                .setRp(rp)
+                .setResult(new SuccessCaseBuilder().setSuccess(new SuccessBuilder().setPaths(paths).build()).build());
+
+        /* Prepare PcRep Message */
+        final PcrepMessageBuilder msgBuilder = new PcrepMessageBuilder()
+                .setReplies(Lists.newArrayList(replyBuilder.build()));
+        return new PcrepBuilder().setPcrepMessage(msgBuilder.build()).build();
+    }
+
+    public static Pcrep createNoPathMessage(Rp rp, byte reason) {
+
+        /* Prepare NoPath Object */
+        final Flags flags = new Flags(false, false, false, false, false, false,
+                (reason == UNKNOWN_DESTINATION) ? true : false, (reason == UNKNOWN_SOURCE) ? true : false);
+        final NoPathVectorBuilder npvBuilder = new NoPathVectorBuilder().setFlags(flags);
+        final TlvsBuilder tlvsBuilder = new TlvsBuilder().setNoPathVector(npvBuilder.build());
+        final NoPathBuilder npBuilder = new NoPathBuilder()
+                .setProcessingRule(false)
+                .setIgnore(false)
+                .setNatureOfIssue(Uint8.ZERO)
+                .setUnsatisfiedConstraints(true)
+                .setTlvs(tlvsBuilder.build());
+
+        /* Prepare Reply */
+        final RepliesBuilder replyBuilder = new RepliesBuilder()
+                .setRp(rp)
+                .setResult(new FailureCaseBuilder().setNoPath(npBuilder.build()).build());
+
+        /* Prepare PcRep Message */
+        final PcrepMessageBuilder msgBuilder = new PcrepMessageBuilder()
+                .setReplies(Lists.newArrayList(replyBuilder.build()));
+        return new PcrepBuilder().setPcrepMessage(msgBuilder.build()).build();
+    }
+
+    public static Pcerr createErrorMsg(@NonNull final PCEPErrors pcepErrors, final Uint32 reqID) {
+        final PcerrMessageBuilder msgBuilder = new PcerrMessageBuilder();
+        return new PcerrBuilder().setPcerrMessage(msgBuilder
+                .setErrorType(
+                        new RequestCaseBuilder().setRequest(new RequestBuilder()
+                                .setRps(Lists
+                                        .newArrayList(new RpsBuilder().setRp(new RpBuilder().setProcessingRule(false)
+                                                .setIgnore(false).setRequestId(new RequestId(reqID)).build()).build()))
+                                .build()).build())
+                .setErrors(Collections.singletonList(new ErrorsBuilder().setErrorObject(new ErrorObjectBuilder()
+                        .setType(pcepErrors.getErrorType()).setValue(pcepErrors.getErrorValue()).build()).build()))
+                .build()).build();
+    }
+
+}
diff --git a/pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PathComputationImpl.java b/pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PathComputationImpl.java
new file mode 100644 (file)
index 0000000..af094ec
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2020 Orange. 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.bgpcep.pcep.server.provider;
+
+import com.google.common.base.Preconditions;
+import java.math.BigDecimal;
+import java.nio.ByteBuffer;
+import java.util.List;
+import org.opendaylight.algo.PathComputationAlgorithm;
+import org.opendaylight.algo.PathComputationProvider;
+import org.opendaylight.bgpcep.pcep.server.PathComputation;
+import org.opendaylight.graph.ConnectedGraph;
+import org.opendaylight.graph.ConnectedVertex;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.protocol.pcep.spi.PSTUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.DecimalBandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Delay;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.AlgorithmType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ComputationStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ConstrainedPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.PathConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.PathConstraints.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.get.constrained.path.input.ConstraintsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.bandwidth.object.Bandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.classtype.object.ClassType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv4Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv6Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.object.EndpointsObj;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.lsp.attributes.Metrics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.Requests;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq.message.requests.segment.computation.P2p;
+import org.opendaylight.yangtools.yang.common.Uint32;
+import org.opendaylight.yangtools.yang.common.Uint8;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PathComputationImpl implements PathComputation {
+
+    private static final Logger LOG = LoggerFactory.getLogger(PathComputationImpl.class);
+
+    private final ConnectedGraph tedGraph;
+    private final PathComputationProvider algoProvider;
+
+    public PathComputationImpl(ConnectedGraph tedGraph, PathComputationProvider algoProvider) {
+        Preconditions.checkArgument(tedGraph != null);
+        this.tedGraph = tedGraph;
+        this.algoProvider = algoProvider;
+    }
+
+    @Override
+    public Message computePath(Requests req) {
+        LOG.info("Received Compute Path request");
+
+        /* Check that Request Parameter Object is present */
+        if (req == null || req.getRp() == null) {
+            LOG.error("Missing Request Parameter Objects. Abort!");
+            return MessagesUtil.createErrorMsg(PCEPErrors.RP_MISSING, Uint32.ZERO);
+        }
+
+        LOG.debug("Request for path computation {}", req);
+
+        /*
+         * Check that mandatory End Point Objects are present and Source /
+         * Destination are know in the TED Graph
+         */
+        P2p input = req.getSegmentComputation().getP2p();
+        if (input == null || input.getEndpointsObj() == null) {
+            LOG.error("Missing End Point Objects. Abort!");
+            Uint32 reqID = req.getRp().getRequestId().getValue();
+            return MessagesUtil.createErrorMsg(PCEPErrors.END_POINTS_MISSING, reqID);
+        }
+        VertexKey source = getSourceVertexKey(input.getEndpointsObj());
+        VertexKey destination = getDestinationVertexKey(input.getEndpointsObj());
+        if (source == null) {
+            return MessagesUtil.createNoPathMessage(req.getRp(), MessagesUtil.UNKNOWN_SOURCE);
+        }
+        if (destination == null) {
+            return MessagesUtil.createNoPathMessage(req.getRp(), MessagesUtil.UNKNOWN_DESTINATION);
+        }
+
+        /* Create new Constraints Object from the request */
+        PathConstraints cts = getConstraints(input, !PSTUtil.isDefaultPST(req.getRp().getTlvs().getPathSetupType()));
+
+        /* Determine Path Computation Algorithm according to Input choice */
+        AlgorithmType algoType;
+        if ((cts.getTeMetric() == null) && (cts.getDelay() == null)) {
+            algoType = AlgorithmType.Spf;
+        } else if (cts.getDelay() == null) {
+            algoType = AlgorithmType.Cspf;
+        } else {
+            algoType = AlgorithmType.Samcra;
+        }
+        PathComputationAlgorithm algo = algoProvider.getPathComputationAlgorithm(tedGraph, algoType);
+        if (algo == null) {
+            return MessagesUtil.createErrorMsg(PCEPErrors.RESOURCE_LIMIT_EXCEEDED, Uint32.ZERO);
+        }
+
+        /* Request Path Computation for given source, destination and constraints */
+        LOG.debug("Call Path Computation {} algorithm for path from {} to {} with contraints {}",
+                algoType, source, destination, cts);
+        final ConstrainedPath cpath = algo.computeP2pPath(source, destination, cts);
+
+        LOG.info("Computed path: {}", cpath.getPathDescription());
+
+        /* Check if we got a valid Path and return appropriate message */
+        if (cpath.getStatus() == ComputationStatus.Completed) {
+            return MessagesUtil.createPcRepMessage(req.getRp(), req.getSegmentComputation().getP2p(), cpath);
+        } else {
+            return MessagesUtil.createNoPathMessage(req.getRp(), MessagesUtil.NO_PATH);
+        }
+    }
+
+    @Override
+    public Ero computeEro(EndpointsObj endpoints, Bandwidth bandwidth, ClassType classType, List<Metrics> metrics,
+            boolean segmentRouting) {
+        VertexKey source = getSourceVertexKey(endpoints);
+        VertexKey destination = getDestinationVertexKey(endpoints);
+        if (source == null) {
+            return null;
+        }
+        if (destination == null) {
+            return null;
+        }
+        /* Create new Constraints Object from the request */
+        PathConstraints cts = getConstraints(endpoints, bandwidth, classType, metrics, segmentRouting);
+
+        /* Determine Path Computation Algorithm according to parameters */
+        AlgorithmType algoType;
+        if ((cts.getTeMetric() == null) && (cts.getDelay() == null) && (cts.getBandwidth() == null)) {
+            algoType = AlgorithmType.Spf;
+        } else if (cts.getDelay() == null) {
+            algoType = AlgorithmType.Cspf;
+        } else {
+            algoType = AlgorithmType.Samcra;
+        }
+        PathComputationAlgorithm algo = algoProvider.getPathComputationAlgorithm(tedGraph, algoType);
+        if (algo == null) {
+            return null;
+        }
+
+        /*
+         * Request Path Computation for given source, destination and
+         * constraints
+         */
+        final ConstrainedPath cpath = algo.computeP2pPath(source, destination, cts);
+
+        LOG.info("Computed ERO: {}", cpath.getPathDescription());
+
+        /* Check if we got a valid Path and return appropriate ERO */
+        if (cpath.getStatus() == ComputationStatus.Completed) {
+            return MessagesUtil.getEro(cpath.getPathDescription());
+        } else {
+            return null;
+        }
+    }
+
+    private VertexKey getSourceVertexKey(EndpointsObj endPoints) {
+        IpAddress address = null;
+
+        if (endPoints.getAddressFamily() instanceof Ipv4Case) {
+            address = new IpAddress(((Ipv4Case) endPoints.getAddressFamily()).getIpv4().getSourceIpv4Address());
+        }
+        if (endPoints.getAddressFamily() instanceof Ipv6Case) {
+            address = new IpAddress(((Ipv6Case) endPoints.getAddressFamily()).getIpv6().getSourceIpv6Address());
+        }
+        if (address == null) {
+            return null;
+        }
+
+        ConnectedVertex vertex = tedGraph.getConnectedVertex(address);
+        LOG.debug("Compute path from Source {}", vertex.toString());
+        return (vertex != null) ? vertex.getVertex().key() : null;
+    }
+
+    private VertexKey getDestinationVertexKey(EndpointsObj endPoints) {
+        IpAddress address = null;
+
+        if (endPoints.getAddressFamily() instanceof Ipv4Case) {
+            address = new IpAddress(((Ipv4Case) endPoints.getAddressFamily()).getIpv4().getDestinationIpv4Address());
+        }
+        if (endPoints.getAddressFamily() instanceof Ipv6Case) {
+            address = new IpAddress(((Ipv6Case) endPoints.getAddressFamily()).getIpv6().getDestinationIpv6Address());
+        }
+        if (address == null) {
+            return null;
+        }
+
+        ConnectedVertex vertex = tedGraph.getConnectedVertex(address);
+        LOG.debug("Compute path to Destination {}", vertex.toString());
+        return (vertex != null) ? vertex.getVertex().key() : null;
+    }
+
+    private PathConstraints getConstraints(P2p parameters, boolean segmentRouting) {
+        return getConstraints(parameters.getEndpointsObj(), parameters.getBandwidth(), parameters.getClassType(),
+                parameters.getMetrics(), segmentRouting);
+    }
+
+    private PathConstraints getConstraints(EndpointsObj endpoints, Bandwidth bandwidth, ClassType classType,
+            List<Metrics> metrics, boolean segmentRouting) {
+        ConstraintsBuilder ctsBuilder = new ConstraintsBuilder();
+        Float convert;
+
+        /* Set Metrics if any */
+        if (metrics != null) {
+            for (Metrics metric : metrics) {
+                convert = ByteBuffer.wrap(metric.getMetric().getValue().getValue()).getFloat();
+                switch (metric.getMetric().getMetricType().intValue()) {
+                    case MessagesUtil.IGP_METRIC:
+                        ctsBuilder.setMetric(Uint32.valueOf(convert.longValue()));
+                        break;
+                    case MessagesUtil.TE_METRIC:
+                        ctsBuilder.setTeMetric(Uint32.valueOf(convert.longValue()));
+                        break;
+                    case MessagesUtil.PATH_DELAY:
+                        ctsBuilder.setDelay(new Delay(Uint32.valueOf(convert.longValue())));
+                        break;
+                    default:
+                        LOG.warn("Metric {} is not handle by Path Computation Constraints", metric);
+                        break;
+                }
+            }
+        }
+
+        /* Set Bandwidth and Class Type */
+        if (bandwidth != null) {
+            convert = ByteBuffer.wrap(bandwidth.getBandwidth().getValue()).getFloat();
+            ctsBuilder.setBandwidth(new DecimalBandwidth(BigDecimal.valueOf(convert.longValue())));
+            if (classType != null) {
+                ctsBuilder.setClassType(classType.getClassType().getValue());
+            } else {
+                ctsBuilder.setClassType(Uint8.ZERO);
+            }
+        }
+
+        /* Set Address Family */
+        if (endpoints.getAddressFamily() instanceof Ipv4Case) {
+            if (segmentRouting) {
+                ctsBuilder.setAddressFamily(AddressFamily.SrIpv4);
+            } else {
+                ctsBuilder.setAddressFamily(AddressFamily.Ipv4);
+            }
+        } else {
+            if (segmentRouting) {
+                ctsBuilder.setAddressFamily(AddressFamily.SrIpv6);
+            } else {
+                ctsBuilder.setAddressFamily(AddressFamily.Ipv6);
+            }
+        }
+
+        return ctsBuilder.build();
+    }
+}
diff --git a/pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PceServerFactory.java b/pcep/server/server-provider/src/main/java/org/opendaylight/bgpcep/pcep/server/provider/PceServerFactory.java
new file mode 100644 (file)
index 0000000..813a6a4
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020 Orange. 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.bgpcep.pcep.server.provider;
+
+import com.google.common.base.Preconditions;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.algo.PathComputationProvider;
+import org.opendaylight.bgpcep.pcep.server.PceServerProvider;
+import org.opendaylight.graph.ConnectedGraph;
+import org.opendaylight.graph.ConnectedGraphProvider;
+
+public class PceServerFactory implements PceServerProvider {
+
+    private final ConnectedGraphProvider graphProvider;
+    private final PathComputationProvider algoProvider;
+    private ConnectedGraph tedGraph = null;
+
+    public PceServerFactory(ConnectedGraphProvider graphProvider, PathComputationProvider pathComputationProvider) {
+        Preconditions.checkArgument(graphProvider != null);
+        this.graphProvider = graphProvider;
+        this.algoProvider = pathComputationProvider;
+        setTedGraph();
+    }
+
+    /**
+     * Set Traffic Engineering Graph. This method is necessary as the TedGraph could be available
+     * after the PathComputationFactory start e.g. manual insertion of a ted Graph, or late tedGraph fulfillment
+     * from BGP Link State.
+     */
+    private void setTedGraph() {
+        for (ConnectedGraph cgraph : this.graphProvider.getConnectedGraphs()) {
+            if (cgraph.getGraph().getName().startsWith("ted://")) {
+                this.tedGraph = cgraph;
+                break;
+            }
+        }
+    }
+
+    @Override
+    public PathComputationImpl getPathComputation() {
+        /* Leave a change to get a valid Graph */
+        if (tedGraph == null) {
+            setTedGraph();
+        }
+        return new PathComputationImpl(tedGraph, algoProvider);
+    }
+
+    @Override
+    public @Nullable ConnectedGraph getTedGraph() {
+        /* Leave a change to get a valid Graph in case of late fulfillment */
+        if (tedGraph == null) {
+            setTedGraph();
+        }
+        return this.tedGraph;
+    }
+}
diff --git a/pcep/server/server-provider/src/main/resources/OSGI-INF/blueprint/pce-server.xml b/pcep/server/server-provider/src/main/resources/OSGI-INF/blueprint/pce-server.xml
new file mode 100644 (file)
index 0000000..a4f5962
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright (c) 2020 Orange. 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
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0">
+
+    <reference id="pathComputationProvider" interface="org.opendaylight.algo.PathComputationProvider"/>
+    <reference id="connectedGraphProvider" interface="org.opendaylight.graph.ConnectedGraphProvider" />
+
+    <bean id="pceServerProvider" class="org.opendaylight.bgpcep.pcep.server.provider.PceServerFactory">
+        <argument ref="connectedGraphProvider"/>
+        <argument ref="pathComputationProvider"/>
+    </bean>
+
+    <service ref="pceServerProvider" interface="org.opendaylight.bgpcep.pcep.server.PceServerProvider"/>
+
+</blueprint>
index d04f475cdab4e3edfea0fce320f066f1798bf8fd..b6e03187f0a27c074f0d5bafee1de23bdc859ba5 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>pcep-topology-spi</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>pcep-server-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>programming-api</artifactId>
index 487e8678949ec34532af1aa3a4d6606c5007075b..dd96a7917bbc9f37bbd4af76e8d611f4e9b27291 100644 (file)
@@ -275,4 +275,8 @@ final class ServerSessionManager implements PCEPSessionListenerFactory, Topology
     PCEPDispatcherDependencies getPCEPDispatcherDependencies() {
         return this.pcepDispatcherDependencies;
     }
+
+    PCEPTopologyProviderDependencies getPCEPTopologyProviderDependencies() {
+        return this.dependenciesProvider;
+    }
 }
\ No newline at end of file
index 3129288287c10476545c01dda32952c5e45f3ed6..a4fbe85ce3a5e19f4e9a88a47de09c86fcfc9251 100644 (file)
@@ -28,6 +28,8 @@ import java.util.Optional;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.opendaylight.bgpcep.pcep.server.PathComputation;
+import org.opendaylight.bgpcep.pcep.server.PceServerProvider;
 import org.opendaylight.protocol.pcep.PCEPSession;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
 import org.opendaylight.protocol.pcep.spi.PSTUtil;
@@ -69,11 +71,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.iet
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.srp.object.SrpBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.stateful.capability.tlv.Stateful;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.symbolic.path.name.tlv.SymbolicPathNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev181109.Pcreq;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Message;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.PcerrMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.EroBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.open.object.open.Tlvs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.path.setup.type.tlv.PathSetupType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.PcreqMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspArgs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.EnsureLspOperationalInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.LspId;
@@ -109,11 +113,14 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
     private final AtomicBoolean lspUpdateCapability = new AtomicBoolean(false);
     private final AtomicBoolean initiationCapability = new AtomicBoolean(false);
 
+    private PceServerProvider pceServerProvider;
+
     /**
      * Creates a new stateful topology session listener for given server session manager.
      */
     Stateful07TopologySessionListener(final ServerSessionManager serverSessionManager) {
         super(serverSessionManager);
+        this.pceServerProvider = serverSessionManager.getPCEPTopologyProviderDependencies().getPceServerProvider();
     }
 
     private static LspDbVersion geLspDbVersionTlv(final Lsp lsp) {
@@ -364,11 +371,37 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
         return pb.build();
     }
 
+    private boolean handlePcreqMessage(final PcreqMessage message) {
+
+        LOG.info("Start PcRequest Message handler");
+
+        /* Get a Path Computation to compute the Path from the Request */
+        PathComputation pathComputation = this.pceServerProvider.getPathComputation();
+        Message rep = null;
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.pcreq.message.pcreq
+                .message.Requests req : message.getRequests()) {
+            LOG.debug("Process request {}", req);
+            rep = pathComputation.computePath(req);
+            SrpIdNumber repId = null;
+            if (req.getRp() != null) {
+                repId = new SrpIdNumber(req.getRp().getRequestId().getValue());
+            } else {
+                repId = new SrpIdNumber(Uint32.ZERO);
+            }
+            sendMessage(rep, repId, null);
+        }
+        return false;
+    }
+
     @Override
     protected synchronized boolean onMessage(final MessageContext ctx, final Message message) {
         if (message instanceof PcerrMessage) {
             return handleErrorMessage((PcerrMessage) message);
         }
+        if (message instanceof Pcreq) {
+            LOG.info("PcReq detected. Start Request Message handler");
+            return handlePcreqMessage(((Pcreq) message).getPcreqMessage());
+        }
         if (!(message instanceof PcrptMessage)) {
             return true;
         }
@@ -714,14 +747,28 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
 
             // Build the request
             final RequestsBuilder rb = new RequestsBuilder();
-            final Arguments2 args = this.input.getArguments().augmentation(Arguments2.class);
-            final Lsp inputLsp = args != null ? args.getLsp() : null;
+            final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120
+                    .add.lsp.args.Arguments args = this.input.getArguments();
+            final Arguments2 args2 = args.augmentation(Arguments2.class);
+            final Lsp inputLsp = args2 != null ? args2.getLsp() : null;
             if (inputLsp == null) {
                 return OperationResults.createUnsent(PCEPErrors.LSP_MISSING).future();
             }
 
             rb.fieldsFrom(this.input.getArguments());
 
+            /* Call Path Computation if an ERO was not provided */
+            boolean segmentRouting = !PSTUtil.isDefaultPST(args2.getPathSetupType());
+            if ((rb.getEro() == null)
+                    || (rb.getEro().getSubobject() == null)
+                    || (rb.getEro().getSubobject().size() == 0)) {
+
+                /* Get a Path Computation to compute the Path from the Arguments */
+                PathComputation pathComputation = pceServerProvider.getPathComputation();
+                rb.setEro(pathComputation.computeEro(args.getEndpointsObj(), args.getBandwidth(), args.getClassType(),
+                        args.getMetrics(), segmentRouting));
+            }
+
             final TlvsBuilder tlvsBuilder;
             if (inputLsp.getTlvs() != null) {
                 tlvsBuilder = new TlvsBuilder(inputLsp.getTlvs());
@@ -735,11 +782,11 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
             final SrpBuilder srpBuilder = new SrpBuilder()
                     .setOperationId(nextRequest())
                     .setProcessingRule(Boolean.TRUE);
-            if (!PSTUtil.isDefaultPST(args.getPathSetupType())) {
+            if (segmentRouting) {
                 srpBuilder.setTlvs(
                         new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf
                                 .stateful.rev181109.srp.object.srp.TlvsBuilder()
-                                .setPathSetupType(args.getPathSetupType()).build());
+                                .setPathSetupType(args2.getPathSetupType()).build());
             }
             rb.setSrp(srpBuilder.build());
 
index b38582dc9e2d9b8f6c657f355ce1d4ffeb68094b..df0ac55ef590504a9c93c51344cab94633d6b24e 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.List;
 import org.checkerframework.checker.lock.qual.GuardedBy;
+import org.opendaylight.bgpcep.pcep.server.PceServerProvider;
 import org.opendaylight.bgpcep.pcep.topology.provider.PCEPTopologyProvider;
 import org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory;
 import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
@@ -46,6 +47,7 @@ public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDepen
     private final BundleContext bundleContext;
     private final ClusterSingletonServiceProvider cssp;
     private final TopologySessionStatsRegistry stateRegistry;
+    private final PceServerProvider pceServerProvider;
     @GuardedBy("this")
     private PCEPTopologyProviderBeanCSS pcepTopoProviderCSS;
 
@@ -56,7 +58,8 @@ public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDepen
             final PCEPDispatcher pcepDispatcher,
             final RpcProviderService rpcProviderRegistry,
             final TopologySessionListenerFactory sessionListenerFactory,
-            final TopologySessionStatsRegistry stateRegistry) {
+            final TopologySessionStatsRegistry stateRegistry,
+            final PceServerProvider pceServerProvider) {
         this.cssp = requireNonNull(cssp);
         this.bundleContext = requireNonNull(bundleContext);
         this.pcepDispatcher = requireNonNull(pcepDispatcher);
@@ -64,6 +67,7 @@ public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDepen
         this.sessionListenerFactory = requireNonNull(sessionListenerFactory);
         this.rpcProviderRegistry = requireNonNull(rpcProviderRegistry);
         this.stateRegistry = requireNonNull(stateRegistry);
+        this.pceServerProvider = requireNonNull(pceServerProvider);
         final List<PCEPCapability> capabilities = this.pcepDispatcher.getPCEPSessionNegotiatorFactory()
                 .getPCEPSessionProposalFactory().getCapabilities();
         final boolean statefulCapability = capabilities.stream().anyMatch(PCEPCapability::isStateful);
@@ -125,6 +129,11 @@ public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDepen
         return this.stateRegistry;
     }
 
+    @Override
+    public PceServerProvider getPceServerProvider() {
+        return this.pceServerProvider;
+    }
+
     private static class PCEPTopologyProviderBeanCSS implements ClusterSingletonService, AutoCloseable {
         private final ServiceGroupIdentifier sgi;
         private final PCEPTopologyProvider pcepTopoProvider;
index ad090a6550d2dab6da21ba2776288ea87d00a535..24e87c70bf7b26010dd4d14bc9712ec2b26f5ace 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.bgpcep.pcep.topology.provider.config;
 
 import com.google.common.annotations.Beta;
 import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.bgpcep.pcep.server.PceServerProvider;
 import org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory;
 import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
 import org.opendaylight.mdsal.binding.api.DataBroker;
@@ -55,4 +56,11 @@ public interface PCEPTopologyProviderDependencies {
      * @return TopologySessionStateRegistry
      */
     TopologySessionStatsRegistry getStateRegistry();
+
+    /**
+     * PCE Server Provider.
+     *
+     * @return PceServerProvider
+     */
+    PceServerProvider getPceServerProvider();
 }
index f6157fbe8378606e1b1ba2180a52a6d01df6053e..b67b66b8250e33a73ecce931150eb6318913d392 100644 (file)
@@ -13,7 +13,7 @@
           class="org.opendaylight.bgpcep.pcep.topology.provider.Stateful07TopologySessionListenerFactory"/>
     <service ref="Stateful07TopologySessionListenerFactory"
              interface="org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory"/>
-    
+
     <reference id="dataBroker" interface="org.opendaylight.mdsal.binding.api.DataBroker"
                odl:type="default"/>
     <reference id="rpcProviderService" interface="org.opendaylight.mdsal.binding.api.RpcProviderService"/>
@@ -23,6 +23,7 @@
     <reference id="intructionFactory" interface="org.opendaylight.bgpcep.programming.spi.InstructionSchedulerFactory"/>
     <reference id="topologySessionStatsRegistry"
                interface="org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry"/>
+    <reference id="pceServerProvider" interface="org.opendaylight.bgpcep.pcep.server.PceServerProvider"/>
 
     <bean id="pcepTopologyDeployer"
           class="org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyDeployerImpl"
@@ -43,5 +44,6 @@
         <argument ref="rpcProviderService"/>
         <argument ref="Stateful07TopologySessionListenerFactory"/>
         <argument ref="topologySessionStatsRegistry"/>
+        <argument ref="pceServerProvider"/>
     </bean>
 </blueprint>
index 8a97d8e7aa319e3e7e156e37b23c8e930d8a17e8..da820dc03b90ad3d6b57e9447e8336ade4a24808 100644 (file)
@@ -153,6 +153,7 @@ public abstract class AbstractPCEPSessionTest<T extends TopologySessionListenerF
         doReturn(RPC_TIMEOUT).when(this.sessionConfig).getRpcTimeout();
         doReturn(TEST_TOPOLOGY_ID).when(this.topology).getTopologyId();
         doReturn(Collections.emptyList()).when(this.topology).getNode();
+        doReturn(null).when(this.topologyDependencies).getPceServerProvider();
 
         final PCEPTopologyConfiguration configDep = new PCEPTopologyConfiguration(this.sessionConfig, this.topology);
         this.manager = new ServerSessionManager(this.topologyDependencies, listenerFactory, configDep);
diff --git a/pom.xml b/pom.xml
index ee537c563f1816910a558c206199ea383a6a52ba..dee120bbc7a97a0bc0d02475bed5d607aa78e7c1 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -40,9 +40,9 @@
         <module>util</module>
 
         <!-- Subsystems -->
+        <module>graph</module>
         <module>bgp</module>
         <module>bmp</module>
-        <module>graph</module>
         <module>algo</module>
         <module>pcep</module>
         <module>programming</module>