blob: eaebc57fc9b817f69b4132af28afee7608a5a095 [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;
Avantika-Huaweife44ea62016-05-27 19:21:24 +053032import org.onosproject.net.config.ConfigFactory;
33import org.onosproject.net.config.NetworkConfigRegistry;
34import org.onosproject.net.config.NetworkConfigService;
35import org.onosproject.net.config.basics.SubjectFactories;
cheng fan48e832c2015-05-29 01:54:47 +080036import org.onosproject.net.MastershipRole;
chengfan359abf72015-07-02 23:33:16 +080037import org.onosproject.net.OchPort;
38import org.onosproject.net.OduCltPort;
39import org.onosproject.net.OmsPort;
40import org.onosproject.net.Port;
Saurav Dasa2d37502016-03-25 17:50:40 -070041import org.onosproject.net.PortNumber;
cheng fan48e832c2015-05-29 01:54:47 +080042import org.onosproject.net.device.DefaultDeviceDescription;
43import org.onosproject.net.device.DefaultPortDescription;
44import org.onosproject.net.device.DeviceDescription;
45import org.onosproject.net.device.DeviceProvider;
46import org.onosproject.net.device.DeviceProviderRegistry;
47import org.onosproject.net.device.DeviceProviderService;
48import org.onosproject.net.device.DeviceService;
chengfan359abf72015-07-02 23:33:16 +080049import org.onosproject.net.device.OchPortDescription;
50import org.onosproject.net.device.OduCltPortDescription;
51import org.onosproject.net.device.OmsPortDescription;
cheng fan48e832c2015-05-29 01:54:47 +080052import org.onosproject.net.device.PortDescription;
53import org.onosproject.net.link.DefaultLinkDescription;
54import org.onosproject.net.link.LinkDescription;
55import org.onosproject.net.link.LinkProvider;
56import org.onosproject.net.link.LinkProviderRegistry;
57import org.onosproject.net.link.LinkProviderService;
58import org.onosproject.net.link.LinkService;
59import org.onosproject.net.provider.AbstractProvider;
60import org.onosproject.net.provider.ProviderId;
Avantika-Huaweife44ea62016-05-27 19:21:24 +053061import org.onosproject.pcep.api.DeviceCapability;
cheng fan48e832c2015-05-29 01:54:47 +080062import org.onosproject.pcep.api.PcepController;
63import org.onosproject.pcep.api.PcepDpid;
64import org.onosproject.pcep.api.PcepLink;
cheng fan7716ec92015-05-31 01:53:19 +080065import org.onosproject.pcep.api.PcepLink.PortType;
cheng fan48e832c2015-05-29 01:54:47 +080066import org.onosproject.pcep.api.PcepLinkListener;
67import org.onosproject.pcep.api.PcepOperator.OperationType;
68import org.onosproject.pcep.api.PcepSwitch;
69import org.onosproject.pcep.api.PcepSwitchListener;
Priyanka B94395bf2016-05-21 18:39:46 +053070import org.onosproject.pcep.controller.PccId;
71import org.onosproject.pcep.controller.PcepClient;
72import org.onosproject.pcep.controller.PcepClientController;
73import org.onosproject.pcep.controller.PcepNodeListener;
cheng fan48e832c2015-05-29 01:54:47 +080074import org.slf4j.Logger;
75import org.slf4j.LoggerFactory;
76
chengfan359abf72015-07-02 23:33:16 +080077import java.util.ArrayList;
78import java.util.HashMap;
79import java.util.List;
80
81import static com.google.common.base.Preconditions.checkNotNull;
82import static org.onosproject.net.DeviceId.deviceId;
83import static org.onosproject.pcep.api.PcepDpid.uri;
84
cheng fan48e832c2015-05-29 01:54:47 +080085/**
86 * Provider which uses an PCEP controller to detect network infrastructure
87 * topology.
88 */
89@Component(immediate = true)
90public class PcepTopologyProvider extends AbstractProvider
91 implements LinkProvider, DeviceProvider {
92
Priyanka B9bee0802016-04-27 22:06:02 +053093 /**
94 * Creates instance of PCEP topology provider.
95 */
cheng fan48e832c2015-05-29 01:54:47 +080096 public PcepTopologyProvider() {
Priyanka B9bee0802016-04-27 22:06:02 +053097 super(new ProviderId("l3", "org.onosproject.provider.pcep"));
cheng fan48e832c2015-05-29 01:54:47 +080098 }
99
100 private static final Logger log = LoggerFactory
101 .getLogger(PcepTopologyProvider.class);
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected LinkProviderRegistry linkProviderRegistry;
105
106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 protected DeviceProviderRegistry deviceProviderRegistry;
108
109 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
110 protected PcepController controller;
111
112 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
113 protected DeviceService deviceService;
114
115 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
116 protected LinkService linkService;
117
118 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
119 protected MastershipAdminService mastershipAdminService;
120
121 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
122 protected MastershipService mastershipService;
123
124 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
125 protected ClusterService clusterService;
126
Priyanka B94395bf2016-05-21 18:39:46 +0530127 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
128 protected PcepClientController pcepClientController;
129
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530130 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
131 protected NetworkConfigRegistry netConfigRegistry;
132
133 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
134 protected NetworkConfigService netConfigService;
135
cheng fan48e832c2015-05-29 01:54:47 +0800136 private DeviceProviderService deviceProviderService;
137 private LinkProviderService linkProviderService;
chengfan359abf72015-07-02 23:33:16 +0800138
139 private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
cheng fan48e832c2015-05-29 01:54:47 +0800140 private InternalLinkProvider listener = new InternalLinkProvider();
141
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530142 private final ConfigFactory<DeviceId, DeviceCapability> configFactory =
143 new ConfigFactory<DeviceId, DeviceCapability>(SubjectFactories.DEVICE_SUBJECT_FACTORY,
144 DeviceCapability.class, "deviceCapability", true) {
145 @Override
146 public DeviceCapability createConfig() {
147 return new DeviceCapability();
148 }
149 };
Priyanka B94395bf2016-05-21 18:39:46 +0530150
cheng fan48e832c2015-05-29 01:54:47 +0800151 @Activate
152 public void activate() {
153 linkProviderService = linkProviderRegistry.register(this);
154 deviceProviderService = deviceProviderRegistry.register(this);
155 controller.addListener(listener);
156 controller.addLinkListener(listener);
Priyanka B94395bf2016-05-21 18:39:46 +0530157 pcepClientController.addNodeListener(listener);
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530158 netConfigRegistry.registerConfigFactory(configFactory);
cheng fan48e832c2015-05-29 01:54:47 +0800159 }
160
161 @Deactivate
162 public void deactivate() {
163 linkProviderRegistry.unregister(this);
164 linkProviderService = null;
165 controller.removeListener(listener);
166 controller.removeLinkListener(listener);
Priyanka B94395bf2016-05-21 18:39:46 +0530167 pcepClientController.removeNodeListener(listener);
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530168 netConfigRegistry.unregisterConfigFactory(configFactory);
cheng fan48e832c2015-05-29 01:54:47 +0800169 }
170
chengfan359abf72015-07-02 23:33:16 +0800171 private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
172 Port port,
cheng fan7716ec92015-05-31 01:53:19 +0800173 PortType portType) {
chengfan359abf72015-07-02 23:33:16 +0800174
175 List<PortDescription> portList;
176
177 if (portMap.containsKey(dpid.value())) {
178 portList = portMap.get(dpid.value());
179 } else {
180 portList = new ArrayList<>();
cheng fan48e832c2015-05-29 01:54:47 +0800181 }
chengfan359abf72015-07-02 23:33:16 +0800182 if (port != null && portType != null) {
183 portList.add(buildPortDescription(port, portType));
184 }
185
186 portMap.put(dpid.value(), portList);
187 return portList;
cheng fan48e832c2015-05-29 01:54:47 +0800188 }
189
chengfan359abf72015-07-02 23:33:16 +0800190 private PortDescription buildPortDescription(Port port, PortType portType) {
191 PortDescription portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800192
chengfan359abf72015-07-02 23:33:16 +0800193 switch (portType) {
194 case OCH_PORT:
195 OchPort ochp = (OchPort) port;
196 portDescription = new OchPortDescription(ochp.number(), ochp.isEnabled(),
197 ochp.signalType(), ochp.isTunable(),
198 ochp.lambda());
199 break;
200 case ODU_PORT:
201 OduCltPort odup = (OduCltPort) port;
202 portDescription = new OduCltPortDescription(odup.number(), odup.isEnabled(),
203 odup.signalType());
204 break;
205 case OMS_PORT:
206 OmsPort op = (OmsPort) port;
207 portDescription = new OmsPortDescription(op.number(), op.isEnabled(), op.minFrequency(),
208 op.maxFrequency(), op.grid());
209 break;
210 default:
211 portDescription = new DefaultPortDescription(port.number(), port.isEnabled());
212 break;
213 }
214 return portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800215 }
216
217 /**
chengfan3e618792015-06-28 21:42:01 +0800218 * Build a link description from a pcep link.
cheng fan48e832c2015-05-29 01:54:47 +0800219 *
chengfan3e618792015-06-28 21:42:01 +0800220 * @param pceLink pcep link
221 * @return LinkDescription onos link description
cheng fan48e832c2015-05-29 01:54:47 +0800222 */
223 private LinkDescription buildLinkDescription(PcepLink pceLink) {
224 LinkDescription ld;
chengfan359abf72015-07-02 23:33:16 +0800225 checkNotNull(pceLink);
cheng fan48e832c2015-05-29 01:54:47 +0800226 DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
227 DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));
228
cheng fan48e832c2015-05-29 01:54:47 +0800229 deviceProviderService
230 .updatePorts(srcDeviceID,
chengfan359abf72015-07-02 23:33:16 +0800231 buildPortDescriptions(pceLink.linkSrcDeviceID(),
232 pceLink.linkSrcPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800233
chengfan359abf72015-07-02 23:33:16 +0800234 deviceProviderService
235 .updatePorts(dstDeviceID,
236 buildPortDescriptions(pceLink.linkDstDeviceId(),
237 pceLink.linkDstPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800238
chengfan359abf72015-07-02 23:33:16 +0800239 ConnectPoint src = new ConnectPoint(srcDeviceID, pceLink.linkSrcPort().number());
cheng fan48e832c2015-05-29 01:54:47 +0800240
chengfan359abf72015-07-02 23:33:16 +0800241 ConnectPoint dst = new ConnectPoint(dstDeviceID, pceLink.linkDstPort().number());
242
243 DefaultAnnotations extendedAttributes = DefaultAnnotations
244 .builder()
245 .set("subType", String.valueOf(pceLink.linkSubType()))
246 .set("workState", pceLink.linkState())
247 .set("distance", String.valueOf(pceLink.linkDistance()))
248 .set("capType", pceLink.linkCapacityType().toLowerCase())
249 .set("avail_" + pceLink.linkCapacityType().toLowerCase(),
250 String.valueOf(pceLink.linkAvailValue()))
251 .set("max_" + pceLink.linkCapacityType().toLowerCase(),
252 String.valueOf(pceLink.linkMaxValue())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800253 // construct the link
chengfan359abf72015-07-02 23:33:16 +0800254 ld = new DefaultLinkDescription(src, dst, Type.OPTICAL, extendedAttributes);
cheng fan48e832c2015-05-29 01:54:47 +0800255 return ld;
256 }
257
cheng fan48e832c2015-05-29 01:54:47 +0800258 private class InternalLinkProvider
Priyanka B94395bf2016-05-21 18:39:46 +0530259 implements PcepSwitchListener, PcepLinkListener, PcepNodeListener {
cheng fan48e832c2015-05-29 01:54:47 +0800260
261 @Override
262 public void switchAdded(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800263 if (deviceProviderService == null) {
264 return;
265 }
chengfan359abf72015-07-02 23:33:16 +0800266 DeviceId deviceId = deviceId(uri(dpid));
cheng fan48e832c2015-05-29 01:54:47 +0800267 PcepSwitch sw = controller.getSwitch(dpid);
268 checkNotNull(sw, "device should not null.");
269 // The default device type is switch.
cheng fan48e832c2015-05-29 01:54:47 +0800270 ChassisId cId = new ChassisId(dpid.value());
chengfan359abf72015-07-02 23:33:16 +0800271 Device.Type deviceType;
cheng fan48e832c2015-05-29 01:54:47 +0800272
cheng fan7716ec92015-05-31 01:53:19 +0800273 switch (sw.getDeviceType()) {
chengfan359abf72015-07-02 23:33:16 +0800274 case ROADM:
275 deviceType = Device.Type.ROADM;
276 break;
277 case OTN:
278 deviceType = Device.Type.SWITCH;
279 break;
280 case ROUTER:
281 deviceType = Device.Type.ROUTER;
282 break;
283 default:
284 deviceType = Device.Type.OTHER;
cheng fan7716ec92015-05-31 01:53:19 +0800285 }
cheng fan48e832c2015-05-29 01:54:47 +0800286
287 DeviceDescription description = new DefaultDeviceDescription(
chengfan359abf72015-07-02 23:33:16 +0800288 deviceId.uri(),
289 deviceType,
290 sw.manufacturerDescription(),
291 sw.hardwareDescription(),
292 sw.softwareDescription(),
293 sw.serialNumber(),
294 cId);
295 deviceProviderService.deviceConnected(deviceId, description);
cheng fan48e832c2015-05-29 01:54:47 +0800296
297 }
298
299 @Override
300 public void switchRemoved(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800301 if (deviceProviderService == null || linkProviderService == null) {
302 return;
303 }
304 deviceProviderService.deviceDisconnected(deviceId(uri(dpid)));
305
306 linkProviderService.linksVanished(DeviceId.deviceId(uri(dpid)));
307 }
308
309 @Override
310 public void switchChanged(PcepDpid dpid) {
311 // TODO Auto-generated method stub
312
313 }
314
315 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700316 public void handlePceplink(PcepLink link) {
cheng fan48e832c2015-05-29 01:54:47 +0800317
318 OperationType operType = link.getOperationType();
319 LinkDescription ld = buildLinkDescription(link);
320 if (ld == null) {
321 log.error("Invalid link info.");
322 return;
323 }
324 switch (operType) {
chengfan359abf72015-07-02 23:33:16 +0800325 case ADD:
326 case UPDATE:
327 linkProviderService.linkDetected(ld);
328 break;
cheng fan48e832c2015-05-29 01:54:47 +0800329
chengfan359abf72015-07-02 23:33:16 +0800330 case DELETE:
331 linkProviderService.linkVanished(ld);
332 break;
cheng fan48e832c2015-05-29 01:54:47 +0800333
chengfan359abf72015-07-02 23:33:16 +0800334 default:
335 break;
cheng fan48e832c2015-05-29 01:54:47 +0800336
337 }
338 }
339
Priyanka B94395bf2016-05-21 18:39:46 +0530340 @Override
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530341 public void addDevicePcepConfig(PcepClient pc) {
342 if (netConfigRegistry == null) {
343 log.error("Cannot add PCEP device capability as network config service is not available.");
Priyanka B94395bf2016-05-21 18:39:46 +0530344 return;
345 }
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530346 DeviceId pccDeviceId = DeviceId.deviceId(String.valueOf(pc.getPccId().ipAddress()));
347 DeviceCapability deviceCap = netConfigService.addConfig(pccDeviceId, DeviceCapability.class);
348 deviceCap.setLabelStackCap(pc.capability().labelStackCapability())
349 .setLocalLabelCap(pc.capability().pceccCapability())
350 .setSrCap(pc.capability().srCapability())
351 .apply();
Priyanka B94395bf2016-05-21 18:39:46 +0530352 }
353
354 @Override
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530355 public void deleteDevicePcepConfig(PccId pccId) {
356 if (netConfigRegistry == null) {
357 log.error("Cannot remove PCEP device capability as network config service is not available.");
Priyanka B94395bf2016-05-21 18:39:46 +0530358 return;
359 }
Avantika-Huaweife44ea62016-05-27 19:21:24 +0530360 DeviceId pccDeviceId = DeviceId.deviceId(String.valueOf(pccId.ipAddress()));
361 netConfigService.removeConfig(pccDeviceId, DeviceCapability.class);
Priyanka B94395bf2016-05-21 18:39:46 +0530362 }
cheng fan48e832c2015-05-29 01:54:47 +0800363 }
364
365 @Override
366 public void triggerProbe(DeviceId deviceId) {
367 // TODO Auto-generated method stub
cheng fan48e832c2015-05-29 01:54:47 +0800368 }
369
370 @Override
371 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
cheng fan48e832c2015-05-29 01:54:47 +0800372 }
373
374 @Override
375 public boolean isReachable(DeviceId deviceId) {
376 // TODO Auto-generated method stub
cheng fan7716ec92015-05-31 01:53:19 +0800377 return true;
cheng fan48e832c2015-05-29 01:54:47 +0800378 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700379
380 @Override
381 public void changePortState(DeviceId deviceId, PortNumber portNumber,
382 boolean enable) {
383 // TODO Auto-generated method stub
384 }
cheng fan48e832c2015-05-29 01:54:47 +0800385}