blob: 75a53f3090a5cbfe66f6283d69058b40a1dfac4b [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;
65import org.slf4j.Logger;
66import org.slf4j.LoggerFactory;
67
chengfan359abf72015-07-02 23:33:16 +080068import java.util.ArrayList;
69import java.util.HashMap;
70import java.util.List;
71
72import static com.google.common.base.Preconditions.checkNotNull;
73import static org.onosproject.net.DeviceId.deviceId;
74import static org.onosproject.pcep.api.PcepDpid.uri;
75
cheng fan48e832c2015-05-29 01:54:47 +080076/**
77 * Provider which uses an PCEP controller to detect network infrastructure
78 * topology.
79 */
80@Component(immediate = true)
81public class PcepTopologyProvider extends AbstractProvider
82 implements LinkProvider, DeviceProvider {
83
Priyanka B9bee0802016-04-27 22:06:02 +053084 /**
85 * Creates instance of PCEP topology provider.
86 */
cheng fan48e832c2015-05-29 01:54:47 +080087 public PcepTopologyProvider() {
Priyanka B9bee0802016-04-27 22:06:02 +053088 super(new ProviderId("l3", "org.onosproject.provider.pcep"));
cheng fan48e832c2015-05-29 01:54:47 +080089 }
90
91 private static final Logger log = LoggerFactory
92 .getLogger(PcepTopologyProvider.class);
93
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 protected LinkProviderRegistry linkProviderRegistry;
96
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected DeviceProviderRegistry deviceProviderRegistry;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected PcepController controller;
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected DeviceService deviceService;
105
106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 protected LinkService linkService;
108
109 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
110 protected MastershipAdminService mastershipAdminService;
111
112 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
113 protected MastershipService mastershipService;
114
115 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
116 protected ClusterService clusterService;
117
118 private DeviceProviderService deviceProviderService;
119 private LinkProviderService linkProviderService;
chengfan359abf72015-07-02 23:33:16 +0800120
121 private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
cheng fan48e832c2015-05-29 01:54:47 +0800122 private InternalLinkProvider listener = new InternalLinkProvider();
123
124 @Activate
125 public void activate() {
126 linkProviderService = linkProviderRegistry.register(this);
127 deviceProviderService = deviceProviderRegistry.register(this);
128 controller.addListener(listener);
129 controller.addLinkListener(listener);
130 }
131
132 @Deactivate
133 public void deactivate() {
134 linkProviderRegistry.unregister(this);
135 linkProviderService = null;
136 controller.removeListener(listener);
137 controller.removeLinkListener(listener);
138 }
139
chengfan359abf72015-07-02 23:33:16 +0800140 private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
141 Port port,
cheng fan7716ec92015-05-31 01:53:19 +0800142 PortType portType) {
chengfan359abf72015-07-02 23:33:16 +0800143
144 List<PortDescription> portList;
145
146 if (portMap.containsKey(dpid.value())) {
147 portList = portMap.get(dpid.value());
148 } else {
149 portList = new ArrayList<>();
cheng fan48e832c2015-05-29 01:54:47 +0800150 }
chengfan359abf72015-07-02 23:33:16 +0800151 if (port != null && portType != null) {
152 portList.add(buildPortDescription(port, portType));
153 }
154
155 portMap.put(dpid.value(), portList);
156 return portList;
cheng fan48e832c2015-05-29 01:54:47 +0800157 }
158
chengfan359abf72015-07-02 23:33:16 +0800159 private PortDescription buildPortDescription(Port port, PortType portType) {
160 PortDescription portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800161
chengfan359abf72015-07-02 23:33:16 +0800162 switch (portType) {
163 case OCH_PORT:
164 OchPort ochp = (OchPort) port;
165 portDescription = new OchPortDescription(ochp.number(), ochp.isEnabled(),
166 ochp.signalType(), ochp.isTunable(),
167 ochp.lambda());
168 break;
169 case ODU_PORT:
170 OduCltPort odup = (OduCltPort) port;
171 portDescription = new OduCltPortDescription(odup.number(), odup.isEnabled(),
172 odup.signalType());
173 break;
174 case OMS_PORT:
175 OmsPort op = (OmsPort) port;
176 portDescription = new OmsPortDescription(op.number(), op.isEnabled(), op.minFrequency(),
177 op.maxFrequency(), op.grid());
178 break;
179 default:
180 portDescription = new DefaultPortDescription(port.number(), port.isEnabled());
181 break;
182 }
183 return portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800184 }
185
186 /**
chengfan3e618792015-06-28 21:42:01 +0800187 * Build a link description from a pcep link.
cheng fan48e832c2015-05-29 01:54:47 +0800188 *
chengfan3e618792015-06-28 21:42:01 +0800189 * @param pceLink pcep link
190 * @return LinkDescription onos link description
cheng fan48e832c2015-05-29 01:54:47 +0800191 */
192 private LinkDescription buildLinkDescription(PcepLink pceLink) {
193 LinkDescription ld;
chengfan359abf72015-07-02 23:33:16 +0800194 checkNotNull(pceLink);
cheng fan48e832c2015-05-29 01:54:47 +0800195 DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
196 DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));
197
cheng fan48e832c2015-05-29 01:54:47 +0800198 deviceProviderService
199 .updatePorts(srcDeviceID,
chengfan359abf72015-07-02 23:33:16 +0800200 buildPortDescriptions(pceLink.linkSrcDeviceID(),
201 pceLink.linkSrcPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800202
chengfan359abf72015-07-02 23:33:16 +0800203 deviceProviderService
204 .updatePorts(dstDeviceID,
205 buildPortDescriptions(pceLink.linkDstDeviceId(),
206 pceLink.linkDstPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800207
chengfan359abf72015-07-02 23:33:16 +0800208 ConnectPoint src = new ConnectPoint(srcDeviceID, pceLink.linkSrcPort().number());
cheng fan48e832c2015-05-29 01:54:47 +0800209
chengfan359abf72015-07-02 23:33:16 +0800210 ConnectPoint dst = new ConnectPoint(dstDeviceID, pceLink.linkDstPort().number());
211
212 DefaultAnnotations extendedAttributes = DefaultAnnotations
213 .builder()
214 .set("subType", String.valueOf(pceLink.linkSubType()))
215 .set("workState", pceLink.linkState())
216 .set("distance", String.valueOf(pceLink.linkDistance()))
217 .set("capType", pceLink.linkCapacityType().toLowerCase())
218 .set("avail_" + pceLink.linkCapacityType().toLowerCase(),
219 String.valueOf(pceLink.linkAvailValue()))
220 .set("max_" + pceLink.linkCapacityType().toLowerCase(),
221 String.valueOf(pceLink.linkMaxValue())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800222 // construct the link
chengfan359abf72015-07-02 23:33:16 +0800223 ld = new DefaultLinkDescription(src, dst, Type.OPTICAL, extendedAttributes);
cheng fan48e832c2015-05-29 01:54:47 +0800224 return ld;
225 }
226
cheng fan48e832c2015-05-29 01:54:47 +0800227 private class InternalLinkProvider
228 implements PcepSwitchListener, PcepLinkListener {
229
230 @Override
231 public void switchAdded(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800232 if (deviceProviderService == null) {
233 return;
234 }
chengfan359abf72015-07-02 23:33:16 +0800235 DeviceId deviceId = deviceId(uri(dpid));
cheng fan48e832c2015-05-29 01:54:47 +0800236 PcepSwitch sw = controller.getSwitch(dpid);
237 checkNotNull(sw, "device should not null.");
238 // The default device type is switch.
cheng fan48e832c2015-05-29 01:54:47 +0800239 ChassisId cId = new ChassisId(dpid.value());
chengfan359abf72015-07-02 23:33:16 +0800240 Device.Type deviceType;
cheng fan48e832c2015-05-29 01:54:47 +0800241
cheng fan7716ec92015-05-31 01:53:19 +0800242 switch (sw.getDeviceType()) {
chengfan359abf72015-07-02 23:33:16 +0800243 case ROADM:
244 deviceType = Device.Type.ROADM;
245 break;
246 case OTN:
247 deviceType = Device.Type.SWITCH;
248 break;
249 case ROUTER:
250 deviceType = Device.Type.ROUTER;
251 break;
252 default:
253 deviceType = Device.Type.OTHER;
cheng fan7716ec92015-05-31 01:53:19 +0800254 }
cheng fan48e832c2015-05-29 01:54:47 +0800255
256 DeviceDescription description = new DefaultDeviceDescription(
chengfan359abf72015-07-02 23:33:16 +0800257 deviceId.uri(),
258 deviceType,
259 sw.manufacturerDescription(),
260 sw.hardwareDescription(),
261 sw.softwareDescription(),
262 sw.serialNumber(),
263 cId);
264 deviceProviderService.deviceConnected(deviceId, description);
cheng fan48e832c2015-05-29 01:54:47 +0800265
266 }
267
268 @Override
269 public void switchRemoved(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800270 if (deviceProviderService == null || linkProviderService == null) {
271 return;
272 }
273 deviceProviderService.deviceDisconnected(deviceId(uri(dpid)));
274
275 linkProviderService.linksVanished(DeviceId.deviceId(uri(dpid)));
276 }
277
278 @Override
279 public void switchChanged(PcepDpid dpid) {
280 // TODO Auto-generated method stub
281
282 }
283
284 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700285 public void handlePceplink(PcepLink link) {
cheng fan48e832c2015-05-29 01:54:47 +0800286
287 OperationType operType = link.getOperationType();
288 LinkDescription ld = buildLinkDescription(link);
289 if (ld == null) {
290 log.error("Invalid link info.");
291 return;
292 }
293 switch (operType) {
chengfan359abf72015-07-02 23:33:16 +0800294 case ADD:
295 case UPDATE:
296 linkProviderService.linkDetected(ld);
297 break;
cheng fan48e832c2015-05-29 01:54:47 +0800298
chengfan359abf72015-07-02 23:33:16 +0800299 case DELETE:
300 linkProviderService.linkVanished(ld);
301 break;
cheng fan48e832c2015-05-29 01:54:47 +0800302
chengfan359abf72015-07-02 23:33:16 +0800303 default:
304 break;
cheng fan48e832c2015-05-29 01:54:47 +0800305
306 }
307 }
308
309 }
310
311 @Override
312 public void triggerProbe(DeviceId deviceId) {
313 // TODO Auto-generated method stub
cheng fan48e832c2015-05-29 01:54:47 +0800314 }
315
316 @Override
317 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
cheng fan48e832c2015-05-29 01:54:47 +0800318 }
319
320 @Override
321 public boolean isReachable(DeviceId deviceId) {
322 // TODO Auto-generated method stub
cheng fan7716ec92015-05-31 01:53:19 +0800323 return true;
cheng fan48e832c2015-05-29 01:54:47 +0800324 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700325
326 @Override
327 public void changePortState(DeviceId deviceId, PortNumber portNumber,
328 boolean enable) {
329 // TODO Auto-generated method stub
330 }
cheng fan48e832c2015-05-29 01:54:47 +0800331}