blob: c52ca63b17dfdbc64ed77a70aab90aadac12f081 [file] [log] [blame]
cheng fan48e832c2015-05-29 01:54:47 +08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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;
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;
chengfan359abf72015-07-02 23:33:16 +080044import org.onosproject.net.device.OchPortDescription;
45import org.onosproject.net.device.OduCltPortDescription;
46import org.onosproject.net.device.OmsPortDescription;
cheng fan48e832c2015-05-29 01:54:47 +080047import org.onosproject.net.device.PortDescription;
48import org.onosproject.net.link.DefaultLinkDescription;
49import org.onosproject.net.link.LinkDescription;
50import org.onosproject.net.link.LinkProvider;
51import org.onosproject.net.link.LinkProviderRegistry;
52import org.onosproject.net.link.LinkProviderService;
53import org.onosproject.net.link.LinkService;
54import org.onosproject.net.provider.AbstractProvider;
55import org.onosproject.net.provider.ProviderId;
56import org.onosproject.pcep.api.PcepController;
57import org.onosproject.pcep.api.PcepDpid;
58import org.onosproject.pcep.api.PcepLink;
cheng fan7716ec92015-05-31 01:53:19 +080059import org.onosproject.pcep.api.PcepLink.PortType;
cheng fan48e832c2015-05-29 01:54:47 +080060import org.onosproject.pcep.api.PcepLinkListener;
61import org.onosproject.pcep.api.PcepOperator.OperationType;
62import org.onosproject.pcep.api.PcepSwitch;
63import org.onosproject.pcep.api.PcepSwitchListener;
64import 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
83 public PcepTopologyProvider() {
84 super(new ProviderId("pcep", "org.onosproject.provider.pcep"));
85 }
86
87 private static final Logger log = LoggerFactory
88 .getLogger(PcepTopologyProvider.class);
89
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 protected LinkProviderRegistry linkProviderRegistry;
92
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected DeviceProviderRegistry deviceProviderRegistry;
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected PcepController controller;
98
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 protected DeviceService deviceService;
101
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected LinkService linkService;
104
105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
106 protected MastershipAdminService mastershipAdminService;
107
108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
109 protected MastershipService mastershipService;
110
111 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
112 protected ClusterService clusterService;
113
114 private DeviceProviderService deviceProviderService;
115 private LinkProviderService linkProviderService;
chengfan359abf72015-07-02 23:33:16 +0800116
117 private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
cheng fan48e832c2015-05-29 01:54:47 +0800118 private InternalLinkProvider listener = new InternalLinkProvider();
119
120 @Activate
121 public void activate() {
122 linkProviderService = linkProviderRegistry.register(this);
123 deviceProviderService = deviceProviderRegistry.register(this);
124 controller.addListener(listener);
125 controller.addLinkListener(listener);
126 }
127
128 @Deactivate
129 public void deactivate() {
130 linkProviderRegistry.unregister(this);
131 linkProviderService = null;
132 controller.removeListener(listener);
133 controller.removeLinkListener(listener);
134 }
135
chengfan359abf72015-07-02 23:33:16 +0800136 private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
137 Port port,
cheng fan7716ec92015-05-31 01:53:19 +0800138 PortType portType) {
chengfan359abf72015-07-02 23:33:16 +0800139
140 List<PortDescription> portList;
141
142 if (portMap.containsKey(dpid.value())) {
143 portList = portMap.get(dpid.value());
144 } else {
145 portList = new ArrayList<>();
cheng fan48e832c2015-05-29 01:54:47 +0800146 }
chengfan359abf72015-07-02 23:33:16 +0800147 if (port != null && portType != null) {
148 portList.add(buildPortDescription(port, portType));
149 }
150
151 portMap.put(dpid.value(), portList);
152 return portList;
cheng fan48e832c2015-05-29 01:54:47 +0800153 }
154
chengfan359abf72015-07-02 23:33:16 +0800155 private PortDescription buildPortDescription(Port port, PortType portType) {
156 PortDescription portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800157
chengfan359abf72015-07-02 23:33:16 +0800158 switch (portType) {
159 case OCH_PORT:
160 OchPort ochp = (OchPort) port;
161 portDescription = new OchPortDescription(ochp.number(), ochp.isEnabled(),
162 ochp.signalType(), ochp.isTunable(),
163 ochp.lambda());
164 break;
165 case ODU_PORT:
166 OduCltPort odup = (OduCltPort) port;
167 portDescription = new OduCltPortDescription(odup.number(), odup.isEnabled(),
168 odup.signalType());
169 break;
170 case OMS_PORT:
171 OmsPort op = (OmsPort) port;
172 portDescription = new OmsPortDescription(op.number(), op.isEnabled(), op.minFrequency(),
173 op.maxFrequency(), op.grid());
174 break;
175 default:
176 portDescription = new DefaultPortDescription(port.number(), port.isEnabled());
177 break;
178 }
179 return portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800180 }
181
182 /**
chengfan3e618792015-06-28 21:42:01 +0800183 * Build a link description from a pcep link.
cheng fan48e832c2015-05-29 01:54:47 +0800184 *
chengfan3e618792015-06-28 21:42:01 +0800185 * @param pceLink pcep link
186 * @return LinkDescription onos link description
cheng fan48e832c2015-05-29 01:54:47 +0800187 */
188 private LinkDescription buildLinkDescription(PcepLink pceLink) {
189 LinkDescription ld;
chengfan359abf72015-07-02 23:33:16 +0800190 checkNotNull(pceLink);
cheng fan48e832c2015-05-29 01:54:47 +0800191 DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
192 DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));
193
cheng fan48e832c2015-05-29 01:54:47 +0800194 deviceProviderService
195 .updatePorts(srcDeviceID,
chengfan359abf72015-07-02 23:33:16 +0800196 buildPortDescriptions(pceLink.linkSrcDeviceID(),
197 pceLink.linkSrcPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800198
chengfan359abf72015-07-02 23:33:16 +0800199 deviceProviderService
200 .updatePorts(dstDeviceID,
201 buildPortDescriptions(pceLink.linkDstDeviceId(),
202 pceLink.linkDstPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800203
chengfan359abf72015-07-02 23:33:16 +0800204 ConnectPoint src = new ConnectPoint(srcDeviceID, pceLink.linkSrcPort().number());
cheng fan48e832c2015-05-29 01:54:47 +0800205
chengfan359abf72015-07-02 23:33:16 +0800206 ConnectPoint dst = new ConnectPoint(dstDeviceID, pceLink.linkDstPort().number());
207
208 DefaultAnnotations extendedAttributes = DefaultAnnotations
209 .builder()
210 .set("subType", String.valueOf(pceLink.linkSubType()))
211 .set("workState", pceLink.linkState())
212 .set("distance", String.valueOf(pceLink.linkDistance()))
213 .set("capType", pceLink.linkCapacityType().toLowerCase())
214 .set("avail_" + pceLink.linkCapacityType().toLowerCase(),
215 String.valueOf(pceLink.linkAvailValue()))
216 .set("max_" + pceLink.linkCapacityType().toLowerCase(),
217 String.valueOf(pceLink.linkMaxValue())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800218 // construct the link
chengfan359abf72015-07-02 23:33:16 +0800219 ld = new DefaultLinkDescription(src, dst, Type.OPTICAL, extendedAttributes);
cheng fan48e832c2015-05-29 01:54:47 +0800220 return ld;
221 }
222
cheng fan48e832c2015-05-29 01:54:47 +0800223 private class InternalLinkProvider
224 implements PcepSwitchListener, PcepLinkListener {
225
226 @Override
227 public void switchAdded(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800228 if (deviceProviderService == null) {
229 return;
230 }
chengfan359abf72015-07-02 23:33:16 +0800231 DeviceId deviceId = deviceId(uri(dpid));
cheng fan48e832c2015-05-29 01:54:47 +0800232 PcepSwitch sw = controller.getSwitch(dpid);
233 checkNotNull(sw, "device should not null.");
234 // The default device type is switch.
cheng fan48e832c2015-05-29 01:54:47 +0800235 ChassisId cId = new ChassisId(dpid.value());
chengfan359abf72015-07-02 23:33:16 +0800236 Device.Type deviceType;
cheng fan48e832c2015-05-29 01:54:47 +0800237
cheng fan7716ec92015-05-31 01:53:19 +0800238 switch (sw.getDeviceType()) {
chengfan359abf72015-07-02 23:33:16 +0800239 case ROADM:
240 deviceType = Device.Type.ROADM;
241 break;
242 case OTN:
243 deviceType = Device.Type.SWITCH;
244 break;
245 case ROUTER:
246 deviceType = Device.Type.ROUTER;
247 break;
248 default:
249 deviceType = Device.Type.OTHER;
cheng fan7716ec92015-05-31 01:53:19 +0800250 }
cheng fan48e832c2015-05-29 01:54:47 +0800251
252 DeviceDescription description = new DefaultDeviceDescription(
chengfan359abf72015-07-02 23:33:16 +0800253 deviceId.uri(),
254 deviceType,
255 sw.manufacturerDescription(),
256 sw.hardwareDescription(),
257 sw.softwareDescription(),
258 sw.serialNumber(),
259 cId);
260 deviceProviderService.deviceConnected(deviceId, description);
cheng fan48e832c2015-05-29 01:54:47 +0800261
262 }
263
264 @Override
265 public void switchRemoved(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800266 if (deviceProviderService == null || linkProviderService == null) {
267 return;
268 }
269 deviceProviderService.deviceDisconnected(deviceId(uri(dpid)));
270
271 linkProviderService.linksVanished(DeviceId.deviceId(uri(dpid)));
272 }
273
274 @Override
275 public void switchChanged(PcepDpid dpid) {
276 // TODO Auto-generated method stub
277
278 }
279
280 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700281 public void handlePceplink(PcepLink link) {
cheng fan48e832c2015-05-29 01:54:47 +0800282
283 OperationType operType = link.getOperationType();
284 LinkDescription ld = buildLinkDescription(link);
285 if (ld == null) {
286 log.error("Invalid link info.");
287 return;
288 }
289 switch (operType) {
chengfan359abf72015-07-02 23:33:16 +0800290 case ADD:
291 case UPDATE:
292 linkProviderService.linkDetected(ld);
293 break;
cheng fan48e832c2015-05-29 01:54:47 +0800294
chengfan359abf72015-07-02 23:33:16 +0800295 case DELETE:
296 linkProviderService.linkVanished(ld);
297 break;
cheng fan48e832c2015-05-29 01:54:47 +0800298
chengfan359abf72015-07-02 23:33:16 +0800299 default:
300 break;
cheng fan48e832c2015-05-29 01:54:47 +0800301
302 }
303 }
304
305 }
306
307 @Override
308 public void triggerProbe(DeviceId deviceId) {
309 // TODO Auto-generated method stub
cheng fan48e832c2015-05-29 01:54:47 +0800310 }
311
312 @Override
313 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
cheng fan48e832c2015-05-29 01:54:47 +0800314 }
315
316 @Override
317 public boolean isReachable(DeviceId deviceId) {
318 // TODO Auto-generated method stub
cheng fan7716ec92015-05-31 01:53:19 +0800319 return true;
cheng fan48e832c2015-05-29 01:54:47 +0800320 }
321}