Path Computation Algorithms
[bgpcep.git] / algo / algo-impl / src / main / java / org / opendaylight / algo / impl / PathComputationServer.java
1 /*
2  * Copyright (c) 2020 Orange. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.algo.impl;
9
10 import static com.google.common.base.Preconditions.checkArgument;
11
12 import com.google.common.util.concurrent.ListenableFuture;
13 import org.opendaylight.algo.PathComputationAlgorithm;
14 import org.opendaylight.algo.PathComputationProvider;
15 import org.opendaylight.graph.ConnectedGraph;
16 import org.opendaylight.graph.ConnectedGraphProvider;
17 import org.opendaylight.mdsal.binding.api.RpcProviderService;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.AlgorithmType;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ComputationStatus;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.ConstrainedPath;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.GetConstrainedPathInput;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.GetConstrainedPathOutput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.GetConstrainedPathOutputBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.path.computation.rev200120.PathComputationService;
26 import org.opendaylight.yangtools.concepts.ObjectRegistration;
27 import org.opendaylight.yangtools.yang.common.RpcError;
28 import org.opendaylight.yangtools.yang.common.RpcResult;
29 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * Path Computation Algorithms provider.
35  *
36  * @author Olivier Dugeon
37  */
38 public class PathComputationServer implements AutoCloseable, PathComputationService, PathComputationProvider {
39
40     private static final Logger LOG = LoggerFactory.getLogger(PathComputationServer.class);
41
42     private ObjectRegistration<PathComputationService> pathService;
43     private RpcProviderService rpcProviderRegistry;
44     private ConnectedGraphProvider graphProvider;
45
46     private ConnectedGraph cgraph;
47
48     public PathComputationServer(final RpcProviderService rpcService, final ConnectedGraphProvider graphProvider) {
49         checkArgument(rpcService != null);
50         checkArgument(graphProvider != null);
51         this.rpcProviderRegistry = rpcService;
52         this.graphProvider = graphProvider;
53     }
54
55     public void init() {
56         pathService = this.rpcProviderRegistry.registerRpcImplementation(PathComputationService.class, this);
57     }
58
59     @Override
60     public ListenableFuture<RpcResult<GetConstrainedPathOutput>> getConstrainedPath(
61             final GetConstrainedPathInput input) {
62         final GetConstrainedPathOutputBuilder output = new GetConstrainedPathOutputBuilder();
63
64         LOG.info("Got Path Computation Service request");
65
66         /* First, get graph */
67         this.cgraph = graphProvider.getConnectedGraph(input.getGraphName());
68         if (this.cgraph == null) {
69             output.setStatus(ComputationStatus.Failed);
70             return RpcResultBuilder.<GetConstrainedPathOutput>failed()
71                     .withError(RpcError.ErrorType.RPC, "Unknown Graph Name").buildFuture();
72         }
73
74         /* get a new Path Computation Algorithm according to Input choice */
75         PathComputationAlgorithm algo = getPathComputationAlgorithm(this.cgraph, input.getAlgorithm());
76         if (algo == null) {
77             output.setStatus(ComputationStatus.Failed);
78             return RpcResultBuilder.<GetConstrainedPathOutput>failed()
79                     .withError(RpcError.ErrorType.RPC, "Unknown Path Computation Algorithm").buildFuture();
80         }
81
82         /*
83          * Request Path Computation for given source, destination and
84          * constraints
85          */
86         final VertexKey source = new VertexKey(input.getSource());
87         final VertexKey destination = new VertexKey(input.getDestination());
88         LOG.info("Call Path Computation {} algorithm for path from {} to {} with contraints {}",
89                 input.getAlgorithm().getName(), source, destination, input.getConstraints());
90         final ConstrainedPath cpath = algo.computeP2pPath(source, destination, input.getConstraints());
91
92         /* Send back the Computed Path */
93         output.setPathDescription(cpath.getPathDescription()).setStatus(cpath.getStatus())
94                 .setComputedMetric(cpath.getMetric()).setComputedTeMetric(cpath.getTeMetric())
95                 .setComputedDelay(cpath.getDelay());
96
97         return RpcResultBuilder.success(output.build()).buildFuture();
98     }
99
100     @Override
101     public void close() throws Exception {
102         pathService.close();
103     }
104
105     @Override
106     public PathComputationAlgorithm getPathComputationAlgorithm(ConnectedGraph runningGraph,
107             AlgorithmType algorithmType) {
108         PathComputationAlgorithm algo = null;
109         switch (algorithmType) {
110             case Spf:
111                 algo = new ShortestPathFirst(runningGraph);
112                 break;
113             case Cspf:
114                 algo = new ConstrainedShortestPathFirst(runningGraph);
115                 break;
116             case Samcra:
117                 algo = new Samcra(runningGraph);
118                 break;
119             default:
120                 break;
121         }
122         return algo;
123     }
124 }