BUG-48: Tunnel integration, part 1 37/2537/3
authorRobert Varga <rovarga@cisco.com>
Thu, 7 Nov 2013 07:53:51 +0000 (08:53 +0100)
committerRobert Varga <rovarga@cisco.com>
Fri, 8 Nov 2013 12:44:56 +0000 (13:44 +0100)
Change-Id: Ib55a9b65dd0d6d535b6e5590b7b02ef355f5ae4f
Signed-off-by: Robert Varga <rovarga@cisco.com>
20 files changed:
pcep/pom.xml
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-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/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
topology/tunnel-api/src/main/yang/topology-tunnel-p2p.yang

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 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..21cb7ffa554d34763deb294dd82b8d2b5f4db53d 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.bgpcep.pcep.topology.provider;
 
 import io.netty.channel.ChannelFuture;
 import io.netty.util.HashedWheelTimer;
-import io.netty.util.concurrent.GlobalEventExecutor;
 
 import java.net.InetSocketAddress;
 import java.util.concurrent.ExecutionException;
@@ -45,7 +44,7 @@ public final class BundleActivator extends AbstractBindingAwareProvider {
                final PCEPDispatcher dispatcher = new PCEPDispatcherImpl(PCEPExtensionProviderContextImpl.getSingletonInstance().getMessageHandlerRegistry(), new DefaultPCEPSessionNegotiatorFactory(new HashedWheelTimer(), prefs, 5));
                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..eb2de0203a54505002a5ab211123f87fa8d82119 100644 (file)
@@ -3,11 +3,9 @@ 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; }
 
         organization "Cisco Systems, Inc.";
         contact "Robert Varga <rovarga@cisco.com>";
@@ -29,35 +27,14 @@ 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;
                }
                output {
-                       uses ttp:create-tunnel-output;
+                       uses ttp:create-p2p-tunnel-output;
                }
        }
 
@@ -72,22 +49,13 @@ 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;
                }
 
                output {
-                       uses pgm:submit-instruction-output;
+                       uses ttp:base-tunnel-output;
                }
        }
 }
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..754925de33f8bbb48ed32f427ebccbc92e20a877 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, session.getRpcService(NetworkTopologyPcepService.class));
        }
 }
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..963d91f
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * 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.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.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.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.yangtools.yang.common.RpcResult;
+
+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 final NetworkTopologyPcepService pcepTopology;
+       private final InstructionScheduler scheduler;
+
+       TunnelProgramming(final InstructionScheduler scheduler, final NetworkTopologyPcepService pcepTopology) {
+               this.scheduler = Preconditions.checkNotNull(scheduler);
+               this.pcepTopology = Preconditions.checkNotNull(pcepTopology);
+       }
+
+       @Override
+       public ListenableFuture<RpcResult<PcepCreateP2pTunnelOutput>> pcepCreateP2pTunnel(final PcepCreateP2pTunnelInput input) {
+               Preconditions.checkNotNull(input.getLinkId());
+               Preconditions.checkNotNull(input.getSourceTp());
+               Preconditions.checkNotNull(input.getDestinationTp());
+
+               final AddLspInputBuilder ab = new AddLspInputBuilder();
+               ab.fieldsFrom(input);
+
+               final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
+                       @Override
+                       protected ListenableFuture<OperationResult> executeImpl() {
+                               final ListenableFuture<RpcResult<AddLspOutput>> s =
+                                               (ListenableFuture<RpcResult<AddLspOutput>>) pcepTopology.addLsp(ab.build());
+
+                               return Futures.transform(s, 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);
+       }
+
+       @Override
+       public ListenableFuture<RpcResult<PcepDestroyTunnelOutput>> pcepDestroyTunnel(final PcepDestroyTunnelInput input) {
+               Preconditions.checkNotNull(input.getLinkId());
+
+               final RemoveLspInputBuilder ab = new RemoveLspInputBuilder();
+               ab.fieldsFrom(input);
+
+               final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
+                       @Override
+                       protected ListenableFuture<OperationResult> executeImpl() {
+                               final ListenableFuture<RpcResult<RemoveLspOutput>> s =
+                                               (ListenableFuture<RpcResult<RemoveLspOutput>>) pcepTopology.removeLsp(ab.build());
+
+                               return Futures.transform(s, 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) {
+               Preconditions.checkNotNull(input.getLinkId());
+
+               final UpdateLspInputBuilder ab = new UpdateLspInputBuilder();
+               ab.fieldsFrom(input);
+
+               final InstructionExecutor e = new AbstractTopologyProgrammingExecutor() {
+                       @Override
+                       protected ListenableFuture<OperationResult> executeImpl() {
+                               final ListenableFuture<RpcResult<UpdateLspOutput>> s =
+                                               (ListenableFuture<RpcResult<UpdateLspOutput>>) pcepTopology.updateLsp(ab.build());
+
+                               return Futures.transform(s, 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..fbbe2e991e8f92a7f67e23a2f2f66b0661e702ab 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,21 +36,49 @@ module topology-tunnel-programming {
                }
        }
 
-       grouping create-tunnel-output {
+       grouping base-tunnel-output {
                uses tp:topology-instruction-output;
        }
 
+       grouping create-tunnel-input {
+               uses base-tunnel-input;
+       }
+
+       grouping create-tunnel-output {
+               uses base-tunnel-output;
+       }
+
        grouping destroy-tunnel-input {
-               uses tp:topology-instruction-input;
+               uses base-tunnel-input;
+       }
 
-               leaf link-id {
-                       type nt:link-id;
+       grouping destroy-tunnel-output {
+               uses base-tunnel-output;
+       }
+
+       grouping p2p-tunnel-input {
+               uses base-tunnel-input;
+
+               leaf source-tp {
+                       type nt:tp-ref;
+                       mandatory true;
+               }
+               leaf destination-tp {
+                       type nt:tp-ref;
                        mandatory true;
                }
        }
 
-       grouping destroy-tunnel-output {
-               uses tp:topology-instruction-output;
+       grouping p2p-tunnel-output {
+               uses base-tunnel-output;
+       }
+
+       grouping create-p2p-tunnel-input {
+               uses p2p-tunnel-input;
+       }
+
+       grouping create-p2p-tunnel-output {
+               uses p2p-tunnel-output;
        }
 }
 
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;
        }
 }