Merge "BUG-50 : added test for Pcinitiate message."
authorRobert Varga <rovarga@cisco.com>
Mon, 11 Nov 2013 11:18:54 +0000 (11:18 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 11 Nov 2013 11:18:54 +0000 (11:18 +0000)
46 files changed:
bgp/parser-api/src/main/yang/bgp-multiprotocol.yang
bgp/pom.xml
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPDispatcherImpl.java
bgp/testtool/src/main/java/org/opendaylight/protocol/bgp/testtool/Main.java
bgp/testtool/src/test/java/org/opendaylight/protocol/bgp/testtool/BGPSpeakerMock.java
bgp/topology-provider/.project [moved from topology/provider-bgp/.project with 100% similarity]
bgp/topology-provider/pom.xml [moved from topology/provider-bgp/pom.xml with 95% similarity]
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/AbstractLocRIBListener.java [new file with mode: 0644]
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/LocRIBListener.java [moved from topology/provider-bgp/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/LocRIBListener.java with 75% similarity]
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/LocRIBListeners.java [moved from topology/provider-bgp/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/LocRIBListeners.java with 100% similarity]
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/AbstractReachabilityTopologyBuilder.java [new file with mode: 0644]
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Activator.java [moved from topology/provider-bgp/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Activator.java with 79% similarity]
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Ipv4ReachabilityTopologyBuilder.java [new file with mode: 0644]
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Ipv6ReachabilityTopologyBuilder.java [new file with mode: 0644]
bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/LocRIBListenerSubscriptionTracker.java [moved from topology/provider-bgp/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/LocRIBListenerSubscriptionTracker.java with 93% similarity]
concepts/src/test/java/org/opendaylight/protocol/concepts/BandwidthTest.java
framework/src/main/java/org/opendaylight/protocol/framework/AbstractDispatcher.java
framework/src/test/java/org/opendaylight/protocol/framework/SimpleDispatcher.java
pcep/api/src/main/yang/pcep-types.yang
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImpl.java
pcep/pom.xml
pcep/testtool/src/main/java/org/opendaylight/protocol/pcep/testtool/Main.java
pcep/testtool/src/test/java/org/opendaylight/protocol/pcep/testtool/PCCMock.java
pcep/topology-provider/pom.xml
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/BundleActivator.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/TopologyProgramming.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/TopologyRPCs.java
pcep/topology-spi/.project [new file with mode: 0644]
pcep/topology-spi/pom.xml [new file with mode: 0644]
pcep/topology-spi/src/main/java/org/opendaylight/bgpcep/pcep/topology/spi/AbstractTopologyProgrammingExecutor.java [new file with mode: 0644]
pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang
pcep/tunnel-api/src/main/yang/topology-tunnel-pcep.yang
pcep/tunnel-provider/pom.xml
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/BundleActivator.java
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/NodeChangedListener.java
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelInstructionExecutor.java [deleted file]
pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java [new file with mode: 0644]
programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/Instruction.java
programming/impl/src/main/java/org/opendaylight/bgpcep/programming/impl/ProgrammingServiceImpl.java
programming/spi/src/main/java/org/opendaylight/bgpcep/programming/spi/InstructionExecutor.java
programming/tunnel-api/src/main/yang/topology-tunnel-programming.yang
rsvp/api/src/main/yang/rsvp.yang
topology/pom.xml
topology/tunnel-api/src/main/yang/topology-tunnel-p2p.yang

index c60118c0ea25ee3df6629207193329c4c9f23459..6dd538461c724f820202804a831e72bd212b1b02 100644 (file)
@@ -68,6 +68,42 @@ module bgp-multiprotocol {
                                uses bgp-table-type;
                        }
                }
+               case c-graceful-restart {
+                       container graceful-restart-capability {
+                               reference "http://tools.ietf.org/html/rfc4724#section-3";
+
+                               leaf restart-flags {
+                                       type bits {
+                                               bit restart-state {
+                                                       position 0;
+                                               }
+                                       }
+                                       mandatory true;
+                               }
+
+                               leaf restart-time {
+                                       type uint16 {
+                                               range 0..4095;
+                                       }
+                                       units seconds;
+                                       mandatory true;
+                               }
+
+                               list tables {
+                                       uses bgp-table-type;
+                                       key "afi safi";
+
+                                       leaf afi-flags {
+                                               type bits {
+                                                       bit forwarding-state {
+                                                               position 0;
+                                                       }
+                                               }
+                                               mandatory true;
+                                       }
+                               }
+                       }
+               }
        }
 
        augment "/bgp-msg:update/bgp-msg:path-attributes" {
index 157e3747ddb8310480a5f8eccbad9e9333cb3583..41073eea18b805ee60e64127052c6c8028157b07 100644 (file)
@@ -28,6 +28,7 @@
         <module>rib-impl</module>
         <module>testtool</module>
         <module>rib-mock</module>
+        <module>topology-provider</module>
         <module>util</module>
     </modules>
 </project>
index a590a630048796ad8fb3ef7e7401a13adb9d5b42..54d75e0bcbd1b7983d87722b815efb0e2f433bae 100644 (file)
@@ -7,14 +7,12 @@
  */
 package org.opendaylight.protocol.bgp.rib.impl;
 
+import io.netty.channel.EventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.Timer;
 import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.Promise;
-
-import java.net.InetSocketAddress;
-
 import org.opendaylight.protocol.bgp.parser.BGPMessageFactory;
 import org.opendaylight.protocol.bgp.parser.BGPSessionListener;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
@@ -23,6 +21,8 @@ import org.opendaylight.protocol.framework.AbstractDispatcher;
 import org.opendaylight.protocol.framework.ReconnectStrategy;
 import org.opendaylight.protocol.framework.SessionListenerFactory;
 
+import java.net.InetSocketAddress;
+
 /**
  * Implementation of BGPDispatcher.
  */
@@ -31,8 +31,8 @@ public final class BGPDispatcherImpl extends AbstractDispatcher<BGPSessionImpl,
 
        private final BGPHandlerFactory hf;
 
-       public BGPDispatcherImpl(final BGPMessageFactory parser) {
-               super();
+       public BGPDispatcherImpl(final BGPMessageFactory parser, EventLoopGroup bossGroup, EventLoopGroup workerGroup) {
+               super(bossGroup, workerGroup);
                this.hf = new BGPHandlerFactory(parser);
        }
 
index 348ae034c63e82d44b57eae12f172afed9be558c..09caaa913861cb86f52605259bd6c3d6ef91182f 100644 (file)
@@ -7,11 +7,8 @@
  */
 package org.opendaylight.protocol.bgp.testtool;
 
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.concurrent.GlobalEventExecutor;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-
 import org.opendaylight.protocol.bgp.parser.BGPSessionListener;
 import org.opendaylight.protocol.bgp.parser.impl.BGPMessageFactoryImpl;
 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
@@ -24,6 +21,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
 /**
  * Starter class for testing.
  */
@@ -54,7 +54,8 @@ public class Main {
        private static final int RECONNECT_MILLIS = 5000;
 
        Main() throws Exception {
-               this.dispatcher = new BGPDispatcherImpl(new BGPMessageFactoryImpl(ServiceLoaderBGPExtensionProviderContext.createConsumerContext().getMessageRegistry()));
+        this.dispatcher = new BGPDispatcherImpl(new BGPMessageFactoryImpl(ServiceLoaderBGPExtensionProviderContext
+                .createConsumerContext().getMessageRegistry()), new NioEventLoopGroup(), new NioEventLoopGroup());
        }
 
        public static void main(final String[] args) throws Exception {
index 24db1cae01269a4ec9e96d6eb24729b9e8387dac..8264d83318b1c584ea14ea413f9e9fe5201c7ed6 100644 (file)
@@ -7,14 +7,13 @@
  */
 package org.opendaylight.protocol.bgp.testtool;
 
+import com.google.common.base.Preconditions;
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.concurrent.DefaultPromise;
 import io.netty.util.concurrent.GlobalEventExecutor;
 import io.netty.util.concurrent.Promise;
-
-import java.net.InetSocketAddress;
-
 import org.opendaylight.protocol.bgp.parser.BGPSessionListener;
 import org.opendaylight.protocol.bgp.parser.impl.BGPMessageFactoryImpl;
 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
@@ -32,7 +31,7 @@ import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
-import com.google.common.base.Preconditions;
+import java.net.InetSocketAddress;
 
 public class BGPSpeakerMock<M, S extends ProtocolSession<M>, L extends SessionListener<M, ?, ?>> extends AbstractDispatcher<S, L> {
 
@@ -41,6 +40,7 @@ public class BGPSpeakerMock<M, S extends ProtocolSession<M>, L extends SessionLi
 
        public BGPSpeakerMock(final SessionNegotiatorFactory<M, S, L> negotiatorFactory, final ProtocolHandlerFactory<?> factory,
                        final DefaultPromise<BGPSessionImpl> defaultPromise) {
+               super(new NioEventLoopGroup(), new NioEventLoopGroup());
                this.negotiatorFactory = Preconditions.checkNotNull(negotiatorFactory);
                this.factory = Preconditions.checkNotNull(factory);
        }
similarity index 95%
rename from topology/provider-bgp/pom.xml
rename to bgp/topology-provider/pom.xml
index f56d630ff54692697f0eb99779a32fa8b0f9e315..3db7f0024e409e83f25c156dc6c22d9625ff6959 100644 (file)
@@ -5,12 +5,12 @@
 
        <parent>
                <groupId>org.opendaylight.bgpcep</groupId>
-               <artifactId>topology-parent</artifactId>
+               <artifactId>bgp-parent</artifactId>
                <version>0.3.0-SNAPSHOT</version>
        </parent>
 
        <modelVersion>4.0.0</modelVersion>
-       <artifactId>topology-provider-bgp</artifactId>
+       <artifactId>bgp-topology-provider</artifactId>
        <description>BGP Topology Provider</description>
        <packaging>bundle</packaging>
        <name>${project.artifactId}</name>
@@ -78,7 +78,7 @@
        <distributionManagement>
                <site>
                        <id>${project.artifactId}</id>
-                       <name>TOPOLOGY-PROVIDER-BGP Module site</name>
+                       <name>BGP-TOPOLOGY-PROVIDER Module site</name>
                        <url>${basedir}/target/site/${project.artifactId}</url>
                </site>
        </distributionManagement>
diff --git a/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/AbstractLocRIBListener.java b/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/AbstractLocRIBListener.java
new file mode 100644 (file)
index 0000000..e3aab20
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.topology.provider.bgp;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractLocRIBListener<T extends Route> implements LocRIBListener {
+       private static final Logger LOG = LoggerFactory.getLogger(AbstractLocRIBListener.class);
+       protected final InstanceIdentifier<Topology> topology;
+       private final Class<T> idClass;
+
+       protected AbstractLocRIBListener(final InstanceIdentifier<Topology> topology, final Class<T> idClass) {
+               this.topology = Preconditions.checkNotNull(topology);
+               this.idClass = Preconditions.checkNotNull(idClass);
+       }
+
+       protected abstract void createObject(DataModification<InstanceIdentifier<?>, DataObject> trans, InstanceIdentifier<T> id, T value);
+       protected abstract void removeObject(DataModification<InstanceIdentifier<?>, DataObject> trans, InstanceIdentifier<T> id, T value);
+
+       private InstanceIdentifier<T> changedObject(final InstanceIdentifier<?> id, final int depth) {
+               final List<PathArgument> p = id.getPath();
+               final int i =  p.indexOf(idClass);
+               Preconditions.checkState(i > -1, "Class %s not found in identifier %s", idClass, id);
+               return new InstanceIdentifier<>(p.subList(depth, i), idClass);
+       }
+
+       @Override
+       public final void onLocRIBChange(final DataModification<InstanceIdentifier<?>, DataObject> trans,
+                       final DataChangeEvent<InstanceIdentifier<?>, DataObject> event, final int depth) {
+
+               final Set<InstanceIdentifier<T>> ids = new HashSet<>();
+               for (final InstanceIdentifier<?> i : event.getRemovedOperationalData()) {
+                       ids.add(Preconditions.checkNotNull(changedObject(i, depth)));
+               }
+               for (final InstanceIdentifier<?> i : event.getUpdatedOperationalData().keySet()) {
+                       ids.add(Preconditions.checkNotNull(changedObject(i, depth)));
+               }
+               for (final InstanceIdentifier<?> i : event.getCreatedOperationalData().keySet()) {
+                       ids.add(Preconditions.checkNotNull(changedObject(i, depth)));
+               }
+
+               final Map<InstanceIdentifier<?>, DataObject> o = event.getOriginalOperationalData();
+               final Map<InstanceIdentifier<?>, DataObject> n = event.getUpdatedOperationalData();
+               for (final InstanceIdentifier<T> i : ids) {
+                       final T oldValue = idClass.cast(o.get(i));
+                       final T newValue = idClass.cast(n.get(i));
+
+                       LOG.debug("Updating object {} value {} -> {}", i, oldValue, newValue);
+                       if (oldValue != null) {
+                               removeObject(trans, i, oldValue);
+                       }
+                       if (newValue != null) {
+                               createObject(trans, i, newValue);
+                       }
+               }
+       }
+}
similarity index 75%
rename from topology/provider-bgp/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/LocRIBListener.java
rename to bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/LocRIBListener.java
index b5bc4579a60944392a7afed8862c50f8792ce5e1..8279601b74c1048abe0d6fd5443bd820c051d103 100644 (file)
@@ -11,6 +11,8 @@ import java.util.EventListener;
 
 import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public interface LocRIBListener extends EventListener {
        /**
@@ -19,7 +21,9 @@ public interface LocRIBListener extends EventListener {
         *              is not shared with any other entity and will be cleaned up by the
         *              caller if it is not committed before this method returns.
         * @param event Data change event
+        * @param depth Subscription path depth.
         * @throws Exception throw it if you must. If you can handle it, please do so.
         */
-       public void onLocRIBChange(DataModification<?, ?> trans, DataChangeEvent<?, ?> event) throws Exception;
+       public void onLocRIBChange(DataModification<InstanceIdentifier<?>, DataObject> trans,
+                       DataChangeEvent<InstanceIdentifier<?>, DataObject> event, int depth) throws Exception;
 }
diff --git a/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/AbstractReachabilityTopologyBuilder.java b/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/AbstractReachabilityTopologyBuilder.java
new file mode 100644 (file)
index 0000000..a4a0b33
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.topology.provider.bgp.impl;
+
+import java.util.ArrayList;
+
+import org.opendaylight.bgpcep.topology.provider.bgp.AbstractLocRIBListener;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.route.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.CIpv4NextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.CIpv6NextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.c.ipv4.next.hop.Ipv4NextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.c.ipv6.next.hop.Ipv6NextHop;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.IgpNodeAttributes;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.Node1;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.Node1Builder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.node.attributes.IgpNodeAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.node.attributes.igp.node.attributes.Prefix;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.node.attributes.igp.node.attributes.PrefixBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.node.attributes.igp.node.attributes.PrefixKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+abstract class AbstractReachabilityTopologyBuilder<T extends Route> extends AbstractLocRIBListener<T> {
+       private static final Logger LOG = LoggerFactory.getLogger(AbstractReachabilityTopologyBuilder.class);
+
+       protected AbstractReachabilityTopologyBuilder(final InstanceIdentifier<Topology> topology, final Class<T> idClass) {
+               super(topology, idClass);
+       }
+
+       private NodeId advertizingNode(final Attributes attrs) {
+               final CNextHop nh = attrs.getCNextHop();
+               if (nh instanceof CIpv4NextHop) {
+                       final Ipv4NextHop ipv4 = ((CIpv4NextHop) nh).getIpv4NextHop();
+
+                       return new NodeId(ipv4.getGlobal().getValue());
+               } else if (nh instanceof CIpv6NextHop) {
+                       final Ipv6NextHop ipv6 = ((CIpv6NextHop) nh).getIpv6NextHop();
+
+                       return new NodeId(ipv6.getGlobal().getValue());
+               } else {
+                       LOG.warn("Unhandled next hop class {}", nh.getImplementedInterface());
+                       return null;
+               }
+       }
+
+       private InstanceIdentifier<Node1> nodeInstanceId(final NodeId ni) {
+               return InstanceIdentifier.builder(topology).node(Node.class, new NodeKey(ni)).node(Node1.class).toInstance();
+       }
+
+       private InstanceIdentifier<Node1> ensureNodePresent(final DataModification<InstanceIdentifier<?>, DataObject> trans,
+                       final NodeId ni) {
+               final InstanceIdentifier<Node1> nii = nodeInstanceId(ni);
+
+               if (trans.readOperationalData(nii) == null) {
+                       LOG.debug("Create a new node at {}", nii);
+                       trans.putOperationalData(nii, new Node1Builder().setIgpNodeAttributes(
+                                       new IgpNodeAttributesBuilder().setPrefix(new ArrayList<Prefix>()).build()).build());
+               }
+
+               return nii;
+       }
+
+       private void removeEmptyNode(final DataModification<InstanceIdentifier<?>, DataObject> trans, final InstanceIdentifier<Node1> nii) {
+               final Node1 node = (Node1) trans.readOperationalData(nii);
+               if (node != null && node.getIgpNodeAttributes().getPrefix().isEmpty()) {
+                       trans.removeOperationalData(nii);
+               }
+       }
+
+       protected abstract Attributes getAttributes(final T value);
+       protected abstract IpPrefix getPrefix(final T value);
+
+       @Override
+       protected final void createObject(final DataModification<InstanceIdentifier<?>, DataObject> trans,
+                       final InstanceIdentifier<T> id, final T value) {
+               final NodeId ni = advertizingNode(getAttributes(value));
+               final InstanceIdentifier<Node1> nii = ensureNodePresent(trans, ni);
+
+               final IpPrefix prefix = getPrefix(value);
+               final PrefixKey pk = new PrefixKey(prefix);
+
+               trans.putOperationalData(InstanceIdentifier.builder(nii).node(IgpNodeAttributes.class).node(Prefix.class, pk).toInstance(),
+                               new PrefixBuilder().setKey(pk).setPrefix(prefix).build());
+       }
+
+
+       @Override
+       protected final void removeObject(final DataModification<InstanceIdentifier<?>, DataObject> trans,
+                       final InstanceIdentifier<T> id, final T value) {
+               final NodeId ni = advertizingNode(getAttributes(value));
+               final InstanceIdentifier<Node1> nii = nodeInstanceId(ni);
+
+               final IpPrefix prefix = getPrefix(value);
+               final PrefixKey pk = new PrefixKey(prefix);
+
+               trans.removeOperationalData(InstanceIdentifier.builder(nii).node(IgpNodeAttributes.class).node(Prefix.class, pk).toInstance());
+
+               removeEmptyNode(trans, nii);
+       }
+}
similarity index 79%
rename from topology/provider-bgp/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Activator.java
rename to bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Activator.java
index 77fe3287890740abb6b4c4fd7a1c1d4a3c12c6cb..b6a93687c2ed1180acb42712c58c306c7b942f08 100644 (file)
@@ -22,7 +22,7 @@ import org.osgi.framework.ServiceRegistration;
 import com.google.common.base.Preconditions;
 
 public class Activator extends AbstractBindingAwareProvider {
-//     private ServiceRegistration<LocRIBListeners.Subscribtion> ipv4, ipv6, linkstate;
+       private ServiceRegistration<LocRIBListeners.Subscribtion> ipv4, ipv6, linkstate;
        private BundleContext context;
 
        @Override
@@ -30,9 +30,12 @@ public class Activator extends AbstractBindingAwareProvider {
                final LocRIBListenerSubscriptionTracker reg = new LocRIBListenerSubscriptionTracker(context, session.getSALService(DataProviderService.class));
                reg.open();
 
-//             ipv4 = LocRIBListeners.subscribe(context, Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, new Ipv4ReachabilityTopologyBuilder());
-//             ipv6 = LocRIBListeners.subscribe(context, Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class, new Ipv6ReachabilityTopologyBuilder());
-//             linkstate = LocRIBListeners.subscribe(context, LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class, new LinkstateTopologyBuilder());
+               ipv4 = LocRIBListeners.subscribe(context, Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class,
+                               new Ipv4ReachabilityTopologyBuilder(null));
+               ipv6 = LocRIBListeners.subscribe(context, Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class,
+                               new Ipv6ReachabilityTopologyBuilder(null));
+//             linkstate = LocRIBListeners.subscribe(context, LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class,
+//                             new LinkstateTopologyBuilder(null));
        }
 
        @Override
diff --git a/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Ipv4ReachabilityTopologyBuilder.java b/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Ipv4ReachabilityTopologyBuilder.java
new file mode 100644 (file)
index 0000000..a211c00
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.topology.provider.bgp.impl;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.routes.ipv4.routes.Ipv4Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.route.Attributes;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+final class Ipv4ReachabilityTopologyBuilder extends AbstractReachabilityTopologyBuilder<Ipv4Routes> {
+       Ipv4ReachabilityTopologyBuilder(final InstanceIdentifier<Topology> topology) {
+               super(topology, Ipv4Routes.class);
+       }
+
+       @Override
+       protected Attributes getAttributes(final Ipv4Routes value) {
+               return value.getAttributes();
+       }
+
+       @Override
+       protected IpPrefix getPrefix(final Ipv4Routes value) {
+               return new IpPrefix(value.getKey().getPrefix());
+       }
+}
diff --git a/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Ipv6ReachabilityTopologyBuilder.java b/bgp/topology-provider/src/main/java/org/opendaylight/bgpcep/topology/provider/bgp/impl/Ipv6ReachabilityTopologyBuilder.java
new file mode 100644 (file)
index 0000000..334b159
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.topology.provider.bgp.impl;
+
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.routes.ipv6.routes.Ipv6Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.route.Attributes;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+final class Ipv6ReachabilityTopologyBuilder extends AbstractReachabilityTopologyBuilder<Ipv6Routes> {
+       Ipv6ReachabilityTopologyBuilder(final InstanceIdentifier<Topology> topology) {
+               super(topology, Ipv6Routes.class);
+       }
+
+       @Override
+       protected Attributes getAttributes(final Ipv6Routes value) {
+               return value.getAttributes();
+       }
+
+       @Override
+       protected IpPrefix getPrefix(final Ipv6Routes value) {
+               return new IpPrefix(value.getKey().getPrefix());
+       }
+}
@@ -10,8 +10,8 @@ package org.opendaylight.bgpcep.topology.provider.bgp.impl;
 import org.opendaylight.bgpcep.topology.provider.bgp.LocRIBListener;
 import org.opendaylight.bgpcep.topology.provider.bgp.LocRIBListeners;
 import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.LocRib;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
@@ -48,15 +48,16 @@ final class LocRIBListenerSubscriptionTracker extends ServiceTracker<LocRIBListe
                final InstanceIdentifier<Tables> path = InstanceIdentifier.builder(locRIBPath).
                                node(Tables.class, new TablesKey(service.getAfi(), service.getSafi())).toInstance();
                final LocRIBListener listener = service.getLocRIBListener();
+               final int depth = path.getPath().size();
 
                final DataChangeListener dcl = new DataChangeListener() {
 
                        @Override
                        public void onDataChanged(final DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
-                               final DataModification<?, ?> trans = dps.beginTransaction();
+                               final DataModificationTransaction trans = dps.beginTransaction();
 
                                try {
-                                       listener.onLocRIBChange(trans, change);
+                                       listener.onLocRIBChange(trans, change, depth);
                                } catch (Exception e) {
                                        LOG.info("Data change {} was not completely propagated to listener {}", change, listener, e);
                                }
index dfa552b126cdb2662a4d240ccd62531026c4f376..6fced21e9dae2ce2d8ce9e2be6d2d737f9b02cbe 100644 (file)
@@ -18,7 +18,6 @@ import java.util.HashSet;
 import java.util.Set;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.nps.concepts.rev130930.Bandwidth;
index afea289c007f1dfdb8df9aa90f0ce5f622f5397b..c040170e1b3dbbcc50c7341139c37ecdf63389d6 100644 (file)
@@ -21,13 +21,12 @@ import io.netty.util.concurrent.DefaultPromise;
 import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.GlobalEventExecutor;
 import io.netty.util.concurrent.Promise;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.io.Closeable;
 import java.net.InetSocketAddress;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 /**
  * Dispatcher class for creating servers and clients. The idea is to first create servers and clients and the run the
  * start method that will handle sockets in different thread.
@@ -38,7 +37,7 @@ public abstract class AbstractDispatcher<S extends ProtocolSession<?>, L extends
                /**
                 * Initializes channel by specifying the handlers in its pipeline. Handlers are protocol specific, therefore this
                 * method needs to be implemented in protocol specific Dispatchers.
-                * 
+                *
                 * @param channel whose pipeline should be defined, also to be passed to {@link SessionNegotiatorFactory}
                 * @param promise to be passed to {@link SessionNegotiatorFactory}
                 */
@@ -52,18 +51,28 @@ public abstract class AbstractDispatcher<S extends ProtocolSession<?>, L extends
 
        private final EventLoopGroup workerGroup;
 
+
+       /**
+        * Internally creates new instances of NioEventLoopGroup, might deplete system resources and result in Too many open files exception.
+        *
+        * @deprecated use {@link AbstractDispatcher#AbstractDispatcher(io.netty.channel.EventLoopGroup, io.netty.channel.EventLoopGroup)} instead.
+        */
+       @Deprecated
        protected AbstractDispatcher() {
-               // FIXME: we should get these as arguments
-               this.bossGroup = new NioEventLoopGroup();
-               this.workerGroup = new NioEventLoopGroup();
+               this(new NioEventLoopGroup(),new NioEventLoopGroup());
+       }
+
+       protected AbstractDispatcher(EventLoopGroup bossGroup, EventLoopGroup workerGroup) {
+               this.bossGroup = bossGroup;
+               this.workerGroup = workerGroup;
        }
 
        /**
         * Creates server. Each server needs factories to pass their instances to client sessions.
-        * 
+        *
         * @param address address to which the server should be bound
         * @param initializer instance of PipelineInitializer used to initialize the channel pipeline
-        * 
+        *
         * @return ChannelFuture representing the binding process
         */
        protected ChannelFuture createServer(final InetSocketAddress address, final PipelineInitializer<S> initializer) {
@@ -89,12 +98,12 @@ public abstract class AbstractDispatcher<S extends ProtocolSession<?>, L extends
 
        /**
         * Creates a client.
-        * 
+        *
         * @param address remote address
         * @param connectStrategy Reconnection strategy to be used when initial connection fails
-        * 
+        *
         * @return Future representing the connection process. Its result represents the combined success of TCP connection
-        *         as well as session negotiation.
+        *               as well as session negotiation.
         */
        protected Future<S> createClient(final InetSocketAddress address, final ReconnectStrategy strategy, final PipelineInitializer<S> initializer) {
                final Bootstrap b = new Bootstrap();
@@ -114,13 +123,13 @@ public abstract class AbstractDispatcher<S extends ProtocolSession<?>, L extends
 
        /**
         * Creates a client.
-        * 
+        *
         * @param address remote address
         * @param connectStrategyFactory Factory for creating reconnection strategy to be used when initial connection fails
         * @param reestablishStrategy Reconnection strategy to be used when the already-established session fails
-        * 
+        *
         * @return Future representing the reconnection task. It will report completion based on reestablishStrategy, e.g.
-        *         success if it indicates no further attempts should be made and failure if it reports an error
+        *               success if it indicates no further attempts should be made and failure if it reports an error
         */
        protected Future<Void> createReconnectingClient(final InetSocketAddress address, final ReconnectStrategyFactory connectStrategyFactory,
                        final ReconnectStrategy reestablishStrategy, final PipelineInitializer<S> initializer) {
index bbaf5ca4ac25363605a08d2ea4d8e42a77429c38..68bf1ceb844b64f954c8abf166814cd1dc11c0e7 100644 (file)
@@ -1,16 +1,15 @@
 package org.opendaylight.protocol.framework;
 
+import com.google.common.base.Preconditions;
 import io.netty.channel.ChannelFuture;
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.Promise;
-
-import java.net.InetSocketAddress;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Preconditions;
+import java.net.InetSocketAddress;
 
 public class SimpleDispatcher extends AbstractDispatcher<SimpleSession, SimpleSessionListener> {
 
@@ -38,6 +37,7 @@ public class SimpleDispatcher extends AbstractDispatcher<SimpleSession, SimpleSe
 
        public SimpleDispatcher(final SessionNegotiatorFactory<SimpleMessage, SimpleSession, SimpleSessionListener> negotiatorFactory, final ProtocolHandlerFactory<?> factory,
                        final Promise<SimpleSession> promise) {
+               super(new NioEventLoopGroup(), new NioEventLoopGroup());
                this.negotiatorFactory = Preconditions.checkNotNull(negotiatorFactory);
                this.factory = Preconditions.checkNotNull(factory);
        }
index 7393bc333ddb1743796cec7914545d6197ae47c6..43269a05e48e8492246119d000732721d41fa812 100644 (file)
@@ -662,23 +662,7 @@ module pcep-types {
 
                container lspa {
                        uses object;
-
-                       leaf hold-priority {
-                               type uint8;
-                               mandatory true;
-                       }
-
-                       leaf setup-priority {
-                               type uint8;
-                               mandatory true;
-                       }
-
-                       leaf local-protection-desired {
-                               type boolean;
-                               default false;
-                       }
-
-                       uses rsvp:attribute-filters;
+                       uses rsvp:tunnel-attributes;
                }
        }
 
index 0e3351fd8b1a0bb2358e1c8157d32abdf455fa9b..05e09aa7add5294651de2a42f8bd591be688f639 100644 (file)
@@ -7,13 +7,11 @@
  */
 package org.opendaylight.protocol.pcep.impl;
 
+import com.google.common.base.Preconditions;
 import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.util.concurrent.Promise;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
 import org.opendaylight.protocol.framework.AbstractDispatcher;
 import org.opendaylight.protocol.framework.SessionListenerFactory;
 import org.opendaylight.protocol.framework.SessionNegotiatorFactory;
@@ -22,7 +20,8 @@ import org.opendaylight.protocol.pcep.PCEPSessionListener;
 import org.opendaylight.protocol.pcep.spi.MessageHandlerRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
 
-import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.net.InetSocketAddress;
 
 /**
  * Implementation of PCEPDispatcher.
@@ -34,11 +33,13 @@ public class PCEPDispatcherImpl extends AbstractDispatcher<PCEPSessionImpl, PCEP
 
        /**
         * Creates an instance of PCEPDispatcherImpl, gets the default selector and opens it.
-        * 
+        *
         * @throws IOException if some error occurred during opening the selector
         */
-       public PCEPDispatcherImpl(final MessageHandlerRegistry registry, final SessionNegotiatorFactory<Message, PCEPSessionImpl, PCEPSessionListener> negotiatorFactory) {
-               super();
+       public PCEPDispatcherImpl(final MessageHandlerRegistry registry,
+                       final SessionNegotiatorFactory<Message, PCEPSessionImpl, PCEPSessionListener> negotiatorFactory,
+                       EventLoopGroup bossGroup, EventLoopGroup workerGroup) {
+               super(bossGroup, workerGroup);
                this.snf = Preconditions.checkNotNull(negotiatorFactory);
                this.hf = new PCEPHandlerFactory(registry);
        }
index f58cee1d714e30356beec68328313bfbcafd2934..aaf0c694b3c5b373c4ac47a829353399954a4170 100644 (file)
@@ -23,6 +23,7 @@
         <module>testtool</module>
         <module>topology-api</module>
         <module>topology-provider</module>
+        <module>topology-spi</module>
         <module>tunnel-api</module>
         <module>tunnel-provider</module>
     </modules>
index e8dd2b4820c1ff02915e5dca3f7f9713f25a3370..2855f4f288873df9883241b41655c2773794ecde 100644 (file)
@@ -7,11 +7,8 @@
  */
 package org.opendaylight.protocol.pcep.testtool;
 
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-
 import org.opendaylight.protocol.pcep.PCEPSessionProposalFactory;
 import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiatorFactory;
 import org.opendaylight.protocol.pcep.impl.PCEPDispatcherImpl;
@@ -21,6 +18,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
 public class Main {
 
        private static final Logger logger = LoggerFactory.getLogger(Main.class);
@@ -126,7 +126,9 @@ public class Main {
 
                final Open prefs = spf.getSessionProposal(address, 0);
 
-               final PCEPDispatcherImpl dispatcher = new PCEPDispatcherImpl(PCEPExtensionProviderContextImpl.getSingletonInstance().getMessageHandlerRegistry(), new DefaultPCEPSessionNegotiatorFactory(new HashedWheelTimer(), prefs, 5));
+               final PCEPDispatcherImpl dispatcher = new PCEPDispatcherImpl(PCEPExtensionProviderContextImpl
+                               .getSingletonInstance().getMessageHandlerRegistry(), new DefaultPCEPSessionNegotiatorFactory(
+                               new HashedWheelTimer(), prefs, 5), new NioEventLoopGroup(), new NioEventLoopGroup());
 
                dispatcher.createServer(address, new TestingSessionListenerFactory()).get();
        }
index 88899670795390464833d384aee66e3df2e64e0c..dc846b37516b08727b19cea5eeb7e3421b9c5852 100644 (file)
@@ -7,15 +7,14 @@
  */
 package org.opendaylight.protocol.pcep.testtool;
 
+import com.google.common.base.Preconditions;
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.util.HashedWheelTimer;
 import io.netty.util.concurrent.DefaultPromise;
 import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.GlobalEventExecutor;
 import io.netty.util.concurrent.Promise;
-
-import java.net.InetSocketAddress;
-
 import org.opendaylight.protocol.framework.AbstractDispatcher;
 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 import org.opendaylight.protocol.framework.ProtocolHandlerFactory;
@@ -34,7 +33,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.TlvsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.predundancy.group.id.tlv.PredundancyGroupIdBuilder;
 
-import com.google.common.base.Preconditions;
+import java.net.InetSocketAddress;
 
 public class PCCMock<M, S extends ProtocolSession<M>, L extends SessionListener<M, ?, ?>> extends AbstractDispatcher<S, L> {
 
@@ -43,6 +42,7 @@ public class PCCMock<M, S extends ProtocolSession<M>, L extends SessionListener<
 
        public PCCMock(final SessionNegotiatorFactory<M, S, L> negotiatorFactory, final ProtocolHandlerFactory<?> factory,
                        final DefaultPromise<PCEPSessionImpl> defaultPromise) {
+               super(new NioEventLoopGroup(), new NioEventLoopGroup());
                this.negotiatorFactory = Preconditions.checkNotNull(negotiatorFactory);
                this.factory = Preconditions.checkNotNull(factory);
        }
index 3dc215b61bd92dd21f1265d61a7ba37d2e72d83d..94fcf797073a1f812bb74cc22c86d8ae6be36b24 100644 (file)
                        <artifactId>pcep-topology-api</artifactId>
             <version>${project.version}</version>
                </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-topology-spi</artifactId>
+            <version>${project.version}</version>
+               </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-api</artifactId>
index 6ffca6c4f7bb4294a034675616a836bab3e92c8e..9e38ec9a8cfda601c57c6362acb4ec611c841352 100644 (file)
@@ -8,8 +8,8 @@
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
 import io.netty.channel.ChannelFuture;
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.HashedWheelTimer;
-import io.netty.util.concurrent.GlobalEventExecutor;
 
 import java.net.InetSocketAddress;
 import java.util.concurrent.ExecutionException;
@@ -42,10 +42,13 @@ public final class BundleActivator extends AbstractBindingAwareProvider {
                final InetSocketAddress address = new InetSocketAddress("0.0.0.0", 4189);
                final PCEPSessionProposalFactory spf = new PCEPSessionProposalFactoryImpl(30, 10, true, true, true, true, 0);
                final Open prefs = spf.getSessionProposal(address, 0);
-               final PCEPDispatcher dispatcher = new PCEPDispatcherImpl(PCEPExtensionProviderContextImpl.getSingletonInstance().getMessageHandlerRegistry(), new DefaultPCEPSessionNegotiatorFactory(new HashedWheelTimer(), prefs, 5));
+               final PCEPDispatcher dispatcher = new PCEPDispatcherImpl(PCEPExtensionProviderContextImpl
+                               .getSingletonInstance().getMessageHandlerRegistry(), new DefaultPCEPSessionNegotiatorFactory(
+                                               new HashedWheelTimer(), prefs, 5), new NioEventLoopGroup(), new NioEventLoopGroup());
+
                final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder().node(Topology.class).toInstance();
 
-               final PCEPTopologyProvider exp = new PCEPTopologyProvider(dispatcher, GlobalEventExecutor.INSTANCE, null, dps, topology);
+               final PCEPTopologyProvider exp = new PCEPTopologyProvider(dispatcher, null, dps, topology);
                final ChannelFuture s = exp.startServer(address);
                try {
                        s.get();
index c0cf2c2b413e35041fe8fc261adabbf250248540..e11c564377a370993bb053b0c9e00a0851530be7 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
 import io.netty.channel.ChannelFuture;
-import io.netty.util.concurrent.EventExecutor;
 
 import java.net.InetSocketAddress;
 
@@ -27,16 +26,15 @@ public final class PCEPTopologyProvider {
        private final TopologyRPCs element;
 
        public PCEPTopologyProvider(final PCEPDispatcher dispatcher,
-                       final EventExecutor executor,
                        final InstructionScheduler scheduler,
                        final DataProviderService dataService,
                        final InstanceIdentifier<Topology> topology) {
                this.dispatcher = Preconditions.checkNotNull(dispatcher);
 
 
-               this.manager = new ServerSessionManager(executor, dataService, topology);
-               this.element = new TopologyRPCs(executor, manager);
-               this.topology = new TopologyProgramming(executor, scheduler, manager);
+               this.manager = new ServerSessionManager(dataService, topology);
+               this.element = new TopologyRPCs(manager);
+               this.topology = new TopologyProgramming(scheduler, manager);
        }
 
        public ChannelFuture startServer(final InetSocketAddress address) {
index 618f97237a05fb4ac6bbefb3689a16c1770d3691..07d6dde9a199926ebb1e69488f3d281303b14b55 100644 (file)
@@ -7,9 +7,7 @@
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
-import io.netty.util.concurrent.EventExecutor;
 import io.netty.util.concurrent.FutureListener;
-import io.netty.util.concurrent.Promise;
 
 import java.net.InetAddress;
 import java.util.HashMap;
@@ -81,6 +79,9 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
 
 /**
  *
@@ -91,8 +92,8 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
        }
 
        private final class SessionListener implements PCEPSessionListener {
-               private final Map<SrpIdNumber, Promise<OperationResult>> waitingRequests = new HashMap<>();
-               private final Map<SrpIdNumber, Promise<OperationResult>> sendingRequests = new HashMap<>();
+               private final Map<SrpIdNumber, SettableFuture<OperationResult>> waitingRequests = new HashMap<>();
+               private final Map<SrpIdNumber, SettableFuture<OperationResult>> sendingRequests = new HashMap<>();
                private final Map<PlspId, SymbolicPathName> lsps = new HashMap<>();
                private PathComputationClientBuilder pccBuilder;
                private InstanceIdentifier<Node1> topologyAugment;
@@ -205,16 +206,16 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
                        }
 
                        // Clear all requests which have not been sent to the peer: they result in cancellation
-                       for (final Entry<SrpIdNumber, Promise<OperationResult>> e : this.sendingRequests.entrySet()) {
+                       for (final Entry<SrpIdNumber, SettableFuture<OperationResult>> e : this.sendingRequests.entrySet()) {
                                LOG.debug("Request {} was not sent when session went down, cancelling the instruction", e.getKey());
-                               e.getValue().setSuccess(OPERATION_UNSENT);
+                               e.getValue().set(OPERATION_UNSENT);
                        }
                        this.sendingRequests.clear();
 
                        // CLear all requests which have not been acked by the peer: they result in failure
-                       for (final Entry<SrpIdNumber, Promise<OperationResult>> e : this.waitingRequests.entrySet()) {
+                       for (final Entry<SrpIdNumber, SettableFuture<OperationResult>> e : this.waitingRequests.entrySet()) {
                                LOG.info("Request {} was incomplete when session went down, failing the instruction", e.getKey());
-                               e.getValue().setSuccess(OPERATION_NOACK);
+                               e.getValue().set(OPERATION_NOACK);
                        }
                        this.waitingRequests.clear();
                }
@@ -265,10 +266,10 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
                                                case Active:
                                                case Down:
                                                case Up:
-                                                       final Promise<OperationResult> p = this.waitingRequests.remove(id);
+                                                       final SettableFuture<OperationResult> p = this.waitingRequests.remove(id);
                                                        if (p != null) {
                                                                LOG.debug("Request {} resulted in LSP operational state {}", id, lsp.getOperational());
-                                                               p.setSuccess(OPERATION_SUCCESS);
+                                                               p.set(OPERATION_SUCCESS);
                                                        } else {
                                                                LOG.warn("Request ID {} not found in outstanding DB", id);
                                                        }
@@ -327,19 +328,19 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
                }
 
                private synchronized void messageSendingComplete(final SrpIdNumber requestId, final io.netty.util.concurrent.Future<Void> future) {
-                       final Promise<OperationResult> promise = this.sendingRequests.remove(requestId);
+                       final SettableFuture<OperationResult> promise = this.sendingRequests.remove(requestId);
 
                        if (future.isSuccess()) {
                                this.waitingRequests.put(requestId, promise);
                        } else {
                                LOG.info("Failed to send request {}, instruction cancelled", requestId, future.cause());
-                               promise.setSuccess(OPERATION_UNSENT);
+                               promise.set(OPERATION_UNSENT);
                        }
                }
 
-               private synchronized io.netty.util.concurrent.Future<OperationResult> sendMessage(final Message message, final SrpIdNumber requestId) {
+               private synchronized ListenableFuture<OperationResult> sendMessage(final Message message, final SrpIdNumber requestId) {
                        final io.netty.util.concurrent.Future<Void> f = this.session.sendMessage(message);
-                       final Promise<OperationResult> ret = ServerSessionManager.this.exec.newPromise();
+                       final SettableFuture<OperationResult> ret = SettableFuture.create();
 
                        this.sendingRequests.put(requestId, ret);
 
@@ -378,13 +379,10 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
        private final Map<NodeId, SessionListener> nodes = new HashMap<>();
        private final InstanceIdentifier<Topology> topology;
        private final DataProviderService dataProvider;
-       private final EventExecutor exec;
 
-       public ServerSessionManager(final EventExecutor exec, final DataProviderService dataProvider,
-                       final InstanceIdentifier<Topology> topology) {
+       public ServerSessionManager(final DataProviderService dataProvider, final InstanceIdentifier<Topology> topology) {
                this.dataProvider = Preconditions.checkNotNull(dataProvider);
                this.topology = Preconditions.checkNotNull(topology);
-               this.exec = Preconditions.checkNotNull(exec);
        }
 
        @Override
@@ -392,12 +390,12 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
                return new SessionListener();
        }
 
-       synchronized io.netty.util.concurrent.Future<OperationResult> realAddLsp(final AddLspArgs input) {
+       synchronized ListenableFuture<OperationResult> realAddLsp(final AddLspArgs input) {
                // Get the listener corresponding to the node
                final SessionListener l = this.nodes.get(input.getNode());
                if (l == null) {
                        LOG.debug("Session for node {} not found", input.getNode());
-                       return this.exec.newSucceededFuture(OPERATION_UNSENT);
+                       return Futures.immediateFuture(OPERATION_UNSENT);
                }
 
                // Make sure there is no such LSP
@@ -405,7 +403,7 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
                                new ReportedLspsKey(input.getName())).toInstance();
                if (this.dataProvider.readOperationalData(lsp) != null) {
                        LOG.debug("Node {} already contains lsp {} at {}", input.getNode(), input.getName(), lsp);
-                       return this.exec.newSucceededFuture(OPERATION_UNSENT);
+                       return Futures.immediateFuture(OPERATION_UNSENT);
                }
 
                // Build the request
@@ -435,12 +433,12 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
                };
        }
 
-       synchronized io.netty.util.concurrent.Future<OperationResult> realRemoveLsp(final RemoveLspArgs input) {
+       synchronized ListenableFuture<OperationResult> realRemoveLsp(final RemoveLspArgs input) {
                // Get the listener corresponding to the node
                final SessionListener l = this.nodes.get(input.getNode());
                if (l == null) {
                        LOG.debug("Session for node {} not found", input.getNode());
-                       return this.exec.newSucceededFuture(OPERATION_UNSENT);
+                       return Futures.immediateFuture(OPERATION_UNSENT);
                }
 
                // Make sure the LSP exists, we need it for PLSP-ID
@@ -449,7 +447,7 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
                final ReportedLsps rep = (ReportedLsps) this.dataProvider.readOperationalData(lsp);
                if (rep == null) {
                        LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
-                       return this.exec.newSucceededFuture(OPERATION_UNSENT);
+                       return Futures.immediateFuture(OPERATION_UNSENT);
                }
 
                // Build the request and send it
@@ -462,12 +460,12 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
                return l.sendMessage(new PcinitiateBuilder().setPcinitiateMessage(ib.build()).build(), rb.getSrp().getOperationId());
        }
 
-       synchronized io.netty.util.concurrent.Future<OperationResult> realUpdateLsp(final UpdateLspArgs input) {
+       synchronized ListenableFuture<OperationResult> realUpdateLsp(final UpdateLspArgs input) {
                // Get the listener corresponding to the node
                final SessionListener l = this.nodes.get(input.getNode());
                if (l == null) {
                        LOG.debug("Session for node {} not found", input.getNode());
-                       return this.exec.newSucceededFuture(OPERATION_UNSENT);
+                       return Futures.immediateFuture(OPERATION_UNSENT);
                }
 
                // Make sure the LSP exists
@@ -476,7 +474,7 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
                final ReportedLsps rep = (ReportedLsps) this.dataProvider.readOperationalData(lsp);
                if (rep == null) {
                        LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
-                       return this.exec.newSucceededFuture(OPERATION_UNSENT);
+                       return Futures.immediateFuture(OPERATION_UNSENT);
                }
 
                // Build the PCUpd request and send it
index 1089da48d5a2f95bb856c1b2cbea974077ab76f3..7c7887cf2b0775186bc0672b27392c2191beb677 100644 (file)
@@ -7,18 +7,10 @@
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
-import io.netty.util.concurrent.EventExecutor;
-import io.netty.util.concurrent.FutureListener;
-import io.netty.util.concurrent.Promise;
-
-import java.util.concurrent.Future;
-
-import org.opendaylight.bgpcep.programming.spi.ExecutionResult;
+import org.opendaylight.bgpcep.pcep.topology.spi.AbstractTopologyProgrammingExecutor;
 import org.opendaylight.bgpcep.programming.spi.InstructionExecutor;
 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
 import org.opendaylight.bgpcep.programming.spi.SuccessfulRpcResult;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.InstructionStatus;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.instruction.status.changed.Details;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.FailureBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.failure.Failure;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.NetworkTopologyPcepProgrammingService;
@@ -31,77 +23,33 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitUpdateLspInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitUpdateLspOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitUpdateLspOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.FailureType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
 import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 
 /**
  *
  */
 final class TopologyProgramming implements NetworkTopologyPcepProgrammingService {
-       private abstract class AbstractInstructionExecutor implements InstructionExecutor {
-
-               protected abstract io.netty.util.concurrent.Future<OperationResult> executeImpl();
-
-               @Override
-               public final io.netty.util.concurrent.Future<ExecutionResult<Details>> execute() {
-                       final Promise<ExecutionResult<Details>> promise = exec.newPromise();
-
-                       executeImpl().addListener(new FutureListener<OperationResult>() {
-                               @Override
-                               public void operationComplete(final io.netty.util.concurrent.Future<OperationResult> future) {
-                                       if (future.isSuccess()) {
-                                               final OperationResult res = future.getNow();
-                                               final FailureType fail = res.getFailure();
-
-                                               final ExecutionResult<Details> result;
-                                               if (fail != null) {
-                                                       switch (fail) {
-                                                       case Failed:
-                                                       case NoAck:
-                                                               result = new ExecutionResult<Details>(InstructionStatus.Failed, null);
-                                                               break;
-                                                       case Unsent:
-                                                               result = new ExecutionResult<Details>(InstructionStatus.Cancelled, null);
-                                                               break;
-                                                       }
-
-                                                       throw new IllegalStateException("Unhandled operation state " + fail);
-                                               } else {
-                                                       result = new ExecutionResult<Details>(InstructionStatus.Successful, null);
-                                               }
-
-                                               promise.setSuccess(result);
-                                       } else {
-                                               promise.setFailure(future.cause());
-                                       }
-                               }
-                       });
-
-                       return promise;
-               }
-       }
-
        private final InstructionScheduler scheduler;
        private final ServerSessionManager manager;
-       private final EventExecutor exec;
 
-       TopologyProgramming(final EventExecutor executor, final InstructionScheduler scheduler, final ServerSessionManager manager) {
+       TopologyProgramming(final InstructionScheduler scheduler, final ServerSessionManager manager) {
                this.scheduler = Preconditions.checkNotNull(scheduler);
                this.manager = Preconditions.checkNotNull(manager);
-               this.exec = Preconditions.checkNotNull(executor);
        }
 
        @Override
-       public Future<RpcResult<SubmitAddLspOutput>> submitAddLsp(final SubmitAddLspInput input) {
+       public ListenableFuture<RpcResult<SubmitAddLspOutput>> submitAddLsp(final SubmitAddLspInput input) {
                Preconditions.checkArgument(input.getNode() != null);
                Preconditions.checkArgument(input.getName() != null);
 
-               final InstructionExecutor e = new AbstractInstructionExecutor() {
+               final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
                        @Override
-                       public io.netty.util.concurrent.Future<OperationResult> executeImpl() {
+                       public ListenableFuture<OperationResult> executeImpl() {
                                return manager.realAddLsp(input);
                        }
                };
@@ -113,17 +61,17 @@ final class TopologyProgramming implements NetworkTopologyPcepProgrammingService
                }
 
                final RpcResult<SubmitAddLspOutput> res = SuccessfulRpcResult.create(b.build());
-               return exec.newSucceededFuture(res);
+               return Futures.immediateFuture(res);
        }
 
        @Override
-       public Future<RpcResult<SubmitRemoveLspOutput>> submitRemoveLsp(final SubmitRemoveLspInput input) {
+       public ListenableFuture<RpcResult<SubmitRemoveLspOutput>> submitRemoveLsp(final SubmitRemoveLspInput input) {
                Preconditions.checkArgument(input.getNode() != null);
                Preconditions.checkArgument(input.getName() != null);
 
-               final InstructionExecutor e = new AbstractInstructionExecutor() {
+               final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
                        @Override
-                       protected io.netty.util.concurrent.Future<OperationResult> executeImpl() {
+                       protected ListenableFuture<OperationResult> executeImpl() {
                                return manager.realRemoveLsp(input);
                        }
                };
@@ -135,17 +83,17 @@ final class TopologyProgramming implements NetworkTopologyPcepProgrammingService
                }
 
                final RpcResult<SubmitRemoveLspOutput> res = SuccessfulRpcResult.create(b.build());
-               return exec.newSucceededFuture(res);
+               return Futures.immediateFuture(res);
        }
 
        @Override
-       public Future<RpcResult<SubmitUpdateLspOutput>> submitUpdateLsp(final SubmitUpdateLspInput input) {
+       public ListenableFuture<RpcResult<SubmitUpdateLspOutput>> submitUpdateLsp(final SubmitUpdateLspInput input) {
                Preconditions.checkArgument(input.getNode() != null);
                Preconditions.checkArgument(input.getName() != null);
 
-               final InstructionExecutor e = new AbstractInstructionExecutor() {
+               final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
                        @Override
-                       protected io.netty.util.concurrent.Future<OperationResult> executeImpl() {
+                       protected ListenableFuture<OperationResult> executeImpl() {
                                return manager.realUpdateLsp(input);
                        }
                };
@@ -157,7 +105,7 @@ final class TopologyProgramming implements NetworkTopologyPcepProgrammingService
                }
 
                final RpcResult<SubmitUpdateLspOutput> res = SuccessfulRpcResult.create(b.build());
-               return exec.newSucceededFuture(res);
+               return Futures.immediateFuture(res);
        }
 
 }
index 96490a9c458ea281bd40d96808bec2cac9235a75..070bfe171e1631aafaff96806b91faee4637faa0 100644 (file)
@@ -7,10 +7,6 @@
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
-import io.netty.util.concurrent.EventExecutor;
-import io.netty.util.concurrent.FutureListener;
-import io.netty.util.concurrent.Promise;
-
 import java.util.concurrent.Future;
 
 import org.opendaylight.bgpcep.programming.spi.SuccessfulRpcResult;
@@ -27,68 +23,44 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspOutputBuilder;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
+import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
 
 final class TopologyRPCs implements NetworkTopologyPcepService {
        private final ServerSessionManager manager;
-       private final EventExecutor exec;
-
-       private abstract class ExecutionResultAdaptor<T> implements FutureListener<OperationResult> {
-               protected final Promise<RpcResult<T>> promise = exec.newPromise();
-
-               protected abstract RpcResult<T> convertResult(OperationResult result);
 
-               @Override
-               public final void operationComplete(final io.netty.util.concurrent.Future<OperationResult> future) {
-                       if (future.isSuccess()) {
-                               promise.setSuccess(convertResult(future.getNow()));
-                       } else {
-                               promise.setFailure(future.cause());
-                       }
-               }
-       }
-
-       TopologyRPCs(final EventExecutor exec, final ServerSessionManager manager) {
+       TopologyRPCs(final ServerSessionManager manager) {
                this.manager = Preconditions.checkNotNull(manager);
-               this.exec = Preconditions.checkNotNull(exec);
        }
 
        @Override
        public Future<RpcResult<AddLspOutput>> addLsp(final AddLspInput input) {
-               final ExecutionResultAdaptor<AddLspOutput> adaptor = new ExecutionResultAdaptor<AddLspOutput>() {
+               return Futures.transform(manager.realAddLsp(input), new Function<OperationResult, RpcResult<AddLspOutput>>() {
                        @Override
-                       protected RpcResult<AddLspOutput> convertResult(final OperationResult result) {
-                               return SuccessfulRpcResult.create(new AddLspOutputBuilder(result).build());
+                       public RpcResult<AddLspOutput> apply(final OperationResult input) {
+                               return SuccessfulRpcResult.create(new AddLspOutputBuilder(input).build());
                        }
-               };
-
-               manager.realAddLsp(input).addListener(adaptor);
-               return adaptor.promise;
+               });
        }
 
        @Override
        public Future<RpcResult<RemoveLspOutput>> removeLsp(final RemoveLspInput input) {
-               final ExecutionResultAdaptor<RemoveLspOutput> adaptor = new ExecutionResultAdaptor<RemoveLspOutput>() {
+               return Futures.transform(manager.realRemoveLsp(input), new Function<OperationResult, RpcResult<RemoveLspOutput>>() {
                        @Override
-                       protected RpcResult<RemoveLspOutput> convertResult(final OperationResult result) {
-                               return SuccessfulRpcResult.create(new RemoveLspOutputBuilder(result).build());
+                       public RpcResult<RemoveLspOutput> apply(final OperationResult input) {
+                               return SuccessfulRpcResult.create(new RemoveLspOutputBuilder(input).build());
                        }
-               };
-
-               manager.realRemoveLsp(input).addListener(adaptor);
-               return adaptor.promise;
+               });
        }
 
        @Override
        public Future<RpcResult<UpdateLspOutput>> updateLsp(final UpdateLspInput input) {
-               final ExecutionResultAdaptor<UpdateLspOutput> adaptor = new ExecutionResultAdaptor<UpdateLspOutput>() {
+               return Futures.transform(manager.realUpdateLsp(input), new Function<OperationResult, RpcResult<UpdateLspOutput>>() {
                        @Override
-                       protected RpcResult<UpdateLspOutput> convertResult(final OperationResult result) {
-                               return SuccessfulRpcResult.create(new UpdateLspOutputBuilder(result).build());
+                       public RpcResult<UpdateLspOutput> apply(final OperationResult input) {
+                               return SuccessfulRpcResult.create(new UpdateLspOutputBuilder(input).build());
                        }
-               };
-
-               manager.realUpdateLsp(input).addListener(adaptor);
-               return adaptor.promise;
+               });
        }
 }
diff --git a/pcep/topology-spi/.project b/pcep/topology-spi/.project
new file mode 100644 (file)
index 0000000..3f9382f
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>pcep-topology-spi</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.m2e.core.maven2Builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.pde.PluginNature</nature>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>org.eclipse.m2e.core.maven2Nature</nature>
+       </natures>
+</projectDescription>
diff --git a/pcep/topology-spi/pom.xml b/pcep/topology-spi/pom.xml
new file mode 100644 (file)
index 0000000..f097583
--- /dev/null
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<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">
+
+       <parent>
+               <groupId>org.opendaylight.bgpcep</groupId>
+               <artifactId>pcep-parent</artifactId>
+               <version>0.3.0-SNAPSHOT</version>
+       </parent>
+
+       <modelVersion>4.0.0</modelVersion>
+       <artifactId>pcep-topology-spi</artifactId>
+       <description>PCEP Topology SPI</description>
+       <packaging>bundle</packaging>
+       <name>${project.artifactId}</name>
+       <prerequisites>
+               <maven>3.0.4</maven>
+       </prerequisites>
+
+       <dependencies>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>topology-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>programming-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>programming-spi</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-topology-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.slf4j</groupId>
+                       <artifactId>slf4j-api</artifactId>
+                       <version>${slf4j.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>mockito-configuration</artifactId>
+            <version>${project.version}</version>
+                       <scope>test</scope>
+        </dependency>
+
+        <!-- FIXME: integrate with config to get rid of this -->
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-impl</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-spi</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+       </dependencies>
+
+       <build>
+        <plugins>
+           <plugin>
+               <groupId>org.apache.felix</groupId>
+               <artifactId>maven-bundle-plugin</artifactId>
+               <version>${maven.bundle.version}</version>
+               <extensions>true</extensions>
+               <configuration>
+                   <instructions>
+                       <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+                       <Export-Package>
+                           org.opendaylight.bgpcep.pcep.topology.spi
+                       </Export-Package>
+                   </instructions>
+               </configuration>
+           </plugin>
+               </plugins>
+       </build>
+
+       <distributionManagement>
+               <site>
+                       <id>${project.artifactId}</id>
+                       <name>PCEP-TOPOLOGY-SPI Module site</name>
+                       <url>${basedir}/target/site/${project.artifactId}</url>
+               </site>
+       </distributionManagement>
+
+</project>
diff --git a/pcep/topology-spi/src/main/java/org/opendaylight/bgpcep/pcep/topology/spi/AbstractTopologyProgrammingExecutor.java b/pcep/topology-spi/src/main/java/org/opendaylight/bgpcep/pcep/topology/spi/AbstractTopologyProgrammingExecutor.java
new file mode 100644 (file)
index 0000000..81418fb
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.pcep.topology.spi;
+
+import org.opendaylight.bgpcep.programming.spi.ExecutionResult;
+import org.opendaylight.bgpcep.programming.spi.InstructionExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.InstructionStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.instruction.status.changed.Details;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.FailureType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
+
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+public abstract class AbstractTopologyProgrammingExecutor implements InstructionExecutor {
+
+       protected abstract ListenableFuture<OperationResult> executeImpl();
+
+       @Override
+       public final ListenableFuture<ExecutionResult<Details>> execute() {
+               return Futures.transform(executeImpl(), new Function<OperationResult, ExecutionResult<Details>>() {
+
+                       @Override
+                       public ExecutionResult<Details> apply(final OperationResult input) {
+                               final FailureType fail = input.getFailure();
+                               if (fail == null) {
+                                       return new ExecutionResult<Details>(InstructionStatus.Successful, null);
+                               }
+
+                               switch (fail) {
+                               case Failed:
+                               case NoAck:
+                                       return new ExecutionResult<Details>(InstructionStatus.Failed, null);
+                               case Unsent:
+                                       return new ExecutionResult<Details>(InstructionStatus.Cancelled, null);
+                               }
+
+                               throw new IllegalStateException("Unhandled operation state " + fail);
+                       }
+               });
+       }
+}
index 991806064be1a924c6305b3412fc54752a7e1680..67b6c24837c7da96c9f5ec3b9ffee63555a14426 100644 (file)
@@ -3,11 +3,10 @@ module topology-tunnel-pcep-programming {
         namespace "urn:opendaylight:params:xml:ns:yang:topology:tunnel:pcep:programming";
         prefix "ttpp";
 
-        import network-topology { prefix nt; revision-date 2013-10-21; }
        import pcep-types { prefix pcep; revision-date 2013-10-05; }
-        import programming { prefix pgm; revision-date 2013-09-30; }
-        import topology-tunnel { prefix tt; revision-date 2013-08-19; }
         import topology-tunnel-programming { prefix ttp; revision-date 2013-09-30; }
+       import topology-tunnel-p2p { prefix p2p; revision-date 2013-08-19; }
+       import topology-tunnel-pcep { prefix ptp; }
 
         organization "Cisco Systems, Inc.";
         contact "Robert Varga <rovarga@cisco.com>";
@@ -29,35 +28,15 @@ module topology-tunnel-pcep-programming {
                 reference "";
         }
 
-       rpc pcep-create-tunnel {
+       rpc pcep-create-p2p-tunnel {
                input {
-                       uses ttp:create-tunnel-input;
+                       uses ttp:create-p2p-tunnel-input;
 
-                       leaf symbolic-path-name {
-                               type pcep:symbolic-path-name;
-                               mandatory true;
-                       }
-
-                       container endpoints {
-                               uses pcep:endpoints;
-                       }
-
-                       leaf signaling-type {
-                               // FIXME: dedicated type in PCEP
-                               type uint8;
-                               default 0;
-                       }
-
-                       leaf administrative {
-                               type boolean;
-                               default true;
-                       }
-
-                       // FIXME: ERO
-                       // FIXME: attribute-list
+                       uses p2p:tunnel-p2p-path-cfg-attributes;
+                       uses ptp:tunnel-pcep-link-cfg-attributes;
                }
                output {
-                       uses ttp:create-tunnel-output;
+                       uses ttp:create-p2p-tunnel-output;
                }
        }
 
@@ -72,22 +51,14 @@ module topology-tunnel-pcep-programming {
 
        rpc pcep-update-tunnel {
                input {
-                       container update-tunnel {
-                                leaf topology-id {
-                                        type nt:topology-id;
-                                        mandatory true;
-                                }
-                                leaf link-id {
-                                        type nt:link-id;
-                                        mandatory true;
-                                }
+                       uses ttp:base-tunnel-input;
 
-                               // FIXME: all that PCUpd jazz
-                       }
+                       uses p2p:tunnel-p2p-path-cfg-attributes;
+                       uses ptp:tunnel-pcep-link-cfg-attributes;
                }
 
                output {
-                       uses pgm:submit-instruction-output;
+                       uses ttp:base-tunnel-output;
                }
        }
 }
index e17563e6e78979dd3ce0848b67b4419f74ff22a9..4e2f54cd81dbdbd90a11692310875757681a6ea7 100644 (file)
@@ -4,8 +4,8 @@ module topology-tunnel-pcep {
        namespace "urn:opendaylight:params:xml:ns:yang:topology:tunnel:pcep";
        prefix "pceptun";
 
-       import ieee754 { prefix ieee754; revision-date 2013-08-19; }
        import network-topology { prefix nt; revision-date 2013-10-21; }
+    import nps-concepts { prefix nps-c; }
        import pcep-types { prefix pcep; revision-date 2013-10-05; }
        import rsvp { prefix rsvp; revision-date 2013-08-20; }
        import topology-tunnel { prefix tt; revision-date 2013-08-19; }
@@ -34,6 +34,31 @@ module topology-tunnel-pcep {
                reference "https://tools.ietf.org/html/draft-ietf-pce-stateful-pce-05#section-7.3";
        }
 
+       grouping topology-tunnel-pcep-type {
+               container topology-tunnel-pcep {
+                       presence "indicates a PCEP tunnel-aware topology";
+               }
+       }
+
+       augment "/nt:network-topology/nt:topology/nt:topology-types" {
+               uses topology-tunnel-pcep-type;
+       }
+
+    grouping tunnel-pcep-supporting-node-attributes {
+        container path-computation-client {
+            leaf controlling {
+                type boolean;
+                default false;
+            }
+        }
+    }
+
+       augment "/nt:network-topology/nt:topology/nt:node/nt:supporting-node" {
+        when "../../../nt:topology-types/topology-tunnel-pcep";
+
+        uses tunnel-pcep-supporting-node-attributes;
+    }
+
        grouping tunnel-pcep-type {
                container pcep-tunnel {
                        presence "indicates a link is a PCEP tunnel";
@@ -44,22 +69,30 @@ module topology-tunnel-pcep {
                uses tunnel-pcep-type;
        }
 
-       grouping tunnel-pcep-link-attributes {
+       grouping tunnel-pcep-link-cfg-attributes {
                leaf administrative-status {
                        type administrative-status;
                }
 
-               leaf operational-status {
-                       type pcep:operational-status;
-                       config false;
-               }
-
                leaf class-type {
                        type pcep:class-type;
                }
 
                leaf bandwidth {
-                       type ieee754:float32;
+                       type nps-c:bandwidth;
+               }
+
+        leaf symbolic-path-name {
+            type pcep:symbolic-path-name;
+        }
+
+        uses rsvp:tunnel-attributes;
+       }
+
+       grouping tunnel-pcep-link-oper-attributes {
+               leaf operational-status {
+                       type pcep:operational-status;
+                       config false;
                }
        }
 
@@ -76,7 +109,8 @@ module topology-tunnel-pcep {
 
        augment "/nt:network-topology/nt:topology/nt:link" {
                when "../../tunnel-types/pcep-tunnel";
-               uses tunnel-pcep-link-attributes;
+               uses tunnel-pcep-link-cfg-attributes;
+               uses tunnel-pcep-link-oper-attributes;
        }
 
        augment "/nt:network-topology/nt:topology/tt:paths" {
index 409ca13d618b69d7124358312e0a9ec32706a92a..8e2dcf219e612151502f1ae12981515c00db548b 100644 (file)
                <dependency>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>pcep-topology-api</artifactId>
+            <version>${project.version}</version>
+               </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>pcep-topology-spi</artifactId>
             <version>${project.version}</version>
                </dependency>
                <dependency>
index 361a641038cf4603013a0180df4d7281bd02c4e1..8bea183e83d09354df8d01e99fefede559ddeeb6 100644 (file)
@@ -1,8 +1,10 @@
 package org.opendaylight.bgpcep.pcep.tunnel.provider;
 
+import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
 import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.NetworkTopologyPcepService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -18,5 +20,8 @@ public final class BundleActivator extends AbstractBindingAwareProvider {
                // FIXME: migrate to config subsystem
                final TunnelTopologyExporter tte = new TunnelTopologyExporter(dps, null);
                tte.addTargetTopology(null);
+
+               final InstructionScheduler scheduler = null;
+               final TunnelProgramming tp = new TunnelProgramming(scheduler, dps, session.getRpcService(NetworkTopologyPcepService.class));
        }
 }
index a81fcb0b4a9508d197d1cf36857c2f4c459df53c..8d939a28286c92dce007cb2a1c5106f88f058c84 100644 (file)
@@ -16,8 +16,13 @@ import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
 import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.SymbolicPathName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLsps;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -77,4 +82,10 @@ final class NodeChangedListener implements DataChangeListener {
                        LOG.error("Failed to propagate a topology change, target topology became inconsistent", e);
                }
        }
-}
\ No newline at end of file
+
+       public static InstanceIdentifier<Link> linkIdentifier(final InstanceIdentifier<Topology> topology,
+                       final NodeId node, final SymbolicPathName name) {
+               return InstanceIdentifier.builder(topology).
+                               node(Link.class, new LinkKey(new LinkId(node.getValue() + "/lsp/" + name))).toInstance();
+       }
+}
diff --git a/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelInstructionExecutor.java b/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/PCEPTunnelInstructionExecutor.java
deleted file mode 100644 (file)
index d8928e1..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.bgpcep.pcep.tunnel.provider;
-
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.topology.pcep.type.TopologyPcep;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
-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;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-public final class PCEPTunnelInstructionExecutor {
-       private static final Logger LOG = LoggerFactory.getLogger(PCEPTunnelInstructionExecutor.class);
-       private final InstanceIdentifier<Topology> underlay;
-       private final InstanceIdentifier<Topology> target;
-       private final DataProviderService dps;
-
-       private PCEPTunnelInstructionExecutor(final DataProviderService dps, final InstanceIdentifier<Topology> underlay,
-                       final InstanceIdentifier<Topology> target, final TopologyId topologyId) {
-               this.dps = Preconditions.checkNotNull(dps);
-               this.underlay = Preconditions.checkNotNull(underlay);
-               this.target = Preconditions.checkNotNull(target);
-       }
-
-       public static PCEPTunnelInstructionExecutor create(final DataProviderService dps, final InstanceIdentifier<Topology> underlay,
-                       final TopologyId targetId) {
-               Preconditions.checkNotNull(dps);
-               Preconditions.checkNotNull(targetId);
-
-               // Topology pointer
-               final InstanceIdentifier<Topology> target = InstanceIdentifier.builder().node(NetworkTopology.class).
-                               node(Topology.class, new TopologyKey(targetId)).toInstance();
-
-               // Now check if there is a container identifying the topology as PCEP-aware
-               final InstanceIdentifier<TopologyPcep> i = InstanceIdentifier.builder(target).node(TopologyTypes.class).node(TopologyPcep.class).toInstance();
-               final DataObject ttt = dps.readOperationalData(i);
-               Preconditions.checkArgument(ttt != null, "Specified topology does not list topology-pcep as its type");
-
-               return new PCEPTunnelInstructionExecutor(dps, underlay, target, targetId);
-       }
-}
diff --git a/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java b/pcep/tunnel-provider/src/main/java/org/opendaylight/bgpcep/pcep/tunnel/provider/TunnelProgramming.java
new file mode 100644 (file)
index 0000000..0bea03f
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.bgpcep.pcep.tunnel.provider;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.bgpcep.pcep.topology.spi.AbstractTopologyProgrammingExecutor;
+import org.opendaylight.bgpcep.programming.spi.InstructionExecutor;
+import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
+import org.opendaylight.bgpcep.programming.spi.SuccessfulRpcResult;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.bandwidth.object.BandwidthBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.classtype.object.ClassTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.EndpointsObjBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.EroBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.Subobjects;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.ero.SubobjectsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.LspaBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.FailureBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.submit.instruction.output.result.failure.Failure;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.NetworkTopologyPcepService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.RemoveLspInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.RemoveLspOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.add.lsp.args.ArgumentsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.programming.rev131102.TopologyInstructionInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.p2p.rev130819.tunnel.p2p.path.cfg.attributes.ExplicitHops;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepCreateP2pTunnelOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepDestroyTunnelInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepDestroyTunnelOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepDestroyTunnelOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepUpdateTunnelInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepUpdateTunnelOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.PcepUpdateTunnelOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev131030.TopologyTunnelPcepProgrammingService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.AdministrativeStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.ExplicitHops1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.Link1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev130820.SupportingNode1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.BaseTunnelInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.TpReference;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNode;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.TerminationPoint1;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.igp.termination.point.attributes.TerminationPointType;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.igp.termination.point.attributes.termination.point.type.Ip;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+final class TunnelProgramming implements TopologyTunnelPcepProgrammingService {
+       private static final Logger LOG = LoggerFactory.getLogger(TunnelProgramming.class);
+       private final NetworkTopologyPcepService topologyService;
+       private final DataProviderService dataProvider;
+       private final InstructionScheduler scheduler;
+
+       TunnelProgramming(final InstructionScheduler scheduler, final DataProviderService dataProvider,
+                       final NetworkTopologyPcepService topologyService) {
+               this.scheduler = Preconditions.checkNotNull(scheduler);
+               this.dataProvider = Preconditions.checkNotNull(dataProvider);
+               this.topologyService = Preconditions.checkNotNull(topologyService);
+       }
+
+       private static final class TpReader {
+               private final DataModificationTransaction t;
+               private final InstanceIdentifier<Node> nii;
+               private final InstanceIdentifier<TerminationPoint> tii;
+
+               TpReader(final DataModificationTransaction t, final InstanceIdentifier<Topology> topo, final TpReference ref) {
+                       this.t = Preconditions.checkNotNull(t);
+
+                       nii = InstanceIdentifier.builder(topo).node(Node.class, new NodeKey(ref.getNode())).toInstance();
+                       tii = InstanceIdentifier.builder(nii).node(TerminationPoint.class, new TerminationPointKey(ref.getTp())).toInstance();
+               }
+
+               private Node getNode() {
+                       return (Node) t.readOperationalData(nii);
+               }
+
+               private TerminationPoint getTp() {
+                       return (TerminationPoint) t.readOperationalData(tii);
+               }
+       }
+
+       private AddressFamily buildAddressFamily(final TerminationPoint sp, final TerminationPoint dp) {
+               // We need the IGP augmentation -- it has IP addresses
+               final TerminationPoint1 sp1 = Preconditions.checkNotNull(sp.getAugmentation(TerminationPoint1.class));
+               final TerminationPoint1 dp1 = Preconditions.checkNotNull(dp.getAugmentation(TerminationPoint1.class));
+
+               // Get the types
+               final TerminationPointType spt = sp1.getIgpTerminationPointAttributes().getTerminationPointType();
+               final TerminationPointType dpt = dp1.getIgpTerminationPointAttributes().getTerminationPointType();
+
+               // The types have to match
+               Preconditions.checkArgument(spt.getImplementedInterface().equals(dpt.getImplementedInterface()));
+
+               // And they have to actually be Ip
+               final Ip sips = (Ip) spt;
+               final Ip dips = (Ip) dpt;
+
+               /*
+                * Now a bit of magic. We need to find 'like' addresses, e.g. both
+                * IPv4 or both IPv6. We are in IPv6-enabled world now, so let's
+                * prefer that.
+                */
+               AddressFamily ret = findIpv6(sips.getIpAddress(), dips.getIpAddress());
+               if (ret == null) {
+                       ret = findIpv4(sips.getIpAddress(), dips.getIpAddress());
+               }
+
+               // We need to have a ret now
+               Preconditions.checkArgument(ret != null, "Failed to find like Endpoint addresses");
+
+               return ret;
+       }
+
+       private AddressFamily findIpv4(final List<IpAddress> srcs, final List<IpAddress> dsts) {
+               for (final IpAddress sc : srcs) {
+                       if (sc.getIpv4Address() != null) {
+                               for (final IpAddress dc : dsts) {
+                                       if (dc.getIpv4Address() != null) {
+                                               return new Ipv4Builder().
+                                                               setSourceIpv4Address(sc.getIpv4Address()).
+                                                               setDestinationIpv4Address(dc.getIpv4Address()).build();
+                                       }
+                               }
+                       }
+               }
+
+               return null;
+       }
+
+       private AddressFamily findIpv6(final List<IpAddress> srcs, final List<IpAddress> dsts) {
+               for (final IpAddress sc : srcs) {
+                       if (sc.getIpv6Address() != null) {
+                               for (final IpAddress dc : dsts) {
+                                       if (dc.getIpv6Address() != null) {
+                                               return new Ipv6Builder().
+                                                               setSourceIpv6Address(sc.getIpv6Address()).
+                                                               setDestinationIpv6Address(dc.getIpv6Address()).build();
+                                       }
+                               }
+                       }
+               }
+
+               return null;
+       }
+
+       private NodeId supportingNode(final DataModificationTransaction t, final Node node) {
+               for (SupportingNode n : node.getSupportingNode()) {
+                       final SupportingNode1 n1 = n.getAugmentation(SupportingNode1.class);
+                       if (n1 != null && n1.getPathComputationClient().isControlling()) {
+                               return n.getKey().getNodeRef();
+                       }
+               }
+
+               return null;
+       }
+
+       private Ero buildEro(final List<ExplicitHops> explicitHops) {
+               final EroBuilder b = new EroBuilder();
+
+               if (!explicitHops.isEmpty()) {
+                       final List<Subobjects> subobjs = new ArrayList<>(explicitHops.size());
+                       for (ExplicitHops h : explicitHops) {
+
+                               final ExplicitHops1 h1 = h.getAugmentation(ExplicitHops1.class);
+                               if (h1 != null) {
+                                       final SubobjectsBuilder sb = new SubobjectsBuilder();
+                                       sb.fieldsFrom(h1);
+                                       sb.setLoose(h.isLoose());
+                                       subobjs.add(sb.build());
+                               } else {
+                                       LOG.debug("Ignoring unhandled explicit hop {}", h);
+                               }
+                       }
+                       b.setSubobjects(subobjs);
+               }
+               return b.build();
+       }
+
+       @Override
+       public ListenableFuture<RpcResult<PcepCreateP2pTunnelOutput>> pcepCreateP2pTunnel(final PcepCreateP2pTunnelInput input) {
+               final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
+                       @Override
+                       protected ListenableFuture<OperationResult> executeImpl() {
+                               final InstanceIdentifier<Topology> tii = topologyIdentifier(input);
+
+                               final DataModificationTransaction t = dataProvider.beginTransaction();
+
+
+                               final TpReader dr = new TpReader(t, tii, input.getDestination());
+                               final TpReader sr = new TpReader(t, tii, input.getSource());
+
+                               final Node sn = Preconditions.checkNotNull(sr.getNode());
+                               final TerminationPoint sp = Preconditions.checkNotNull(sr.getTp());
+                               final TerminationPoint dp = Preconditions.checkNotNull(dr.getTp());
+
+                               final AddLspInputBuilder ab = new AddLspInputBuilder();
+                               ab.setNode(Preconditions.checkNotNull(supportingNode(t, sn)));
+                               ab.setName(Preconditions.checkNotNull(input.getSymbolicPathName()));
+
+                               // The link has to be non-existent
+                               final InstanceIdentifier<Link> lii = NodeChangedListener.linkIdentifier(tii, ab.getNode(), ab.getName());
+                               Preconditions.checkState(t.readOperationalData(lii) == null);
+
+                               final ArgumentsBuilder args = new ArgumentsBuilder();
+                               args.setAdministrative(input.getAdministrativeStatus() == AdministrativeStatus.Active);
+                               args.setBandwidth(new BandwidthBuilder().setBandwidth(input.getBandwidth()).build());
+                               args.setClassType(new ClassTypeBuilder().setClassType(input.getClassType()).build());
+                               args.setEndpointsObj(new EndpointsObjBuilder().setAddressFamily(buildAddressFamily(sp, dp)).build());
+                               args.setEro(buildEro(input.getExplicitHops()));
+                               args.setLspa(new LspaBuilder(input).build());
+
+                               ab.setArguments(args.build());
+
+                               return Futures.transform(
+                                               (ListenableFuture<RpcResult<AddLspOutput>>) topologyService.addLsp(ab.build()),
+                                               new Function<RpcResult<AddLspOutput>, OperationResult>() {
+                                                       @Override
+                                                       public OperationResult apply(final RpcResult<AddLspOutput> input) {
+                                                               return input.getResult();
+                                                       }
+                                               });
+                       }
+               };
+
+               final Failure f = this.scheduler.submitInstruction(input, e);
+               final PcepCreateP2pTunnelOutputBuilder b = new PcepCreateP2pTunnelOutputBuilder();
+               if (f != null) {
+                       b.setResult(new FailureBuilder().setFailure(f).build());
+               }
+
+               final RpcResult<PcepCreateP2pTunnelOutput> res = SuccessfulRpcResult.create(b.build());
+               return Futures.immediateFuture(res);
+       }
+
+       // FIXME: topology programming utility class
+       private InstanceIdentifier<Topology> topologyIdentifier(final TopologyInstructionInput input) {
+               return InstanceIdentifier.builder().
+                               node(NetworkTopology.class).node(Topology.class, new TopologyKey(input.getTopologyId())).toInstance();
+       }
+
+       // FIXME: tunnel programming utility class
+       private InstanceIdentifier<Link> linkIdentifier(final InstanceIdentifier<Topology> topology, final BaseTunnelInput input) {
+               return InstanceIdentifier.builder(topology).
+                               node(Link.class, new LinkKey(Preconditions.checkNotNull(input.getLinkId()))).toInstance();
+       }
+
+       private Node sourceNode(final DataModificationTransaction t, final InstanceIdentifier<Topology> topology, final Link link) {
+               final InstanceIdentifier<Node> nii = InstanceIdentifier.builder(topology).
+                               node(Node.class, new NodeKey(link.getSource().getSourceNode())).toInstance();
+               return (Node) t.readOperationalData(nii);
+       }
+
+       @Override
+       public ListenableFuture<RpcResult<PcepDestroyTunnelOutput>> pcepDestroyTunnel(final PcepDestroyTunnelInput input) {
+               final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
+                       @Override
+                       protected ListenableFuture<OperationResult> executeImpl() {
+                               final InstanceIdentifier<Topology> tii = topologyIdentifier(input);
+                               final InstanceIdentifier<Link> lii = linkIdentifier(tii, input);
+
+                               final DataModificationTransaction t = dataProvider.beginTransaction();
+
+                               // The link has to exist
+                               final Link link = (Link) t.readOperationalData(lii);
+                               Preconditions.checkState(link != null);
+
+                               // The source node has to exist
+                               final Node node = sourceNode(t, tii, link);
+                               Preconditions.checkState(node != null);
+
+                               final RemoveLspInputBuilder ab = new RemoveLspInputBuilder();
+                               ab.setName(link.getAugmentation(Link1.class).getSymbolicPathName());
+                               ab.setNode(node.getSupportingNode().get(0).getKey().getNodeRef());
+
+                               return Futures.transform(
+                                               (ListenableFuture<RpcResult<RemoveLspOutput>>) topologyService.removeLsp(ab.build()),
+                                               new Function<RpcResult<RemoveLspOutput>, OperationResult>() {
+                                                       @Override
+                                                       public OperationResult apply(final RpcResult<RemoveLspOutput> input) {
+                                                               return input.getResult();
+                                                       }
+                                               });
+                       }
+               };
+
+               final Failure f = this.scheduler.submitInstruction(input, e);
+               final PcepDestroyTunnelOutputBuilder b = new PcepDestroyTunnelOutputBuilder();
+               if (f != null) {
+                       b.setResult(new FailureBuilder().setFailure(f).build());
+               }
+
+               final RpcResult<PcepDestroyTunnelOutput> res = SuccessfulRpcResult.create(b.build());
+               return Futures.immediateFuture(res);
+       }
+
+       @Override
+       public ListenableFuture<RpcResult<PcepUpdateTunnelOutput>> pcepUpdateTunnel(final PcepUpdateTunnelInput input) {
+               final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
+                       @Override
+                       protected ListenableFuture<OperationResult> executeImpl() {
+                               final InstanceIdentifier<Topology> tii = topologyIdentifier(input);
+                               final InstanceIdentifier<Link> lii = linkIdentifier(tii, input);
+
+                               final DataModificationTransaction t = dataProvider.beginTransaction();
+
+                               // The link has to exist
+                               final Link link = (Link) t.readOperationalData(lii);
+                               Preconditions.checkState(link != null);
+
+                               // The source node has to exist
+                               final Node node = sourceNode(t, tii, link);
+                               Preconditions.checkState(node != null);
+
+                               final UpdateLspInputBuilder ab = new UpdateLspInputBuilder();
+                               ab.setName(link.getAugmentation(Link1.class).getSymbolicPathName());
+                               ab.setNode(Preconditions.checkNotNull(supportingNode(t, node)));
+
+                               final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder args =
+                                               new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder();
+
+                               args.setAdministrative(input.getAdministrativeStatus() == AdministrativeStatus.Active);
+                               args.setBandwidth(new BandwidthBuilder().setBandwidth(input.getBandwidth()).build());
+                               args.setClassType(new ClassTypeBuilder().setClassType(input.getClassType()).build());
+                               args.setEro(buildEro(input.getExplicitHops()));
+                               args.setLspa(new LspaBuilder(input).build());
+
+                               ab.setArguments(args.build());
+
+                               return Futures.transform(
+                                               (ListenableFuture<RpcResult<UpdateLspOutput>>) topologyService.updateLsp(ab.build()),
+                                               new Function<RpcResult<UpdateLspOutput>, OperationResult>() {
+                                                       @Override
+                                                       public OperationResult apply(final RpcResult<UpdateLspOutput> input) {
+                                                               return input.getResult();
+                                                       }
+                                               });
+                       }
+               };
+
+               final Failure f = this.scheduler.submitInstruction(input, e);
+               final PcepUpdateTunnelOutputBuilder b = new PcepUpdateTunnelOutputBuilder();
+               if (f != null) {
+                       b.setResult(new FailureBuilder().setFailure(f).build());
+               }
+
+               final RpcResult<PcepUpdateTunnelOutput> res = SuccessfulRpcResult.create(b.build());
+               return Futures.immediateFuture(res);
+       }
+}
index 3175d999f918d81c8c9249a66a4f5bec439072aa..246f3d6aef0fab72b8ef1c470d733b7ee73b1bd2 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.bgpcep.programming.impl;
 
 import io.netty.util.Timeout;
-import io.netty.util.concurrent.Future;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -20,6 +19,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programm
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.instruction.status.changed.Details;
 
 import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListenableFuture;
 
 final class Instruction {
        private final List<Instruction> dependants = new ArrayList<>();
@@ -44,7 +44,7 @@ final class Instruction {
                return status;
        }
 
-       Future<ExecutionResult<Details>> execute() {
+       ListenableFuture<ExecutionResult<Details>> execute() {
                return executor.execute();
        }
 
index 6213ab81e25ec12dcdea628e697dd23aae19400d..09c8a369c1fc059fdc403abdd050432ee69a8230 100644 (file)
@@ -10,8 +10,6 @@ package org.opendaylight.bgpcep.programming.impl;
 import io.netty.util.Timeout;
 import io.netty.util.Timer;
 import io.netty.util.TimerTask;
-import io.netty.util.concurrent.Future;
-import io.netty.util.concurrent.FutureListener;
 
 import java.math.BigInteger;
 import java.util.ArrayDeque;
@@ -58,6 +56,8 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
 
 final class ProgrammingServiceImpl implements InstructionScheduler, ProgrammingService {
        private static final Logger LOG = LoggerFactory.getLogger(ProgrammingServiceImpl.class);
@@ -374,15 +374,16 @@ final class ProgrammingServiceImpl implements InstructionScheduler, ProgrammingS
                                Preconditions.checkState(i.getStatus().equals(InstructionStatus.Scheduled));
 
                                transitionInstruction(i, InstructionStatus.Executing, null);
-                               final Future<ExecutionResult<Details>> f = i.execute();
-                               f.addListener(new FutureListener<ExecutionResult<?>>() {
+                               Futures.addCallback(i.execute(), new FutureCallback<ExecutionResult<Details>>() {
+
+                                       @Override
+                                       public void onSuccess(final ExecutionResult<Details> result) {
+                                               executionSuccessful(i, result);
+                                       }
+
                                        @Override
-                                       public void operationComplete(final Future<ExecutionResult<?>> future) {
-                                               if (future.isSuccess()) {
-                                                       executionSuccessful(i, future.getNow());
-                                               } else {
-                                                       executionFailed(i, future.cause());
-                                               }
+                                       public void onFailure(final Throwable t) {
+                                               executionFailed(i, t);
                                        }
                                });
                        }
index 731901ebcf1d5c8398ef7b006d3e8313ff31ffeb..5780e6a693496120a7d96794b10bae26115b7ab2 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.bgpcep.programming.spi;
 
-import io.netty.util.concurrent.Future;
-
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev130930.instruction.status.changed.Details;
 
+import com.google.common.util.concurrent.ListenableFuture;
+
 public interface InstructionExecutor {
-       Future<ExecutionResult<Details>> execute();
+       ListenableFuture<ExecutionResult<Details>> execute();
 }
index d0d196b5e93490c1324949c5e5254aff41aab0a6..471e01d9c5afd1f7f7d34df290fcdaa2ac099a09 100644 (file)
@@ -27,7 +27,7 @@ module topology-tunnel-programming {
                reference "";
        }
 
-       grouping create-tunnel-input {
+       grouping base-tunnel-input {
                uses tp:topology-instruction-input;
 
                leaf link-id {
@@ -36,12 +36,16 @@ module topology-tunnel-programming {
                }
        }
 
-       grouping create-tunnel-output {
+       grouping base-tunnel-output {
                uses tp:topology-instruction-output;
        }
 
-       grouping destroy-tunnel-input {
+       grouping create-tunnel-input {
                uses tp:topology-instruction-input;
+       }
+
+       grouping create-tunnel-output {
+               uses base-tunnel-output;
 
                leaf link-id {
                        type nt:link-id;
@@ -49,8 +53,38 @@ module topology-tunnel-programming {
                }
        }
 
+       grouping destroy-tunnel-input {
+               uses base-tunnel-input;
+       }
+
        grouping destroy-tunnel-output {
-               uses tp:topology-instruction-output;
+               uses base-tunnel-output;
+       }
+
+       grouping tp-reference {
+               leaf node {
+                       type nt:node-ref;
+                       mandatory true;
+               }
+               leaf tp {
+                       type nt:tp-ref;
+                       mandatory true;
+               }
+       }
+
+       grouping create-p2p-tunnel-input {
+               uses create-tunnel-input;
+
+               container destination {
+                       uses tp-reference;
+               }
+               container source {
+                       uses tp-reference;
+               }
+       }
+
+       grouping create-p2p-tunnel-output {
+               uses create-tunnel-output;
        }
 }
 
index 556ac16e47b33873212676639f67f3ce4671339d..a6a61931e79612b6d928fa9dd4e77b4815b5b9a7 100644 (file)
@@ -47,6 +47,25 @@ module rsvp {
                }
        }
 
+       grouping tunnel-attributes {
+               leaf hold-priority {
+                       type uint8;
+                       mandatory true;
+               }
+
+               leaf setup-priority {
+                       type uint8;
+                       mandatory true;
+               }
+
+               leaf local-protection-desired {
+                       type boolean;
+                       default false;
+               }
+
+               uses attribute-filters;
+       }
+
        typedef lsp-id {
                type uint32;
                reference "https://tools.ietf.org/html/rfc3209#section-4.6.2.1";
index e7c24d1c9c390c0fd0238e2959aeefb3980547d0..a924fa7f6ac40b4b6a34c1afa316d6437c047ad7 100644 (file)
@@ -18,7 +18,6 @@
        
        <modules>
         <module>api</module>
-        <module>provider-bgp</module>
                <module>tunnel-api</module>
         <module>segment-routing</module>
     </modules>
index d35cf7e5499b55f8167b49adf7b90622ffde15dc..24bde13e0f14a9a9fa24d91bf4ab5668965e8479 100644 (file)
@@ -43,7 +43,7 @@ module topology-tunnel-p2p {
                }
        }
 
-       grouping tunnel-p2p-path-attributes {
+       grouping tunnel-p2p-path-cfg-attributes {
                list explicit-hops {
                        uses tunnel-p2p-path-hops;
                        key order;
@@ -53,8 +53,11 @@ module topology-tunnel-p2p {
                                mandatory true;
                        }
                }
+       }
 
+       grouping tunnel-p2p-path-oper-attributes {
                list reported-hops {
+                       config false;
                        uses tunnel-p2p-path-hops;
                        key order;
                }
@@ -62,7 +65,8 @@ module topology-tunnel-p2p {
 
        augment "/nt:network-topology/nt:topology/tt:paths" {
                when "../path-types/p2p-tunnel";
-               uses tunnel-p2p-path-attributes;
+               uses tunnel-p2p-path-cfg-attributes;
+               uses tunnel-p2p-path-oper-attributes;
        }
 }