blob: d0f8c1b4acca8f7aafd58a647c7d94596d151130 [file] [log] [blame]
cheng fan48e832c2015-05-29 01:54:47 +08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
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
Ray Milkeyd84f89b2018-08-17 14:54:17 -070018import org.osgi.service.component.annotations.Activate;
19import org.osgi.service.component.annotations.Component;
20import org.osgi.service.component.annotations.Deactivate;
21import org.osgi.service.component.annotations.Reference;
22import org.osgi.service.component.annotations.ReferenceCardinality;
cheng fan48e832c2015-05-29 01:54:47 +080023import org.onlab.packet.ChassisId;
cheng fan48e832c2015-05-29 01:54:47 +080024import org.onosproject.net.ConnectPoint;
25import org.onosproject.net.DefaultAnnotations;
26import org.onosproject.net.Device;
27import org.onosproject.net.DeviceId;
cheng fan48e832c2015-05-29 01:54:47 +080028import org.onosproject.net.Link.Type;
Andrea Campanella5d73df72017-05-09 14:26:00 -070029import org.onosproject.net.SparseAnnotations;
Avantika-Huaweife44ea62016-05-27 19:21:24 +053030import org.onosproject.net.config.ConfigFactory;
31import org.onosproject.net.config.NetworkConfigRegistry;
32import org.onosproject.net.config.NetworkConfigService;
33import org.onosproject.net.config.basics.SubjectFactories;
cheng fan48e832c2015-05-29 01:54:47 +080034import org.onosproject.net.MastershipRole;
chengfan359abf72015-07-02 23:33:16 +080035import org.onosproject.net.Port;
Saurav Dasa2d37502016-03-25 17:50:40 -070036import org.onosproject.net.PortNumber;
cheng fan48e832c2015-05-29 01:54:47 +080037import org.onosproject.net.device.DefaultDeviceDescription;
38import org.onosproject.net.device.DefaultPortDescription;
39import org.onosproject.net.device.DeviceDescription;
40import org.onosproject.net.device.DeviceProvider;
41import org.onosproject.net.device.DeviceProviderRegistry;
42import org.onosproject.net.device.DeviceProviderService;
43import org.onosproject.net.device.DeviceService;
44import org.onosproject.net.device.PortDescription;
45import org.onosproject.net.link.DefaultLinkDescription;
46import org.onosproject.net.link.LinkDescription;
47import org.onosproject.net.link.LinkProvider;
48import org.onosproject.net.link.LinkProviderRegistry;
49import org.onosproject.net.link.LinkProviderService;
cheng fan48e832c2015-05-29 01:54:47 +080050import org.onosproject.net.provider.AbstractProvider;
51import org.onosproject.net.provider.ProviderId;
Avantika-Huaweife44ea62016-05-27 19:21:24 +053052import org.onosproject.pcep.api.DeviceCapability;
cheng fan48e832c2015-05-29 01:54:47 +080053import org.onosproject.pcep.api.PcepController;
54import org.onosproject.pcep.api.PcepDpid;
55import org.onosproject.pcep.api.PcepLink;
56import org.onosproject.pcep.api.PcepLinkListener;
57import org.onosproject.pcep.api.PcepOperator.OperationType;
58import org.onosproject.pcep.api.PcepSwitch;
59import org.onosproject.pcep.api.PcepSwitchListener;
harikrushna-Huaweia2c7c202017-04-10 18:22:00 +053060import org.onosproject.pcep.server.PccId;
61import org.onosproject.pcep.server.PcepClient;
62import org.onosproject.pcep.server.PcepClientController;
63import org.onosproject.pcep.server.PcepNodeListener;
cheng fan48e832c2015-05-29 01:54:47 +080064import org.slf4j.Logger;
65import org.slf4j.LoggerFactory;
66
chengfan359abf72015-07-02 23:33:16 +080067import java.util.ArrayList;
68import java.util.HashMap;
69import java.util.List;
70
71import static com.google.common.base.Preconditions.checkNotNull;
72import static org.onosproject.net.DeviceId.deviceId;
73import static org.onosproject.pcep.api.PcepDpid.uri;
74
cheng fan48e832c2015-05-29 01:54:47 +080075/**
76 * Provider which uses an PCEP controller to detect network infrastructure
77 * topology.
78 */
79@Component(immediate = true)
80public class PcepTopologyProvider extends AbstractProvider
81 implements LinkProvider, DeviceProvider {
82
Priyanka B9bee0802016-04-27 22:06:02 +053083 /**
84 * Creates instance of PCEP topology provider.
85 */
cheng fan48e832c2015-05-29 01:54:47 +080086 public PcepTopologyProvider() {
Priyanka Bcdf9b102016-06-07 20:01:38 +053087 //In BGP-PCEP app, since both BGP and PCEP topology provider have same scheme
88 //so BGP will be primary and PCEP topology provider will be ancillary.
89 super(new ProviderId("l3", "org.onosproject.provider.pcep", true));
cheng fan48e832c2015-05-29 01:54:47 +080090 }
91
92 private static final Logger log = LoggerFactory
93 .getLogger(PcepTopologyProvider.class);
94
Ray Milkeyd84f89b2018-08-17 14:54:17 -070095 @Reference(cardinality = ReferenceCardinality.MANDATORY)
cheng fan48e832c2015-05-29 01:54:47 +080096 protected LinkProviderRegistry linkProviderRegistry;
97
Ray Milkeyd84f89b2018-08-17 14:54:17 -070098 @Reference(cardinality = ReferenceCardinality.MANDATORY)
cheng fan48e832c2015-05-29 01:54:47 +080099 protected DeviceProviderRegistry deviceProviderRegistry;
100
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700101 @Reference(cardinality = ReferenceCardinality.MANDATORY)
cheng fan48e832c2015-05-29 01:54:47 +0800102 protected PcepController controller;
103
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700104 @Reference(cardinality = ReferenceCardinality.MANDATORY)
cheng fan48e832c2015-05-29 01:54:47 +0800105 protected DeviceService deviceService;
106
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700107 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Priyanka B94395bf2016-05-21 18:39:46 +0530108 protected PcepClientController pcepClientController;
109
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700110 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530111 protected NetworkConfigRegistry netConfigRegistry;
112
Ray Milkeyd84f89b2018-08-17 14:54:17 -0700113 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530114 protected NetworkConfigService netConfigService;
115
cheng fan48e832c2015-05-29 01:54:47 +0800116 private DeviceProviderService deviceProviderService;
117 private LinkProviderService linkProviderService;
chengfan359abf72015-07-02 23:33:16 +0800118
119 private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
cheng fan48e832c2015-05-29 01:54:47 +0800120 private InternalLinkProvider listener = new InternalLinkProvider();
121
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530122 private final ConfigFactory<DeviceId, DeviceCapability> configFactory =
123 new ConfigFactory<DeviceId, DeviceCapability>(SubjectFactories.DEVICE_SUBJECT_FACTORY,
Avantika-Huawei3524d852016-06-04 20:44:13 +0530124 DeviceCapability.class, "deviceCapability", false) {
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530125 @Override
126 public DeviceCapability createConfig() {
127 return new DeviceCapability();
128 }
129 };
Priyanka B94395bf2016-05-21 18:39:46 +0530130
cheng fan48e832c2015-05-29 01:54:47 +0800131 @Activate
132 public void activate() {
133 linkProviderService = linkProviderRegistry.register(this);
134 deviceProviderService = deviceProviderRegistry.register(this);
135 controller.addListener(listener);
136 controller.addLinkListener(listener);
Priyanka B94395bf2016-05-21 18:39:46 +0530137 pcepClientController.addNodeListener(listener);
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530138 netConfigRegistry.registerConfigFactory(configFactory);
Priyanka Bcdf9b102016-06-07 20:01:38 +0530139 log.info("Started");
cheng fan48e832c2015-05-29 01:54:47 +0800140 }
141
142 @Deactivate
143 public void deactivate() {
144 linkProviderRegistry.unregister(this);
145 linkProviderService = null;
146 controller.removeListener(listener);
147 controller.removeLinkListener(listener);
Priyanka B94395bf2016-05-21 18:39:46 +0530148 pcepClientController.removeNodeListener(listener);
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530149 netConfigRegistry.unregisterConfigFactory(configFactory);
Priyanka Bcdf9b102016-06-07 20:01:38 +0530150 log.info("Stopped");
cheng fan48e832c2015-05-29 01:54:47 +0800151 }
152
chengfan359abf72015-07-02 23:33:16 +0800153 private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
Andrea Campanella5d73df72017-05-09 14:26:00 -0700154 Port port) {
chengfan359abf72015-07-02 23:33:16 +0800155
156 List<PortDescription> portList;
157
158 if (portMap.containsKey(dpid.value())) {
159 portList = portMap.get(dpid.value());
160 } else {
161 portList = new ArrayList<>();
cheng fan48e832c2015-05-29 01:54:47 +0800162 }
Andrea Campanella5d73df72017-05-09 14:26:00 -0700163 if (port != null) {
164 SparseAnnotations annotations = DefaultAnnotations.builder()
165 .putAll(port.annotations()).build();
Yuta HIGUCHI53e47962018-03-01 23:50:48 -0800166 portList.add(DefaultPortDescription.builder()
167 .withPortNumber(port.number())
168 .isEnabled(port.isEnabled())
169 .type(port.type())
170 .portSpeed(port.portSpeed())
171 .annotations(annotations)
172 .build());
chengfan359abf72015-07-02 23:33:16 +0800173 }
174
175 portMap.put(dpid.value(), portList);
176 return portList;
cheng fan48e832c2015-05-29 01:54:47 +0800177 }
178
cheng fan48e832c2015-05-29 01:54:47 +0800179 /**
chengfan3e618792015-06-28 21:42:01 +0800180 * Build a link description from a pcep link.
cheng fan48e832c2015-05-29 01:54:47 +0800181 *
chengfan3e618792015-06-28 21:42:01 +0800182 * @param pceLink pcep link
183 * @return LinkDescription onos link description
cheng fan48e832c2015-05-29 01:54:47 +0800184 */
185 private LinkDescription buildLinkDescription(PcepLink pceLink) {
186 LinkDescription ld;
chengfan359abf72015-07-02 23:33:16 +0800187 checkNotNull(pceLink);
cheng fan48e832c2015-05-29 01:54:47 +0800188 DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
189 DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));
190
cheng fan48e832c2015-05-29 01:54:47 +0800191 deviceProviderService
192 .updatePorts(srcDeviceID,
chengfan359abf72015-07-02 23:33:16 +0800193 buildPortDescriptions(pceLink.linkSrcDeviceID(),
Andrea Campanella5d73df72017-05-09 14:26:00 -0700194 pceLink.linkSrcPort()));
cheng fan48e832c2015-05-29 01:54:47 +0800195
chengfan359abf72015-07-02 23:33:16 +0800196 deviceProviderService
197 .updatePorts(dstDeviceID,
198 buildPortDescriptions(pceLink.linkDstDeviceId(),
Andrea Campanella5d73df72017-05-09 14:26:00 -0700199 pceLink.linkDstPort()));
cheng fan48e832c2015-05-29 01:54:47 +0800200
chengfan359abf72015-07-02 23:33:16 +0800201 ConnectPoint src = new ConnectPoint(srcDeviceID, pceLink.linkSrcPort().number());
cheng fan48e832c2015-05-29 01:54:47 +0800202
chengfan359abf72015-07-02 23:33:16 +0800203 ConnectPoint dst = new ConnectPoint(dstDeviceID, pceLink.linkDstPort().number());
204
205 DefaultAnnotations extendedAttributes = DefaultAnnotations
206 .builder()
207 .set("subType", String.valueOf(pceLink.linkSubType()))
208 .set("workState", pceLink.linkState())
209 .set("distance", String.valueOf(pceLink.linkDistance()))
210 .set("capType", pceLink.linkCapacityType().toLowerCase())
211 .set("avail_" + pceLink.linkCapacityType().toLowerCase(),
212 String.valueOf(pceLink.linkAvailValue()))
213 .set("max_" + pceLink.linkCapacityType().toLowerCase(),
214 String.valueOf(pceLink.linkMaxValue())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800215 // construct the link
chengfan359abf72015-07-02 23:33:16 +0800216 ld = new DefaultLinkDescription(src, dst, Type.OPTICAL, extendedAttributes);
cheng fan48e832c2015-05-29 01:54:47 +0800217 return ld;
218 }
219
cheng fan48e832c2015-05-29 01:54:47 +0800220 private class InternalLinkProvider
Priyanka B94395bf2016-05-21 18:39:46 +0530221 implements PcepSwitchListener, PcepLinkListener, PcepNodeListener {
cheng fan48e832c2015-05-29 01:54:47 +0800222
223 @Override
224 public void switchAdded(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800225 if (deviceProviderService == null) {
226 return;
227 }
chengfan359abf72015-07-02 23:33:16 +0800228 DeviceId deviceId = deviceId(uri(dpid));
cheng fan48e832c2015-05-29 01:54:47 +0800229 PcepSwitch sw = controller.getSwitch(dpid);
230 checkNotNull(sw, "device should not null.");
231 // The default device type is switch.
cheng fan48e832c2015-05-29 01:54:47 +0800232 ChassisId cId = new ChassisId(dpid.value());
chengfan359abf72015-07-02 23:33:16 +0800233 Device.Type deviceType;
cheng fan48e832c2015-05-29 01:54:47 +0800234
cheng fan7716ec92015-05-31 01:53:19 +0800235 switch (sw.getDeviceType()) {
chengfan359abf72015-07-02 23:33:16 +0800236 case ROADM:
237 deviceType = Device.Type.ROADM;
238 break;
239 case OTN:
240 deviceType = Device.Type.SWITCH;
241 break;
242 case ROUTER:
243 deviceType = Device.Type.ROUTER;
244 break;
245 default:
246 deviceType = Device.Type.OTHER;
cheng fan7716ec92015-05-31 01:53:19 +0800247 }
cheng fan48e832c2015-05-29 01:54:47 +0800248
249 DeviceDescription description = new DefaultDeviceDescription(
chengfan359abf72015-07-02 23:33:16 +0800250 deviceId.uri(),
251 deviceType,
252 sw.manufacturerDescription(),
253 sw.hardwareDescription(),
254 sw.softwareDescription(),
255 sw.serialNumber(),
256 cId);
257 deviceProviderService.deviceConnected(deviceId, description);
cheng fan48e832c2015-05-29 01:54:47 +0800258
259 }
260
261 @Override
262 public void switchRemoved(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800263 if (deviceProviderService == null || linkProviderService == null) {
264 return;
265 }
266 deviceProviderService.deviceDisconnected(deviceId(uri(dpid)));
267
268 linkProviderService.linksVanished(DeviceId.deviceId(uri(dpid)));
269 }
270
271 @Override
272 public void switchChanged(PcepDpid dpid) {
273 // TODO Auto-generated method stub
274
275 }
276
277 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700278 public void handlePceplink(PcepLink link) {
cheng fan48e832c2015-05-29 01:54:47 +0800279
280 OperationType operType = link.getOperationType();
281 LinkDescription ld = buildLinkDescription(link);
282 if (ld == null) {
283 log.error("Invalid link info.");
284 return;
285 }
286 switch (operType) {
chengfan359abf72015-07-02 23:33:16 +0800287 case ADD:
288 case UPDATE:
289 linkProviderService.linkDetected(ld);
290 break;
cheng fan48e832c2015-05-29 01:54:47 +0800291
chengfan359abf72015-07-02 23:33:16 +0800292 case DELETE:
293 linkProviderService.linkVanished(ld);
294 break;
cheng fan48e832c2015-05-29 01:54:47 +0800295
chengfan359abf72015-07-02 23:33:16 +0800296 default:
297 break;
cheng fan48e832c2015-05-29 01:54:47 +0800298
299 }
300 }
301
Priyanka B94395bf2016-05-21 18:39:46 +0530302 @Override
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530303 public void addDevicePcepConfig(PcepClient pc) {
304 if (netConfigRegistry == null) {
305 log.error("Cannot add PCEP device capability as network config service is not available.");
Priyanka B94395bf2016-05-21 18:39:46 +0530306 return;
307 }
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530308 DeviceId pccDeviceId = DeviceId.deviceId(String.valueOf(pc.getPccId().ipAddress()));
309 DeviceCapability deviceCap = netConfigService.addConfig(pccDeviceId, DeviceCapability.class);
310 deviceCap.setLabelStackCap(pc.capability().labelStackCapability())
311 .setLocalLabelCap(pc.capability().pceccCapability())
312 .setSrCap(pc.capability().srCapability())
313 .apply();
Priyanka B94395bf2016-05-21 18:39:46 +0530314 }
315
316 @Override
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530317 public void deleteDevicePcepConfig(PccId pccId) {
318 if (netConfigRegistry == null) {
319 log.error("Cannot remove PCEP device capability as network config service is not available.");
Priyanka B94395bf2016-05-21 18:39:46 +0530320 return;
321 }
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530322 DeviceId pccDeviceId = DeviceId.deviceId(String.valueOf(pccId.ipAddress()));
323 netConfigService.removeConfig(pccDeviceId, DeviceCapability.class);
Priyanka B94395bf2016-05-21 18:39:46 +0530324 }
cheng fan48e832c2015-05-29 01:54:47 +0800325 }
326
327 @Override
328 public void triggerProbe(DeviceId deviceId) {
329 // TODO Auto-generated method stub
cheng fan48e832c2015-05-29 01:54:47 +0800330 }
331
332 @Override
333 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
cheng fan48e832c2015-05-29 01:54:47 +0800334 }
335
336 @Override
337 public boolean isReachable(DeviceId deviceId) {
338 // TODO Auto-generated method stub
cheng fan7716ec92015-05-31 01:53:19 +0800339 return true;
cheng fan48e832c2015-05-29 01:54:47 +0800340 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700341
342 @Override
343 public void changePortState(DeviceId deviceId, PortNumber portNumber,
344 boolean enable) {
345 // TODO Auto-generated method stub
346 }
cheng fan48e832c2015-05-29 01:54:47 +0800347}