blob: 9a445fbf38a16e4798b03108de82edc3d5757c20 [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;
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;
Avantika-Huaweife44ea62016-05-27 19:21:24 +053029import org.onosproject.net.config.ConfigFactory;
30import org.onosproject.net.config.NetworkConfigRegistry;
31import org.onosproject.net.config.NetworkConfigService;
32import org.onosproject.net.config.basics.SubjectFactories;
cheng fan48e832c2015-05-29 01:54:47 +080033import org.onosproject.net.MastershipRole;
chengfan359abf72015-07-02 23:33:16 +080034import org.onosproject.net.OchPort;
35import org.onosproject.net.OduCltPort;
36import org.onosproject.net.OmsPort;
37import org.onosproject.net.Port;
Saurav Dasa2d37502016-03-25 17:50:40 -070038import org.onosproject.net.PortNumber;
cheng fan48e832c2015-05-29 01:54:47 +080039import org.onosproject.net.device.DefaultDeviceDescription;
40import org.onosproject.net.device.DefaultPortDescription;
41import org.onosproject.net.device.DeviceDescription;
42import org.onosproject.net.device.DeviceProvider;
43import org.onosproject.net.device.DeviceProviderRegistry;
44import org.onosproject.net.device.DeviceProviderService;
45import org.onosproject.net.device.DeviceService;
chengfan359abf72015-07-02 23:33:16 +080046import org.onosproject.net.device.OchPortDescription;
47import org.onosproject.net.device.OduCltPortDescription;
48import org.onosproject.net.device.OmsPortDescription;
cheng fan48e832c2015-05-29 01:54:47 +080049import org.onosproject.net.device.PortDescription;
50import org.onosproject.net.link.DefaultLinkDescription;
51import org.onosproject.net.link.LinkDescription;
52import org.onosproject.net.link.LinkProvider;
53import org.onosproject.net.link.LinkProviderRegistry;
54import org.onosproject.net.link.LinkProviderService;
cheng fan48e832c2015-05-29 01:54:47 +080055import org.onosproject.net.provider.AbstractProvider;
56import org.onosproject.net.provider.ProviderId;
Avantika-Huaweife44ea62016-05-27 19:21:24 +053057import org.onosproject.pcep.api.DeviceCapability;
cheng fan48e832c2015-05-29 01:54:47 +080058import org.onosproject.pcep.api.PcepController;
59import org.onosproject.pcep.api.PcepDpid;
60import org.onosproject.pcep.api.PcepLink;
cheng fan7716ec92015-05-31 01:53:19 +080061import org.onosproject.pcep.api.PcepLink.PortType;
cheng fan48e832c2015-05-29 01:54:47 +080062import org.onosproject.pcep.api.PcepLinkListener;
63import org.onosproject.pcep.api.PcepOperator.OperationType;
64import org.onosproject.pcep.api.PcepSwitch;
65import org.onosproject.pcep.api.PcepSwitchListener;
Priyanka B94395bf2016-05-21 18:39:46 +053066import org.onosproject.pcep.controller.PccId;
67import org.onosproject.pcep.controller.PcepClient;
68import org.onosproject.pcep.controller.PcepClientController;
69import org.onosproject.pcep.controller.PcepNodeListener;
cheng fan48e832c2015-05-29 01:54:47 +080070import org.slf4j.Logger;
71import org.slf4j.LoggerFactory;
72
chengfan359abf72015-07-02 23:33:16 +080073import java.util.ArrayList;
74import java.util.HashMap;
75import java.util.List;
76
77import static com.google.common.base.Preconditions.checkNotNull;
78import static org.onosproject.net.DeviceId.deviceId;
79import static org.onosproject.pcep.api.PcepDpid.uri;
80
cheng fan48e832c2015-05-29 01:54:47 +080081/**
82 * Provider which uses an PCEP controller to detect network infrastructure
83 * topology.
84 */
85@Component(immediate = true)
86public class PcepTopologyProvider extends AbstractProvider
87 implements LinkProvider, DeviceProvider {
88
Priyanka B9bee0802016-04-27 22:06:02 +053089 /**
90 * Creates instance of PCEP topology provider.
91 */
cheng fan48e832c2015-05-29 01:54:47 +080092 public PcepTopologyProvider() {
Priyanka Bcdf9b102016-06-07 20:01:38 +053093 //In BGP-PCEP app, since both BGP and PCEP topology provider have same scheme
94 //so BGP will be primary and PCEP topology provider will be ancillary.
95 super(new ProviderId("l3", "org.onosproject.provider.pcep", true));
cheng fan48e832c2015-05-29 01:54:47 +080096 }
97
98 private static final Logger log = LoggerFactory
99 .getLogger(PcepTopologyProvider.class);
100
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected LinkProviderRegistry linkProviderRegistry;
103
104 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
105 protected DeviceProviderRegistry deviceProviderRegistry;
106
107 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
108 protected PcepController controller;
109
110 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
111 protected DeviceService deviceService;
112
113 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Priyanka B94395bf2016-05-21 18:39:46 +0530114 protected PcepClientController pcepClientController;
115
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530116 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
117 protected NetworkConfigRegistry netConfigRegistry;
118
119 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
120 protected NetworkConfigService netConfigService;
121
cheng fan48e832c2015-05-29 01:54:47 +0800122 private DeviceProviderService deviceProviderService;
123 private LinkProviderService linkProviderService;
chengfan359abf72015-07-02 23:33:16 +0800124
125 private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
cheng fan48e832c2015-05-29 01:54:47 +0800126 private InternalLinkProvider listener = new InternalLinkProvider();
127
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530128 private final ConfigFactory<DeviceId, DeviceCapability> configFactory =
129 new ConfigFactory<DeviceId, DeviceCapability>(SubjectFactories.DEVICE_SUBJECT_FACTORY,
Avantika-Huawei3524d852016-06-04 20:44:13 +0530130 DeviceCapability.class, "deviceCapability", false) {
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530131 @Override
132 public DeviceCapability createConfig() {
133 return new DeviceCapability();
134 }
135 };
Priyanka B94395bf2016-05-21 18:39:46 +0530136
cheng fan48e832c2015-05-29 01:54:47 +0800137 @Activate
138 public void activate() {
139 linkProviderService = linkProviderRegistry.register(this);
140 deviceProviderService = deviceProviderRegistry.register(this);
141 controller.addListener(listener);
142 controller.addLinkListener(listener);
Priyanka B94395bf2016-05-21 18:39:46 +0530143 pcepClientController.addNodeListener(listener);
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530144 netConfigRegistry.registerConfigFactory(configFactory);
Priyanka Bcdf9b102016-06-07 20:01:38 +0530145 log.info("Started");
cheng fan48e832c2015-05-29 01:54:47 +0800146 }
147
148 @Deactivate
149 public void deactivate() {
150 linkProviderRegistry.unregister(this);
151 linkProviderService = null;
152 controller.removeListener(listener);
153 controller.removeLinkListener(listener);
Priyanka B94395bf2016-05-21 18:39:46 +0530154 pcepClientController.removeNodeListener(listener);
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530155 netConfigRegistry.unregisterConfigFactory(configFactory);
Priyanka Bcdf9b102016-06-07 20:01:38 +0530156 log.info("Stopped");
cheng fan48e832c2015-05-29 01:54:47 +0800157 }
158
chengfan359abf72015-07-02 23:33:16 +0800159 private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
160 Port port,
cheng fan7716ec92015-05-31 01:53:19 +0800161 PortType portType) {
chengfan359abf72015-07-02 23:33:16 +0800162
163 List<PortDescription> portList;
164
165 if (portMap.containsKey(dpid.value())) {
166 portList = portMap.get(dpid.value());
167 } else {
168 portList = new ArrayList<>();
cheng fan48e832c2015-05-29 01:54:47 +0800169 }
chengfan359abf72015-07-02 23:33:16 +0800170 if (port != null && portType != null) {
171 portList.add(buildPortDescription(port, portType));
172 }
173
174 portMap.put(dpid.value(), portList);
175 return portList;
cheng fan48e832c2015-05-29 01:54:47 +0800176 }
177
chengfan359abf72015-07-02 23:33:16 +0800178 private PortDescription buildPortDescription(Port port, PortType portType) {
179 PortDescription portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800180
chengfan359abf72015-07-02 23:33:16 +0800181 switch (portType) {
182 case OCH_PORT:
183 OchPort ochp = (OchPort) port;
184 portDescription = new OchPortDescription(ochp.number(), ochp.isEnabled(),
185 ochp.signalType(), ochp.isTunable(),
186 ochp.lambda());
187 break;
188 case ODU_PORT:
189 OduCltPort odup = (OduCltPort) port;
190 portDescription = new OduCltPortDescription(odup.number(), odup.isEnabled(),
191 odup.signalType());
192 break;
193 case OMS_PORT:
194 OmsPort op = (OmsPort) port;
195 portDescription = new OmsPortDescription(op.number(), op.isEnabled(), op.minFrequency(),
196 op.maxFrequency(), op.grid());
197 break;
198 default:
199 portDescription = new DefaultPortDescription(port.number(), port.isEnabled());
200 break;
201 }
202 return portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800203 }
204
205 /**
chengfan3e618792015-06-28 21:42:01 +0800206 * Build a link description from a pcep link.
cheng fan48e832c2015-05-29 01:54:47 +0800207 *
chengfan3e618792015-06-28 21:42:01 +0800208 * @param pceLink pcep link
209 * @return LinkDescription onos link description
cheng fan48e832c2015-05-29 01:54:47 +0800210 */
211 private LinkDescription buildLinkDescription(PcepLink pceLink) {
212 LinkDescription ld;
chengfan359abf72015-07-02 23:33:16 +0800213 checkNotNull(pceLink);
cheng fan48e832c2015-05-29 01:54:47 +0800214 DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
215 DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));
216
cheng fan48e832c2015-05-29 01:54:47 +0800217 deviceProviderService
218 .updatePorts(srcDeviceID,
chengfan359abf72015-07-02 23:33:16 +0800219 buildPortDescriptions(pceLink.linkSrcDeviceID(),
220 pceLink.linkSrcPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800221
chengfan359abf72015-07-02 23:33:16 +0800222 deviceProviderService
223 .updatePorts(dstDeviceID,
224 buildPortDescriptions(pceLink.linkDstDeviceId(),
225 pceLink.linkDstPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800226
chengfan359abf72015-07-02 23:33:16 +0800227 ConnectPoint src = new ConnectPoint(srcDeviceID, pceLink.linkSrcPort().number());
cheng fan48e832c2015-05-29 01:54:47 +0800228
chengfan359abf72015-07-02 23:33:16 +0800229 ConnectPoint dst = new ConnectPoint(dstDeviceID, pceLink.linkDstPort().number());
230
231 DefaultAnnotations extendedAttributes = DefaultAnnotations
232 .builder()
233 .set("subType", String.valueOf(pceLink.linkSubType()))
234 .set("workState", pceLink.linkState())
235 .set("distance", String.valueOf(pceLink.linkDistance()))
236 .set("capType", pceLink.linkCapacityType().toLowerCase())
237 .set("avail_" + pceLink.linkCapacityType().toLowerCase(),
238 String.valueOf(pceLink.linkAvailValue()))
239 .set("max_" + pceLink.linkCapacityType().toLowerCase(),
240 String.valueOf(pceLink.linkMaxValue())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800241 // construct the link
chengfan359abf72015-07-02 23:33:16 +0800242 ld = new DefaultLinkDescription(src, dst, Type.OPTICAL, extendedAttributes);
cheng fan48e832c2015-05-29 01:54:47 +0800243 return ld;
244 }
245
cheng fan48e832c2015-05-29 01:54:47 +0800246 private class InternalLinkProvider
Priyanka B94395bf2016-05-21 18:39:46 +0530247 implements PcepSwitchListener, PcepLinkListener, PcepNodeListener {
cheng fan48e832c2015-05-29 01:54:47 +0800248
249 @Override
250 public void switchAdded(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800251 if (deviceProviderService == null) {
252 return;
253 }
chengfan359abf72015-07-02 23:33:16 +0800254 DeviceId deviceId = deviceId(uri(dpid));
cheng fan48e832c2015-05-29 01:54:47 +0800255 PcepSwitch sw = controller.getSwitch(dpid);
256 checkNotNull(sw, "device should not null.");
257 // The default device type is switch.
cheng fan48e832c2015-05-29 01:54:47 +0800258 ChassisId cId = new ChassisId(dpid.value());
chengfan359abf72015-07-02 23:33:16 +0800259 Device.Type deviceType;
cheng fan48e832c2015-05-29 01:54:47 +0800260
cheng fan7716ec92015-05-31 01:53:19 +0800261 switch (sw.getDeviceType()) {
chengfan359abf72015-07-02 23:33:16 +0800262 case ROADM:
263 deviceType = Device.Type.ROADM;
264 break;
265 case OTN:
266 deviceType = Device.Type.SWITCH;
267 break;
268 case ROUTER:
269 deviceType = Device.Type.ROUTER;
270 break;
271 default:
272 deviceType = Device.Type.OTHER;
cheng fan7716ec92015-05-31 01:53:19 +0800273 }
cheng fan48e832c2015-05-29 01:54:47 +0800274
275 DeviceDescription description = new DefaultDeviceDescription(
chengfan359abf72015-07-02 23:33:16 +0800276 deviceId.uri(),
277 deviceType,
278 sw.manufacturerDescription(),
279 sw.hardwareDescription(),
280 sw.softwareDescription(),
281 sw.serialNumber(),
282 cId);
283 deviceProviderService.deviceConnected(deviceId, description);
cheng fan48e832c2015-05-29 01:54:47 +0800284
285 }
286
287 @Override
288 public void switchRemoved(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800289 if (deviceProviderService == null || linkProviderService == null) {
290 return;
291 }
292 deviceProviderService.deviceDisconnected(deviceId(uri(dpid)));
293
294 linkProviderService.linksVanished(DeviceId.deviceId(uri(dpid)));
295 }
296
297 @Override
298 public void switchChanged(PcepDpid dpid) {
299 // TODO Auto-generated method stub
300
301 }
302
303 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700304 public void handlePceplink(PcepLink link) {
cheng fan48e832c2015-05-29 01:54:47 +0800305
306 OperationType operType = link.getOperationType();
307 LinkDescription ld = buildLinkDescription(link);
308 if (ld == null) {
309 log.error("Invalid link info.");
310 return;
311 }
312 switch (operType) {
chengfan359abf72015-07-02 23:33:16 +0800313 case ADD:
314 case UPDATE:
315 linkProviderService.linkDetected(ld);
316 break;
cheng fan48e832c2015-05-29 01:54:47 +0800317
chengfan359abf72015-07-02 23:33:16 +0800318 case DELETE:
319 linkProviderService.linkVanished(ld);
320 break;
cheng fan48e832c2015-05-29 01:54:47 +0800321
chengfan359abf72015-07-02 23:33:16 +0800322 default:
323 break;
cheng fan48e832c2015-05-29 01:54:47 +0800324
325 }
326 }
327
Priyanka B94395bf2016-05-21 18:39:46 +0530328 @Override
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530329 public void addDevicePcepConfig(PcepClient pc) {
330 if (netConfigRegistry == null) {
331 log.error("Cannot add PCEP device capability as network config service is not available.");
Priyanka B94395bf2016-05-21 18:39:46 +0530332 return;
333 }
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530334 DeviceId pccDeviceId = DeviceId.deviceId(String.valueOf(pc.getPccId().ipAddress()));
335 DeviceCapability deviceCap = netConfigService.addConfig(pccDeviceId, DeviceCapability.class);
336 deviceCap.setLabelStackCap(pc.capability().labelStackCapability())
337 .setLocalLabelCap(pc.capability().pceccCapability())
338 .setSrCap(pc.capability().srCapability())
339 .apply();
Priyanka B94395bf2016-05-21 18:39:46 +0530340 }
341
342 @Override
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530343 public void deleteDevicePcepConfig(PccId pccId) {
344 if (netConfigRegistry == null) {
345 log.error("Cannot remove PCEP device capability as network config service is not available.");
Priyanka B94395bf2016-05-21 18:39:46 +0530346 return;
347 }
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530348 DeviceId pccDeviceId = DeviceId.deviceId(String.valueOf(pccId.ipAddress()));
349 netConfigService.removeConfig(pccDeviceId, DeviceCapability.class);
Priyanka B94395bf2016-05-21 18:39:46 +0530350 }
cheng fan48e832c2015-05-29 01:54:47 +0800351 }
352
353 @Override
354 public void triggerProbe(DeviceId deviceId) {
355 // TODO Auto-generated method stub
cheng fan48e832c2015-05-29 01:54:47 +0800356 }
357
358 @Override
359 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
cheng fan48e832c2015-05-29 01:54:47 +0800360 }
361
362 @Override
363 public boolean isReachable(DeviceId deviceId) {
364 // TODO Auto-generated method stub
cheng fan7716ec92015-05-31 01:53:19 +0800365 return true;
cheng fan48e832c2015-05-29 01:54:47 +0800366 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700367
368 @Override
369 public void changePortState(DeviceId deviceId, PortNumber portNumber,
370 boolean enable) {
371 // TODO Auto-generated method stub
372 }
cheng fan48e832c2015-05-29 01:54:47 +0800373}