blob: 38239ed53b06f78229c75db6ff03d7e072033281 [file] [log] [blame]
cheng fan48e832c2015-05-29 01:54:47 +08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
cheng fan48e832c2015-05-29 01:54:47 +08003 *
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.provider.pcep.topology.impl;
17
cheng fan48e832c2015-05-29 01:54:47 +080018import org.apache.felix.scr.annotations.Activate;
19import org.apache.felix.scr.annotations.Component;
20import org.apache.felix.scr.annotations.Deactivate;
21import org.apache.felix.scr.annotations.Reference;
22import org.apache.felix.scr.annotations.ReferenceCardinality;
23import org.onlab.packet.ChassisId;
24import org.onosproject.cluster.ClusterService;
cheng fan48e832c2015-05-29 01:54:47 +080025import org.onosproject.mastership.MastershipAdminService;
26import org.onosproject.mastership.MastershipService;
27import org.onosproject.net.ConnectPoint;
28import org.onosproject.net.DefaultAnnotations;
29import org.onosproject.net.Device;
30import org.onosproject.net.DeviceId;
cheng fan48e832c2015-05-29 01:54:47 +080031import org.onosproject.net.Link.Type;
32import org.onosproject.net.MastershipRole;
chengfan359abf72015-07-02 23:33:16 +080033import org.onosproject.net.OchPort;
34import org.onosproject.net.OduCltPort;
35import org.onosproject.net.OmsPort;
36import org.onosproject.net.Port;
Saurav Dasa2d37502016-03-25 17:50:40 -070037import org.onosproject.net.PortNumber;
cheng fan48e832c2015-05-29 01:54:47 +080038import org.onosproject.net.device.DefaultDeviceDescription;
39import org.onosproject.net.device.DefaultPortDescription;
40import org.onosproject.net.device.DeviceDescription;
41import org.onosproject.net.device.DeviceProvider;
42import org.onosproject.net.device.DeviceProviderRegistry;
43import org.onosproject.net.device.DeviceProviderService;
44import org.onosproject.net.device.DeviceService;
chengfan359abf72015-07-02 23:33:16 +080045import org.onosproject.net.device.OchPortDescription;
46import org.onosproject.net.device.OduCltPortDescription;
47import org.onosproject.net.device.OmsPortDescription;
cheng fan48e832c2015-05-29 01:54:47 +080048import org.onosproject.net.device.PortDescription;
49import org.onosproject.net.link.DefaultLinkDescription;
50import org.onosproject.net.link.LinkDescription;
51import org.onosproject.net.link.LinkProvider;
52import org.onosproject.net.link.LinkProviderRegistry;
53import org.onosproject.net.link.LinkProviderService;
54import org.onosproject.net.link.LinkService;
55import org.onosproject.net.provider.AbstractProvider;
56import org.onosproject.net.provider.ProviderId;
57import org.onosproject.pcep.api.PcepController;
58import org.onosproject.pcep.api.PcepDpid;
59import org.onosproject.pcep.api.PcepLink;
cheng fan7716ec92015-05-31 01:53:19 +080060import org.onosproject.pcep.api.PcepLink.PortType;
cheng fan48e832c2015-05-29 01:54:47 +080061import org.onosproject.pcep.api.PcepLinkListener;
62import org.onosproject.pcep.api.PcepOperator.OperationType;
63import org.onosproject.pcep.api.PcepSwitch;
64import org.onosproject.pcep.api.PcepSwitchListener;
Priyanka B94395bf2016-05-21 18:39:46 +053065import org.onosproject.pcep.controller.PccId;
66import org.onosproject.pcep.controller.PcepClient;
67import org.onosproject.pcep.controller.PcepClientController;
68import org.onosproject.pcep.controller.PcepNodeListener;
cheng fan48e832c2015-05-29 01:54:47 +080069import org.slf4j.Logger;
70import org.slf4j.LoggerFactory;
71
chengfan359abf72015-07-02 23:33:16 +080072import java.util.ArrayList;
73import java.util.HashMap;
74import java.util.List;
75
76import static com.google.common.base.Preconditions.checkNotNull;
77import static org.onosproject.net.DeviceId.deviceId;
78import static org.onosproject.pcep.api.PcepDpid.uri;
79
cheng fan48e832c2015-05-29 01:54:47 +080080/**
81 * Provider which uses an PCEP controller to detect network infrastructure
82 * topology.
83 */
84@Component(immediate = true)
85public class PcepTopologyProvider extends AbstractProvider
86 implements LinkProvider, DeviceProvider {
87
Priyanka B9bee0802016-04-27 22:06:02 +053088 /**
89 * Creates instance of PCEP topology provider.
90 */
cheng fan48e832c2015-05-29 01:54:47 +080091 public PcepTopologyProvider() {
Priyanka B9bee0802016-04-27 22:06:02 +053092 super(new ProviderId("l3", "org.onosproject.provider.pcep"));
cheng fan48e832c2015-05-29 01:54:47 +080093 }
94
95 private static final Logger log = LoggerFactory
96 .getLogger(PcepTopologyProvider.class);
97
98 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
99 protected LinkProviderRegistry linkProviderRegistry;
100
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected DeviceProviderRegistry deviceProviderRegistry;
103
104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
105 protected PcepController controller;
106
107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
108 protected DeviceService deviceService;
109
110 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
111 protected LinkService linkService;
112
113 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
114 protected MastershipAdminService mastershipAdminService;
115
116 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
117 protected MastershipService mastershipService;
118
119 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
120 protected ClusterService clusterService;
121
Priyanka B94395bf2016-05-21 18:39:46 +0530122 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
123 protected PcepClientController pcepClientController;
124
cheng fan48e832c2015-05-29 01:54:47 +0800125 private DeviceProviderService deviceProviderService;
126 private LinkProviderService linkProviderService;
chengfan359abf72015-07-02 23:33:16 +0800127
128 private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
cheng fan48e832c2015-05-29 01:54:47 +0800129 private InternalLinkProvider listener = new InternalLinkProvider();
130
Priyanka B94395bf2016-05-21 18:39:46 +0530131 /*
132 * For the client supporting SR capability.
133 */
134 public static final String SR_CAPABILITY = "srCapability";
135
136 /*
137 * For the client supporting PCECC capability.
138 */
139 public static final String PCECC_CAPABILITY = "pceccCapability";
140
141 /*
142 * For the client supporting label stack capability.
143 */
144 public static final String LABEL_STACK_CAPABILITY = "labelStackCapability";
145
146 public static final String LSRID = "lsrId";
147 private static final String UNKNOWN = "unknown";
148
cheng fan48e832c2015-05-29 01:54:47 +0800149 @Activate
150 public void activate() {
151 linkProviderService = linkProviderRegistry.register(this);
152 deviceProviderService = deviceProviderRegistry.register(this);
153 controller.addListener(listener);
154 controller.addLinkListener(listener);
Priyanka B94395bf2016-05-21 18:39:46 +0530155 pcepClientController.addNodeListener(listener);
cheng fan48e832c2015-05-29 01:54:47 +0800156 }
157
158 @Deactivate
159 public void deactivate() {
160 linkProviderRegistry.unregister(this);
161 linkProviderService = null;
162 controller.removeListener(listener);
163 controller.removeLinkListener(listener);
Priyanka B94395bf2016-05-21 18:39:46 +0530164 pcepClientController.removeNodeListener(listener);
cheng fan48e832c2015-05-29 01:54:47 +0800165 }
166
chengfan359abf72015-07-02 23:33:16 +0800167 private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
168 Port port,
cheng fan7716ec92015-05-31 01:53:19 +0800169 PortType portType) {
chengfan359abf72015-07-02 23:33:16 +0800170
171 List<PortDescription> portList;
172
173 if (portMap.containsKey(dpid.value())) {
174 portList = portMap.get(dpid.value());
175 } else {
176 portList = new ArrayList<>();
cheng fan48e832c2015-05-29 01:54:47 +0800177 }
chengfan359abf72015-07-02 23:33:16 +0800178 if (port != null && portType != null) {
179 portList.add(buildPortDescription(port, portType));
180 }
181
182 portMap.put(dpid.value(), portList);
183 return portList;
cheng fan48e832c2015-05-29 01:54:47 +0800184 }
185
chengfan359abf72015-07-02 23:33:16 +0800186 private PortDescription buildPortDescription(Port port, PortType portType) {
187 PortDescription portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800188
chengfan359abf72015-07-02 23:33:16 +0800189 switch (portType) {
190 case OCH_PORT:
191 OchPort ochp = (OchPort) port;
192 portDescription = new OchPortDescription(ochp.number(), ochp.isEnabled(),
193 ochp.signalType(), ochp.isTunable(),
194 ochp.lambda());
195 break;
196 case ODU_PORT:
197 OduCltPort odup = (OduCltPort) port;
198 portDescription = new OduCltPortDescription(odup.number(), odup.isEnabled(),
199 odup.signalType());
200 break;
201 case OMS_PORT:
202 OmsPort op = (OmsPort) port;
203 portDescription = new OmsPortDescription(op.number(), op.isEnabled(), op.minFrequency(),
204 op.maxFrequency(), op.grid());
205 break;
206 default:
207 portDescription = new DefaultPortDescription(port.number(), port.isEnabled());
208 break;
209 }
210 return portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800211 }
212
213 /**
chengfan3e618792015-06-28 21:42:01 +0800214 * Build a link description from a pcep link.
cheng fan48e832c2015-05-29 01:54:47 +0800215 *
chengfan3e618792015-06-28 21:42:01 +0800216 * @param pceLink pcep link
217 * @return LinkDescription onos link description
cheng fan48e832c2015-05-29 01:54:47 +0800218 */
219 private LinkDescription buildLinkDescription(PcepLink pceLink) {
220 LinkDescription ld;
chengfan359abf72015-07-02 23:33:16 +0800221 checkNotNull(pceLink);
cheng fan48e832c2015-05-29 01:54:47 +0800222 DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
223 DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));
224
cheng fan48e832c2015-05-29 01:54:47 +0800225 deviceProviderService
226 .updatePorts(srcDeviceID,
chengfan359abf72015-07-02 23:33:16 +0800227 buildPortDescriptions(pceLink.linkSrcDeviceID(),
228 pceLink.linkSrcPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800229
chengfan359abf72015-07-02 23:33:16 +0800230 deviceProviderService
231 .updatePorts(dstDeviceID,
232 buildPortDescriptions(pceLink.linkDstDeviceId(),
233 pceLink.linkDstPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800234
chengfan359abf72015-07-02 23:33:16 +0800235 ConnectPoint src = new ConnectPoint(srcDeviceID, pceLink.linkSrcPort().number());
cheng fan48e832c2015-05-29 01:54:47 +0800236
chengfan359abf72015-07-02 23:33:16 +0800237 ConnectPoint dst = new ConnectPoint(dstDeviceID, pceLink.linkDstPort().number());
238
239 DefaultAnnotations extendedAttributes = DefaultAnnotations
240 .builder()
241 .set("subType", String.valueOf(pceLink.linkSubType()))
242 .set("workState", pceLink.linkState())
243 .set("distance", String.valueOf(pceLink.linkDistance()))
244 .set("capType", pceLink.linkCapacityType().toLowerCase())
245 .set("avail_" + pceLink.linkCapacityType().toLowerCase(),
246 String.valueOf(pceLink.linkAvailValue()))
247 .set("max_" + pceLink.linkCapacityType().toLowerCase(),
248 String.valueOf(pceLink.linkMaxValue())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800249 // construct the link
chengfan359abf72015-07-02 23:33:16 +0800250 ld = new DefaultLinkDescription(src, dst, Type.OPTICAL, extendedAttributes);
cheng fan48e832c2015-05-29 01:54:47 +0800251 return ld;
252 }
253
cheng fan48e832c2015-05-29 01:54:47 +0800254 private class InternalLinkProvider
Priyanka B94395bf2016-05-21 18:39:46 +0530255 implements PcepSwitchListener, PcepLinkListener, PcepNodeListener {
cheng fan48e832c2015-05-29 01:54:47 +0800256
257 @Override
258 public void switchAdded(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800259 if (deviceProviderService == null) {
260 return;
261 }
chengfan359abf72015-07-02 23:33:16 +0800262 DeviceId deviceId = deviceId(uri(dpid));
cheng fan48e832c2015-05-29 01:54:47 +0800263 PcepSwitch sw = controller.getSwitch(dpid);
264 checkNotNull(sw, "device should not null.");
265 // The default device type is switch.
cheng fan48e832c2015-05-29 01:54:47 +0800266 ChassisId cId = new ChassisId(dpid.value());
chengfan359abf72015-07-02 23:33:16 +0800267 Device.Type deviceType;
cheng fan48e832c2015-05-29 01:54:47 +0800268
cheng fan7716ec92015-05-31 01:53:19 +0800269 switch (sw.getDeviceType()) {
chengfan359abf72015-07-02 23:33:16 +0800270 case ROADM:
271 deviceType = Device.Type.ROADM;
272 break;
273 case OTN:
274 deviceType = Device.Type.SWITCH;
275 break;
276 case ROUTER:
277 deviceType = Device.Type.ROUTER;
278 break;
279 default:
280 deviceType = Device.Type.OTHER;
cheng fan7716ec92015-05-31 01:53:19 +0800281 }
cheng fan48e832c2015-05-29 01:54:47 +0800282
283 DeviceDescription description = new DefaultDeviceDescription(
chengfan359abf72015-07-02 23:33:16 +0800284 deviceId.uri(),
285 deviceType,
286 sw.manufacturerDescription(),
287 sw.hardwareDescription(),
288 sw.softwareDescription(),
289 sw.serialNumber(),
290 cId);
291 deviceProviderService.deviceConnected(deviceId, description);
cheng fan48e832c2015-05-29 01:54:47 +0800292
293 }
294
295 @Override
296 public void switchRemoved(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800297 if (deviceProviderService == null || linkProviderService == null) {
298 return;
299 }
300 deviceProviderService.deviceDisconnected(deviceId(uri(dpid)));
301
302 linkProviderService.linksVanished(DeviceId.deviceId(uri(dpid)));
303 }
304
305 @Override
306 public void switchChanged(PcepDpid dpid) {
307 // TODO Auto-generated method stub
308
309 }
310
311 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700312 public void handlePceplink(PcepLink link) {
cheng fan48e832c2015-05-29 01:54:47 +0800313
314 OperationType operType = link.getOperationType();
315 LinkDescription ld = buildLinkDescription(link);
316 if (ld == null) {
317 log.error("Invalid link info.");
318 return;
319 }
320 switch (operType) {
chengfan359abf72015-07-02 23:33:16 +0800321 case ADD:
322 case UPDATE:
323 linkProviderService.linkDetected(ld);
324 break;
cheng fan48e832c2015-05-29 01:54:47 +0800325
chengfan359abf72015-07-02 23:33:16 +0800326 case DELETE:
327 linkProviderService.linkVanished(ld);
328 break;
cheng fan48e832c2015-05-29 01:54:47 +0800329
chengfan359abf72015-07-02 23:33:16 +0800330 default:
331 break;
cheng fan48e832c2015-05-29 01:54:47 +0800332
333 }
334 }
335
Priyanka B94395bf2016-05-21 18:39:46 +0530336 @Override
337 public void addNode(PcepClient pc) {
338 if (deviceProviderService == null) {
339 return;
340 }
341
342 //Right now device URI for PCEP devices is their LSRID
343 DeviceId deviceId = deviceId(uri(new PcepDpid(pc.getPccId().id().getIp4Address().toInt())));
344 ChassisId cId = new ChassisId();
345
346 Device.Type deviceType = Device.Type.ROUTER;
347
348 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
349 //PCC capabilities (SR, PCECC and PCECC-SR)
350 annotationBuilder.set(SR_CAPABILITY, String.valueOf(pc.capability().srCapability()));
351 annotationBuilder.set(PCECC_CAPABILITY, String.valueOf(pc.capability().pceccCapability()));
352 annotationBuilder.set(LABEL_STACK_CAPABILITY, String.valueOf(pc.capability().labelStackCapability()));
353 //PccId is the lsrId contained in openMsg, if not present it will be the socket address
354 annotationBuilder.set(LSRID, String.valueOf(pc.getPccId().id()));
355
356 DeviceDescription description = new DefaultDeviceDescription(
357 deviceId.uri(),
358 deviceType,
359 UNKNOWN,
360 UNKNOWN,
361 UNKNOWN,
362 UNKNOWN,
363 cId,
364 annotationBuilder.build());
365
366 deviceProviderService.deviceConnected(deviceId, description);
367 }
368
369 @Override
370 public void deleteNode(PccId pccId) {
371 if (deviceProviderService == null || deviceService == null) {
372 return;
373 }
374 //TODO: In device manager, in deviceDisconnected() method, get the device but null check is not validated
375 if (deviceService.getDevice(DeviceId.deviceId(uri(new PcepDpid(pccId.id()
376 .getIp4Address().toInt())))) == null) {
377 return;
378 }
379 deviceProviderService.deviceDisconnected(deviceId(uri(new PcepDpid(pccId.id().getIp4Address().toInt()))));
380 }
cheng fan48e832c2015-05-29 01:54:47 +0800381 }
382
383 @Override
384 public void triggerProbe(DeviceId deviceId) {
385 // TODO Auto-generated method stub
cheng fan48e832c2015-05-29 01:54:47 +0800386 }
387
388 @Override
389 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
cheng fan48e832c2015-05-29 01:54:47 +0800390 }
391
392 @Override
393 public boolean isReachable(DeviceId deviceId) {
394 // TODO Auto-generated method stub
cheng fan7716ec92015-05-31 01:53:19 +0800395 return true;
cheng fan48e832c2015-05-29 01:54:47 +0800396 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700397
398 @Override
399 public void changePortState(DeviceId deviceId, PortNumber portNumber,
400 boolean enable) {
401 // TODO Auto-generated method stub
402 }
cheng fan48e832c2015-05-29 01:54:47 +0800403}