--- /dev/null
+module network-topology-pcep-progrogramming {
+ // vi: set et smarttab sw=4 tabstop=4:
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:topology:pcep:programming";
+ prefix "pnp";
+
+ import network-topology-programming { prefix ntp; revision-date 2013-11-02; }
+ import network-topology-pcep { prefix pcep; revision-date 2013-10-24; }
+
+ organization "Cisco Systems, Inc.";
+ contact "Robert Varga <rovarga@cisco.com>";
+
+ description
+ "This module contains the PCEP extensions to base topology model. It
+ exposes the LSPs for which a particular node is the head end.
+
+ This module exposes three programming instructions,add-lsp,
+ remove-lsp and update-lsp, which map to actively-stateful PCEP
+ operations using PCInitiate and PCUpd messages to initiate,
+ destroy and udpate LSP configuration. The lifecycle of these
+ instructions follows draft-crabbe-pce-pce-initiated-lsp and
+ draft-ietf-pce-stateful-pce, completing execution once the head-end
+ router has acknowledged operation success. Should the router become
+ disconnected, the instruction resolve to Cancelled if the message
+ has not been sent into the TCP socket, or Failed it they have.
+
+ Copyright (c)2013 Cisco Systems, Inc. All rights reserved.";
+
+ revision "2013-11-06" {
+ description
+ "Initial revision.";
+ reference "";
+ }
+
+ rpc submit-add-lsp {
+ input {
+ uses ntp:topology-instruction-input;
+ uses pcep:add-lsp-args;
+ }
+ output {
+ uses ntp:topology-instruction-output;
+ }
+ }
+
+ rpc submit-remove-lsp {
+ input {
+ uses ntp:topology-instruction-input;
+ uses pcep:remove-lsp-args;
+ }
+ output {
+ uses ntp:topology-instruction-output;
+ }
+ }
+
+ rpc submit-update-lsp {
+ input {
+ uses ntp:topology-instruction-input;
+ uses pcep:update-lsp-args;
+ }
+ output {
+ uses ntp:topology-instruction-output;
+ }
+ }
+}
+
prefix "pn";
import network-topology { prefix nt; revision-date 2013-10-21; }
- import network-topology-programming { prefix ntp; revision-date 2013-11-02; }
import pcep-types { prefix pcep; revision-date 2013-10-05; }
organization "Cisco Systems, Inc.";
uses pcep-client-attributes;
}
- rpc add-lsp {
- input {
- uses ntp:topology-instruction-input;
+ typedef failure-type {
+ type enumeration {
+ enum unsent;
+ enum no-ack;
+ enum failed;
+ }
+ }
- leaf node {
- type nt:node-ref;
- mandatory true;
- }
+ grouping lsp-id {
+ leaf node {
+ type nt:node-ref;
+ mandatory true;
+ }
- leaf name {
- type pcep:symbolic-path-name;
- mandatory true;
- }
+ leaf name {
+ type pcep:symbolic-path-name;
+ mandatory true;
+ }
+ }
- container arguments {
- leaf administrative {
- type boolean;
- default true;
- }
+ grouping operation-result {
+ leaf failure {
+ type failure-type;
+ }
+ }
- container endpoints {
- uses pcep:endpoints-object;
- }
+ grouping add-lsp-args {
+ uses lsp-id;
+
+ container arguments {
+ leaf administrative {
+ type boolean;
+ default true;
+ }
- uses pcep:path-definition;
+ container endpoints {
+ uses pcep:endpoints-object;
}
+
+ uses pcep:path-definition;
+ }
+ }
+
+ rpc add-lsp {
+ input {
+ uses add-lsp-args;
}
output {
- uses ntp:topology-instruction-output;
+ uses operation-result;
}
}
+ grouping remove-lsp-args {
+ uses lsp-id;
+ }
+
rpc remove-lsp {
input {
- uses ntp:topology-instruction-input;
-
- leaf node {
- type nt:node-ref;
- mandatory true;
- }
-
- leaf name {
- type pcep:symbolic-path-name;
- mandatory true;
- }
+ uses remove-lsp-args;
}
output {
- uses ntp:topology-instruction-output;
+ uses operation-result;
}
}
- rpc update-lsp {
- input {
- uses ntp:topology-instruction-input;
-
- leaf node {
- type nt:node-ref;
- mandatory true;
- }
+ grouping update-lsp-args {
+ uses lsp-id;
- leaf name {
- type pcep:symbolic-path-name;
- mandatory true;
+ container arguments {
+ leaf administrative {
+ type boolean;
+ default true;
}
- container arguments {
- leaf administrative {
- type boolean;
- default true;
- }
+ uses pcep:path-definition;
+ }
+ }
- uses pcep:path-definition;
- }
+ rpc update-lsp {
+ input {
+ uses update-lsp-args;
}
output {
- uses ntp:topology-instruction-output;
+ uses operation-result;
}
}
}
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;
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, null, dps, topology);
+ final PCEPTopologyProvider exp = new PCEPTopologyProvider(dispatcher, GlobalEventExecutor.INSTANCE, null, dps, topology);
final ChannelFuture s = exp.startServer(address);
try {
s.get();
package org.opendaylight.bgpcep.pcep.topology.provider;
import io.netty.channel.ChannelFuture;
+import io.netty.util.concurrent.EventExecutor;
import java.net.InetSocketAddress;
public final class PCEPTopologyProvider {
private final PCEPDispatcher dispatcher;
- private final DataProviderService dataProvider;
- private final InstanceIdentifier<Topology> topology;
- private final InstructionScheduler scheduler;
+ private final TopologyProgramming topology;
+ private final ServerSessionManager manager;
+ 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.dataProvider = Preconditions.checkNotNull(dataService);
- this.topology = Preconditions.checkNotNull(topology);
- this.scheduler = Preconditions.checkNotNull(scheduler);
+
+
+ this.manager = new ServerSessionManager(executor, dataService, topology);
+ this.element = new TopologyRPCs(executor, manager);
+ this.topology = new TopologyProgramming(executor, scheduler, manager);
}
public ChannelFuture startServer(final InetSocketAddress address) {
- return dispatcher.createServer(address, new ServerSessionManager(scheduler, dataProvider, topology));
+ return dispatcher.createServer(address, manager);
}
}
import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.FutureListener;
-import io.netty.util.concurrent.GlobalEventExecutor;
import io.netty.util.concurrent.Promise;
import java.net.InetAddress;
import javax.annotation.concurrent.GuardedBy;
-import org.opendaylight.bgpcep.programming.spi.ExecutionResult;
-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.md.sal.common.api.TransactionStatus;
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.stateful.capability.tlv.Stateful;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.symbolic.path.name.tlv.SymbolicPathName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.symbolic.path.name.tlv.SymbolicPathNameBuilder;
-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.rev131024.AddLspInput;
-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.AddLspOutputBuilder;
-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.AddLspArgs;
+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.Node1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.Node1Builder;
+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.PccSyncState;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.RemoveLspInput;
-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.RemoveLspOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspInput;
-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.UpdateLspOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.RemoveLspArgs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspArgs;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.PathComputationClientBuilder;
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.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.pcep.client.attributes.path.computation.client.ReportedLspsKey;
/**
*
*/
-final class ServerSessionManager implements SessionListenerFactory<PCEPSessionListener>, NetworkTopologyPcepService {
+final class ServerSessionManager implements SessionListenerFactory<PCEPSessionListener> {
private static String createNodeId(final InetAddress addr) {
return "pcc://" + addr.getHostAddress();
}
private final class SessionListener implements PCEPSessionListener {
- private final Map<SrpIdNumber, Promise<ExecutionResult<Details>>> waitingRequests = new HashMap<>();
- private final Map<SrpIdNumber, Promise<ExecutionResult<Details>>> sendingRequests = new HashMap<>();
+ private final Map<SrpIdNumber, Promise<OperationResult>> waitingRequests = new HashMap<>();
+ private final Map<SrpIdNumber, Promise<OperationResult>> sendingRequests = new HashMap<>();
private final Map<PlspId, SymbolicPathName> lsps = new HashMap<>();
private PathComputationClientBuilder pccBuilder;
private InstanceIdentifier<Node1> topologyAugment;
}
// Clear all requests which have not been sent to the peer: they result in cancellation
- for (final Entry<SrpIdNumber, Promise<ExecutionResult<Details>>> e : this.sendingRequests.entrySet()) {
+ for (final Entry<SrpIdNumber, Promise<OperationResult>> e : this.sendingRequests.entrySet()) {
LOG.debug("Request {} was not sent when session went down, cancelling the instruction", e.getKey());
- e.getValue().setSuccess(new ExecutionResult<Details>(InstructionStatus.Cancelled, null));
+ e.getValue().setSuccess(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<ExecutionResult<Details>>> e : this.waitingRequests.entrySet()) {
+ for (final Entry<SrpIdNumber, Promise<OperationResult>> e : this.waitingRequests.entrySet()) {
LOG.info("Request {} was incomplete when session went down, failing the instruction", e.getKey());
- e.getValue().setSuccess(new ExecutionResult<Details>(InstructionStatus.Failed, null));
+ e.getValue().setSuccess(OPERATION_NOACK);
}
this.waitingRequests.clear();
}
case Active:
case Down:
case Up:
- final Promise<ExecutionResult<Details>> p = this.waitingRequests.remove(id);
+ final Promise<OperationResult> p = this.waitingRequests.remove(id);
if (p != null) {
LOG.debug("Request {} resulted in LSP operational state {}", id, lsp.getOperational());
- p.setSuccess(new ExecutionResult<Details>(InstructionStatus.Successful, null));
+ p.setSuccess(OPERATION_SUCCESS);
} else {
LOG.warn("Request ID {} not found in outstanding DB", id);
}
}
private synchronized void messageSendingComplete(final SrpIdNumber requestId, final io.netty.util.concurrent.Future<Void> future) {
- final Promise<ExecutionResult<Details>> promise = this.sendingRequests.remove(requestId);
+ final Promise<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(new ExecutionResult<Details>(InstructionStatus.Cancelled, null));
+ promise.setSuccess(OPERATION_UNSENT);
}
}
- private synchronized io.netty.util.concurrent.Future<ExecutionResult<Details>> sendMessage(final Message message,
+ private synchronized io.netty.util.concurrent.Future<OperationResult> sendMessage(final Message message,
final SrpIdNumber requestId) {
final io.netty.util.concurrent.Future<Void> f = this.session.sendMessage(message);
- final Promise<ExecutionResult<Details>> ret = exec.newPromise();
+ final Promise<OperationResult> ret = exec.newPromise();
this.sendingRequests.put(requestId, ret);
return this.version;
}
};
- private static final EventExecutor exec = GlobalEventExecutor.INSTANCE;
+
+ private static final OperationResult OPERATION_NOACK = createOperationResult(FailureType.NoAck);
+ private static final OperationResult OPERATION_SUCCESS = createOperationResult(null);
+ private static final OperationResult OPERATION_UNSENT = createOperationResult(FailureType.Unsent);
+
private final Map<NodeId, SessionListener> nodes = new HashMap<>();
private final InstanceIdentifier<Topology> topology;
private final DataProviderService dataProvider;
- private final InstructionScheduler scheduler;
+ private final EventExecutor exec;
- public ServerSessionManager(final InstructionScheduler scheduler, final DataProviderService dataProvider,
+ public ServerSessionManager(
+ final EventExecutor exec,
+ final DataProviderService dataProvider,
final InstanceIdentifier<Topology> topology) {
this.dataProvider = Preconditions.checkNotNull(dataProvider);
this.topology = Preconditions.checkNotNull(topology);
- this.scheduler = Preconditions.checkNotNull(scheduler);
+ this.exec = Preconditions.checkNotNull(exec);
}
@Override
return new SessionListener();
}
- private synchronized io.netty.util.concurrent.Future<ExecutionResult<Details>> realAddLsp(final AddLspInput input) {
+ synchronized io.netty.util.concurrent.Future<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 exec.newSucceededFuture(new ExecutionResult<Details>(InstructionStatus.Cancelled, null));
+ return exec.newSucceededFuture(OPERATION_UNSENT);
}
// Make sure there is no such LSP
new ReportedLspsKey(input.getName())).toInstance();
if (this.dataProvider.readOperationalData(lsp) != null) {
LOG.debug("Node {} already contains lsp {} at {}", input.getNode(), input.getName(), lsp);
- return exec.newSucceededFuture(new ExecutionResult<Details>(InstructionStatus.Cancelled, null));
+ return exec.newSucceededFuture(OPERATION_UNSENT);
}
// Build the request
return l.sendMessage(new PcinitiateBuilder().setPcinitiateMessage(ib.build()).build(), rb.getSrp().getOperationId());
}
- private synchronized io.netty.util.concurrent.Future<ExecutionResult<Details>> realRemoveLsp(final RemoveLspInput input) {
+ private static OperationResult createOperationResult(final FailureType type) {
+ return new OperationResult() {
+ @Override
+ public Class<? extends DataContainer> getImplementedInterface() {
+ return OperationResult.class;
+ }
+
+ @Override
+ public FailureType getFailure() {
+ return type;
+ }
+ };
+ }
+
+ synchronized io.netty.util.concurrent.Future<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 exec.newSucceededFuture(new ExecutionResult<Details>(InstructionStatus.Cancelled, null));
+ return exec.newSucceededFuture(OPERATION_UNSENT);
}
// Make sure the LSP exists, we need it for PLSP-ID
final ReportedLsps rep = (ReportedLsps) this.dataProvider.readOperationalData(lsp);
if (rep == null) {
LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
- return exec.newSucceededFuture(new ExecutionResult<Details>(InstructionStatus.Cancelled, null));
+ return exec.newSucceededFuture(OPERATION_UNSENT);
}
// Build the request and send it
return l.sendMessage(new PcinitiateBuilder().setPcinitiateMessage(ib.build()).build(), rb.getSrp().getOperationId());
}
- private synchronized io.netty.util.concurrent.Future<ExecutionResult<Details>> realUpdateLsp(final UpdateLspInput input) {
+ synchronized io.netty.util.concurrent.Future<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 exec.newSucceededFuture(new ExecutionResult<Details>(InstructionStatus.Cancelled, null));
+ return exec.newSucceededFuture(OPERATION_UNSENT);
}
// Make sure the LSP exists
final ReportedLsps rep = (ReportedLsps) this.dataProvider.readOperationalData(lsp);
if (rep == null) {
LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
- return exec.newSucceededFuture(new ExecutionResult<Details>(InstructionStatus.Cancelled, null));
+ return exec.newSucceededFuture(OPERATION_UNSENT);
}
// Build the PCUpd request and send it
ub.setUpdates(ImmutableList.of(rb.build()));
return l.sendMessage(new PcupdBuilder().setPcupdMessage(ub.build()).build(), rb.getSrp().getOperationId());
}
-
- @Override
- public Future<RpcResult<AddLspOutput>> addLsp(final AddLspInput input) {
- Preconditions.checkArgument(input.getNode() != null);
- Preconditions.checkArgument(input.getName() != null);
-
- final InstructionExecutor e = new InstructionExecutor() {
- @Override
- public io.netty.util.concurrent.Future<ExecutionResult<Details>> execute() {
- return realAddLsp(input);
- }
- };
-
- final Failure f = this.scheduler.submitInstruction(input, e);
- final AddLspOutputBuilder b = new AddLspOutputBuilder();
- if (f != null) {
- b.setResult(new FailureBuilder().setFailure(f).build());
- }
-
- final RpcResult<AddLspOutput> res = SuccessfulRpcResult.create(b.build());
- return exec.newSucceededFuture(res);
- }
-
- @Override
- public Future<RpcResult<RemoveLspOutput>> removeLsp(final RemoveLspInput input) {
- Preconditions.checkArgument(input.getNode() != null);
- Preconditions.checkArgument(input.getName() != null);
-
- final InstructionExecutor e = new InstructionExecutor() {
- @Override
- public io.netty.util.concurrent.Future<ExecutionResult<Details>> execute() {
- return realRemoveLsp(input);
- }
- };
-
- final Failure f = this.scheduler.submitInstruction(input, e);
- final RemoveLspOutputBuilder b = new RemoveLspOutputBuilder();
- if (f != null) {
- b.setResult(new FailureBuilder().setFailure(f).build());
- }
-
- final RpcResult<RemoveLspOutput> res = SuccessfulRpcResult.create(b.build());
- return exec.newSucceededFuture(res);
- }
-
- @Override
- public Future<RpcResult<UpdateLspOutput>> updateLsp(final UpdateLspInput input) {
- Preconditions.checkArgument(input.getNode() != null);
- Preconditions.checkArgument(input.getName() != null);
-
- final InstructionExecutor e = new InstructionExecutor() {
- @Override
- public io.netty.util.concurrent.Future<ExecutionResult<Details>> execute() {
- return realUpdateLsp(input);
- }
- };
-
- final Failure f = this.scheduler.submitInstruction(input, e);
- final UpdateLspOutputBuilder b = new UpdateLspOutputBuilder();
- if (f != null) {
- b.setResult(new FailureBuilder().setFailure(f).build());
- }
-
- final RpcResult<UpdateLspOutput> res = SuccessfulRpcResult.create(b.build());
- return exec.newSucceededFuture(res);
- }
}
--- /dev/null
+/*
+ * 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.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.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.NetworkTopologyPcepProgrogrammingService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitAddLspInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitAddLspOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitAddLspOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitRemoveLspInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitRemoveLspOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.programming.rev131106.SubmitRemoveLspOutputBuilder;
+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;
+
+/**
+ *
+ */
+final class TopologyProgramming implements NetworkTopologyPcepProgrogrammingService {
+ 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) {
+ this.scheduler = Preconditions.checkNotNull(scheduler);
+ this.manager = Preconditions.checkNotNull(manager);
+ this.exec = Preconditions.checkNotNull(executor);
+ }
+
+ @Override
+ public Future<RpcResult<SubmitAddLspOutput>> submitAddLsp(final SubmitAddLspInput input) {
+ Preconditions.checkArgument(input.getNode() != null);
+ Preconditions.checkArgument(input.getName() != null);
+
+ final InstructionExecutor e = new AbstractInstructionExecutor() {
+ @Override
+ public io.netty.util.concurrent.Future<OperationResult> executeImpl() {
+ return manager.realAddLsp(input);
+ }
+ };
+
+ final Failure f = this.scheduler.submitInstruction(input, e);
+ final SubmitAddLspOutputBuilder b = new SubmitAddLspOutputBuilder();
+ if (f != null) {
+ b.setResult(new FailureBuilder().setFailure(f).build());
+ }
+
+ final RpcResult<SubmitAddLspOutput> res = SuccessfulRpcResult.create(b.build());
+ return exec.newSucceededFuture(res);
+ }
+
+ @Override
+ public Future<RpcResult<SubmitRemoveLspOutput>> submitRemoveLsp(final SubmitRemoveLspInput input) {
+ Preconditions.checkArgument(input.getNode() != null);
+ Preconditions.checkArgument(input.getName() != null);
+
+ final InstructionExecutor e = new AbstractInstructionExecutor() {
+ @Override
+ protected io.netty.util.concurrent.Future<OperationResult> executeImpl() {
+ return manager.realRemoveLsp(input);
+ }
+ };
+
+ final Failure f = this.scheduler.submitInstruction(input, e);
+ final SubmitRemoveLspOutputBuilder b = new SubmitRemoveLspOutputBuilder();
+ if (f != null) {
+ b.setResult(new FailureBuilder().setFailure(f).build());
+ }
+
+ final RpcResult<SubmitRemoveLspOutput> res = SuccessfulRpcResult.create(b.build());
+ return exec.newSucceededFuture(res);
+ }
+
+ @Override
+ public Future<RpcResult<SubmitUpdateLspOutput>> submitUpdateLsp(final SubmitUpdateLspInput input) {
+ Preconditions.checkArgument(input.getNode() != null);
+ Preconditions.checkArgument(input.getName() != null);
+
+ final InstructionExecutor e = new AbstractInstructionExecutor() {
+ @Override
+ protected io.netty.util.concurrent.Future<OperationResult> executeImpl() {
+ return manager.realUpdateLsp(input);
+ }
+ };
+
+ final Failure f = this.scheduler.submitInstruction(input, e);
+ final SubmitUpdateLspOutputBuilder b = new SubmitUpdateLspOutputBuilder();
+ if (f != null) {
+ b.setResult(new FailureBuilder().setFailure(f).build());
+ }
+
+ final RpcResult<SubmitUpdateLspOutput> res = SuccessfulRpcResult.create(b.build());
+ return exec.newSucceededFuture(res);
+ }
+
+}
--- /dev/null
+/*
+ * 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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.AddLspInput;
+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.AddLspOutputBuilder;
+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.RemoveLspInput;
+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.RemoveLspOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.UpdateLspInput;
+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.UpdateLspOutputBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import com.google.common.base.Preconditions;
+
+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) {
+ 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>() {
+ @Override
+ protected RpcResult<AddLspOutput> convertResult(final OperationResult result) {
+ return SuccessfulRpcResult.create(new AddLspOutputBuilder(result).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>() {
+ @Override
+ protected RpcResult<RemoveLspOutput> convertResult(final OperationResult result) {
+ return SuccessfulRpcResult.create(new RemoveLspOutputBuilder(result).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>() {
+ @Override
+ protected RpcResult<UpdateLspOutput> convertResult(final OperationResult result) {
+ return SuccessfulRpcResult.create(new UpdateLspOutputBuilder(result).build());
+ }
+ };
+
+ manager.realUpdateLsp(input).addListener(adaptor);
+ return adaptor.promise;
+ }
+}