blob: 7ea9934d11dd3c12c40ce6e01c59cc53f4c20804 [file] [log] [blame]
Avantika-Huawei73862d42016-05-12 18:58:06 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.pce.pceservice;
17
18import static com.google.common.base.Preconditions.checkNotNull;
19import static org.onosproject.incubator.net.tunnel.Tunnel.Type.MPLS;
20
Priyanka Bb6963582016-05-20 20:21:20 +053021import java.util.Collections;
Avantika-Huawei73862d42016-05-12 18:58:06 +053022import java.util.Iterator;
23import java.util.List;
Priyanka Bb6963582016-05-20 20:21:20 +053024import java.util.Set;
Avantika-Huawei73862d42016-05-12 18:58:06 +053025
26import org.apache.felix.scr.annotations.Activate;
27import org.apache.felix.scr.annotations.Component;
28import org.apache.felix.scr.annotations.Deactivate;
29import org.apache.felix.scr.annotations.Reference;
30import org.apache.felix.scr.annotations.ReferenceCardinality;
31import org.apache.felix.scr.annotations.Service;
32import org.onosproject.core.ApplicationId;
33import org.onosproject.core.CoreService;
34import org.onosproject.core.IdGenerator;
35import org.onosproject.incubator.net.tunnel.Tunnel;
36import org.onosproject.incubator.net.tunnel.TunnelId;
37import org.onosproject.incubator.net.tunnel.TunnelService;
38import org.onosproject.net.DeviceId;
Priyanka Bb6963582016-05-20 20:21:20 +053039import org.onosproject.net.Path;
Avantika-Huawei73862d42016-05-12 18:58:06 +053040import org.onosproject.net.intent.Constraint;
Priyanka Bb6963582016-05-20 20:21:20 +053041import org.onosproject.net.device.DeviceService;
42import org.onosproject.net.resource.ResourceService;
43import org.onosproject.net.topology.LinkWeight;
44import org.onosproject.net.topology.PathService;
45import org.onosproject.net.topology.TopologyEdge;
Avantika-Huawei73862d42016-05-12 18:58:06 +053046import org.onosproject.pce.pceservice.api.PceService;
Priyanka Bb6963582016-05-20 20:21:20 +053047import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
Avantika-Huawei73862d42016-05-12 18:58:06 +053048import org.onosproject.store.serializers.KryoNamespaces;
49import org.onosproject.store.service.DistributedSet;
50import org.onosproject.store.service.Serializer;
51import org.onosproject.store.service.StorageService;
52import org.slf4j.Logger;
53import org.slf4j.LoggerFactory;
54
Priyanka Bb6963582016-05-20 20:21:20 +053055import com.google.common.collect.ImmutableList;
56
Avantika-Huawei73862d42016-05-12 18:58:06 +053057/**
58 * Implementation of PCE service.
59 */
60@Component(immediate = true)
61@Service
62public class PceManager implements PceService {
63 private static final Logger log = LoggerFactory.getLogger(PceManager.class);
64
65 public static final String PCE_SERVICE_APP = "org.onosproject.pce";
66
67 private static final String LOCAL_LSP_ID_GEN_TOPIC = "pcep-local-lsp-id";
68 private IdGenerator localLspIdIdGen;
69 protected DistributedSet<Short> localLspIdFreeList;
70
71 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 protected CoreService coreService;
73
74 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
75 protected TunnelService tunnelService;
76
77 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
78 protected StorageService storageService;
79
Priyanka Bb6963582016-05-20 20:21:20 +053080 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
81 protected PathService pathService;
82
83 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
84 protected ResourceService resourceService;
85
86 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
87 protected DeviceService deviceService;
88
Avantika-Huawei73862d42016-05-12 18:58:06 +053089 private ApplicationId appId;
90
91 /**
92 * Creates new instance of PceManager.
93 */
94 public PceManager() {
95 }
96
97 @Activate
98 protected void activate() {
99 appId = coreService.registerApplication(PCE_SERVICE_APP);
100 log.info("Started");
101
102 localLspIdIdGen = coreService.getIdGenerator(LOCAL_LSP_ID_GEN_TOPIC);
103 localLspIdFreeList = storageService.<Short>setBuilder()
104 .withName("pcepLocalLspIdDeletedList")
105 .withSerializer(Serializer.using(KryoNamespaces.API))
106 .build()
107 .asDistributedSet();
108 }
109
110 @Deactivate
111 protected void deactivate() {
112 log.info("Stopped");
113 }
114
Priyanka Bb6963582016-05-20 20:21:20 +0530115 /**
116 * Returns an edge-weight capable of evaluating links on the basis of the
117 * specified constraints.
118 *
119 * @param constraints path constraints
120 * @return edge-weight function
121 */
122 private LinkWeight weight(List<Constraint> constraints) {
123 return new TeConstraintBasedLinkWeight(constraints);
124 }
125
126 /**
127 * Computes a path between two devices.
128 *
129 * @param src ingress device
130 * @param dst egress device
131 * @param constraints path constraints
132 * @return computed path based on constraints
133 */
134 protected Set<Path> computePath(DeviceId src, DeviceId dst, List<Constraint> constraints) {
135 if (pathService == null) {
136 return null;
137 }
138 Set<Path> paths = pathService.getPaths(src, dst, weight(constraints));
139 if (!paths.isEmpty()) {
140 return paths;
141 }
142 return null;
143 }
144
Avantika-Huawei73862d42016-05-12 18:58:06 +0530145 //[TODO:] handle requests in queue
146 @Override
147 public boolean setupPath(DeviceId src, DeviceId dst, String tunnelName, List<Constraint> constraints,
148 LspType lspType) {
149 checkNotNull(src);
150 checkNotNull(dst);
151 checkNotNull(tunnelName);
152 checkNotNull(constraints);
153 checkNotNull(lspType);
154
155 // TODO: compute and setup path.
Priyanka Bb6963582016-05-20 20:21:20 +0530156 //TODO: gets the path based on constraints and creates a tunnel in network via tunnel manager
157 return computePath(src, dst, constraints) != null ? true : false;
Avantika-Huawei73862d42016-05-12 18:58:06 +0530158 }
159
160
161 @Override
162 public boolean updatePath(TunnelId tunnelId, List<Constraint> constraints) {
163 checkNotNull(tunnelId);
164 checkNotNull(constraints);
165
166 // TODO: compute and update path.
167
168 return true;
169 }
170
171 @Override
172 public boolean releasePath(TunnelId tunnelId) {
173 checkNotNull(tunnelId);
174 // 1. Query Tunnel from Tunnel manager.
175 Tunnel tunnel = tunnelService.queryTunnel(tunnelId);
176
177 if (tunnel == null) {
178 return false;
179 }
180
181 // 2. Call tunnel service.
182 return tunnelService.downTunnel(appId, tunnel.tunnelId());
183 }
184
185 @Override
186 public Iterable<Tunnel> queryAllPath() {
187 return tunnelService.queryTunnel(MPLS);
188 }
189
190 @Override
191 public Tunnel queryPath(TunnelId tunnelId) {
192 return tunnelService.queryTunnel(tunnelId);
193 }
194
195 /**
196 * Returns the next local LSP identifier to be used either by getting from
197 * freed list if available otherwise generating a new one.
198 *
199 * @return value of local LSP identifier
200 */
201 private short getNextLocalLspId() {
202 // If there is any free id use it. Otherwise generate new id.
203 if (localLspIdFreeList.isEmpty()) {
204 return (short) localLspIdIdGen.getNewId();
205 }
206 Iterator<Short> it = localLspIdFreeList.iterator();
207 Short value = it.next();
208 localLspIdFreeList.remove(value);
209 return value;
210 }
211
Priyanka Bb6963582016-05-20 20:21:20 +0530212 protected class TeConstraintBasedLinkWeight implements LinkWeight {
213
214 private final List<Constraint> constraints;
215
216 /**
217 * Creates a new edge-weight function capable of evaluating links
218 * on the basis of the specified constraints.
219 *
220 * @param constraints path constraints
221 */
222 public TeConstraintBasedLinkWeight(List<Constraint> constraints) {
223 if (constraints == null) {
224 this.constraints = Collections.emptyList();
225 } else {
226 this.constraints = ImmutableList.copyOf(constraints);
227 }
228 }
229
230 @Override
231 public double weight(TopologyEdge edge) {
232 if (!constraints.iterator().hasNext()) {
233 //Takes default cost/hopcount as 1 if no constraints specified
234 return 1.0;
235 }
236
237 Iterator<Constraint> it = constraints.iterator();
238 double cost = 1;
239
240 //If any constraint fails return -1 also value of cost returned from cost constraint can't be negative
241 while (it.hasNext() && cost > 0) {
242 Constraint constraint = it.next();
243 if (constraint instanceof CapabilityConstraint) {
244 cost = ((CapabilityConstraint) constraint).isValidLink(edge.link(), deviceService) ? 1 : -1;
245 } else {
246 cost = constraint.cost(edge.link(), resourceService::isAvailable);
247 }
248 }
249 return cost;
250 }
251 }
Avantika-Huawei73862d42016-05-12 18:58:06 +0530252}