blob: c5257ebfd25b1a2e3e76dbd61bb04aee76b97d28 [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
84 public PcepTopologyProvider() {
85 super(new ProviderId("pcep", "org.onosproject.provider.pcep"));
86 }
87
88 private static final Logger log = LoggerFactory
89 .getLogger(PcepTopologyProvider.class);
90
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected LinkProviderRegistry linkProviderRegistry;
93
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 protected DeviceProviderRegistry deviceProviderRegistry;
96
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected PcepController controller;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected DeviceService deviceService;
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected LinkService linkService;
105
106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 protected MastershipAdminService mastershipAdminService;
108
109 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
110 protected MastershipService mastershipService;
111
112 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
113 protected ClusterService clusterService;
114
115 private DeviceProviderService deviceProviderService;
116 private LinkProviderService linkProviderService;
chengfan359abf72015-07-02 23:33:16 +0800117
118 private HashMap<Long, List<PortDescription>> portMap = new HashMap<>();
cheng fan48e832c2015-05-29 01:54:47 +0800119 private InternalLinkProvider listener = new InternalLinkProvider();
120
121 @Activate
122 public void activate() {
123 linkProviderService = linkProviderRegistry.register(this);
124 deviceProviderService = deviceProviderRegistry.register(this);
125 controller.addListener(listener);
126 controller.addLinkListener(listener);
127 }
128
129 @Deactivate
130 public void deactivate() {
131 linkProviderRegistry.unregister(this);
132 linkProviderService = null;
133 controller.removeListener(listener);
134 controller.removeLinkListener(listener);
135 }
136
chengfan359abf72015-07-02 23:33:16 +0800137 private List<PortDescription> buildPortDescriptions(PcepDpid dpid,
138 Port port,
cheng fan7716ec92015-05-31 01:53:19 +0800139 PortType portType) {
chengfan359abf72015-07-02 23:33:16 +0800140
141 List<PortDescription> portList;
142
143 if (portMap.containsKey(dpid.value())) {
144 portList = portMap.get(dpid.value());
145 } else {
146 portList = new ArrayList<>();
cheng fan48e832c2015-05-29 01:54:47 +0800147 }
chengfan359abf72015-07-02 23:33:16 +0800148 if (port != null && portType != null) {
149 portList.add(buildPortDescription(port, portType));
150 }
151
152 portMap.put(dpid.value(), portList);
153 return portList;
cheng fan48e832c2015-05-29 01:54:47 +0800154 }
155
chengfan359abf72015-07-02 23:33:16 +0800156 private PortDescription buildPortDescription(Port port, PortType portType) {
157 PortDescription portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800158
chengfan359abf72015-07-02 23:33:16 +0800159 switch (portType) {
160 case OCH_PORT:
161 OchPort ochp = (OchPort) port;
162 portDescription = new OchPortDescription(ochp.number(), ochp.isEnabled(),
163 ochp.signalType(), ochp.isTunable(),
164 ochp.lambda());
165 break;
166 case ODU_PORT:
167 OduCltPort odup = (OduCltPort) port;
168 portDescription = new OduCltPortDescription(odup.number(), odup.isEnabled(),
169 odup.signalType());
170 break;
171 case OMS_PORT:
172 OmsPort op = (OmsPort) port;
173 portDescription = new OmsPortDescription(op.number(), op.isEnabled(), op.minFrequency(),
174 op.maxFrequency(), op.grid());
175 break;
176 default:
177 portDescription = new DefaultPortDescription(port.number(), port.isEnabled());
178 break;
179 }
180 return portDescription;
cheng fan48e832c2015-05-29 01:54:47 +0800181 }
182
183 /**
chengfan3e618792015-06-28 21:42:01 +0800184 * Build a link description from a pcep link.
cheng fan48e832c2015-05-29 01:54:47 +0800185 *
chengfan3e618792015-06-28 21:42:01 +0800186 * @param pceLink pcep link
187 * @return LinkDescription onos link description
cheng fan48e832c2015-05-29 01:54:47 +0800188 */
189 private LinkDescription buildLinkDescription(PcepLink pceLink) {
190 LinkDescription ld;
chengfan359abf72015-07-02 23:33:16 +0800191 checkNotNull(pceLink);
cheng fan48e832c2015-05-29 01:54:47 +0800192 DeviceId srcDeviceID = deviceId(uri(pceLink.linkSrcDeviceID()));
193 DeviceId dstDeviceID = deviceId(uri(pceLink.linkDstDeviceId()));
194
cheng fan48e832c2015-05-29 01:54:47 +0800195 deviceProviderService
196 .updatePorts(srcDeviceID,
chengfan359abf72015-07-02 23:33:16 +0800197 buildPortDescriptions(pceLink.linkSrcDeviceID(),
198 pceLink.linkSrcPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800199
chengfan359abf72015-07-02 23:33:16 +0800200 deviceProviderService
201 .updatePorts(dstDeviceID,
202 buildPortDescriptions(pceLink.linkDstDeviceId(),
203 pceLink.linkDstPort(), pceLink.portType()));
cheng fan48e832c2015-05-29 01:54:47 +0800204
chengfan359abf72015-07-02 23:33:16 +0800205 ConnectPoint src = new ConnectPoint(srcDeviceID, pceLink.linkSrcPort().number());
cheng fan48e832c2015-05-29 01:54:47 +0800206
chengfan359abf72015-07-02 23:33:16 +0800207 ConnectPoint dst = new ConnectPoint(dstDeviceID, pceLink.linkDstPort().number());
208
209 DefaultAnnotations extendedAttributes = DefaultAnnotations
210 .builder()
211 .set("subType", String.valueOf(pceLink.linkSubType()))
212 .set("workState", pceLink.linkState())
213 .set("distance", String.valueOf(pceLink.linkDistance()))
214 .set("capType", pceLink.linkCapacityType().toLowerCase())
215 .set("avail_" + pceLink.linkCapacityType().toLowerCase(),
216 String.valueOf(pceLink.linkAvailValue()))
217 .set("max_" + pceLink.linkCapacityType().toLowerCase(),
218 String.valueOf(pceLink.linkMaxValue())).build();
cheng fan48e832c2015-05-29 01:54:47 +0800219 // construct the link
chengfan359abf72015-07-02 23:33:16 +0800220 ld = new DefaultLinkDescription(src, dst, Type.OPTICAL, extendedAttributes);
cheng fan48e832c2015-05-29 01:54:47 +0800221 return ld;
222 }
223
cheng fan48e832c2015-05-29 01:54:47 +0800224 private class InternalLinkProvider
225 implements PcepSwitchListener, PcepLinkListener {
226
227 @Override
228 public void switchAdded(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800229 if (deviceProviderService == null) {
230 return;
231 }
chengfan359abf72015-07-02 23:33:16 +0800232 DeviceId deviceId = deviceId(uri(dpid));
cheng fan48e832c2015-05-29 01:54:47 +0800233 PcepSwitch sw = controller.getSwitch(dpid);
234 checkNotNull(sw, "device should not null.");
235 // The default device type is switch.
cheng fan48e832c2015-05-29 01:54:47 +0800236 ChassisId cId = new ChassisId(dpid.value());
chengfan359abf72015-07-02 23:33:16 +0800237 Device.Type deviceType;
cheng fan48e832c2015-05-29 01:54:47 +0800238
cheng fan7716ec92015-05-31 01:53:19 +0800239 switch (sw.getDeviceType()) {
chengfan359abf72015-07-02 23:33:16 +0800240 case ROADM:
241 deviceType = Device.Type.ROADM;
242 break;
243 case OTN:
244 deviceType = Device.Type.SWITCH;
245 break;
246 case ROUTER:
247 deviceType = Device.Type.ROUTER;
248 break;
249 default:
250 deviceType = Device.Type.OTHER;
cheng fan7716ec92015-05-31 01:53:19 +0800251 }
cheng fan48e832c2015-05-29 01:54:47 +0800252
253 DeviceDescription description = new DefaultDeviceDescription(
chengfan359abf72015-07-02 23:33:16 +0800254 deviceId.uri(),
255 deviceType,
256 sw.manufacturerDescription(),
257 sw.hardwareDescription(),
258 sw.softwareDescription(),
259 sw.serialNumber(),
260 cId);
261 deviceProviderService.deviceConnected(deviceId, description);
cheng fan48e832c2015-05-29 01:54:47 +0800262
263 }
264
265 @Override
266 public void switchRemoved(PcepDpid dpid) {
cheng fan48e832c2015-05-29 01:54:47 +0800267 if (deviceProviderService == null || linkProviderService == null) {
268 return;
269 }
270 deviceProviderService.deviceDisconnected(deviceId(uri(dpid)));
271
272 linkProviderService.linksVanished(DeviceId.deviceId(uri(dpid)));
273 }
274
275 @Override
276 public void switchChanged(PcepDpid dpid) {
277 // TODO Auto-generated method stub
278
279 }
280
281 @Override
Jonathan Hart51539b82015-10-29 09:53:04 -0700282 public void handlePceplink(PcepLink link) {
cheng fan48e832c2015-05-29 01:54:47 +0800283
284 OperationType operType = link.getOperationType();
285 LinkDescription ld = buildLinkDescription(link);
286 if (ld == null) {
287 log.error("Invalid link info.");
288 return;
289 }
290 switch (operType) {
chengfan359abf72015-07-02 23:33:16 +0800291 case ADD:
292 case UPDATE:
293 linkProviderService.linkDetected(ld);
294 break;
cheng fan48e832c2015-05-29 01:54:47 +0800295
chengfan359abf72015-07-02 23:33:16 +0800296 case DELETE:
297 linkProviderService.linkVanished(ld);
298 break;
cheng fan48e832c2015-05-29 01:54:47 +0800299
chengfan359abf72015-07-02 23:33:16 +0800300 default:
301 break;
cheng fan48e832c2015-05-29 01:54:47 +0800302
303 }
304 }
305
306 }
307
308 @Override
309 public void triggerProbe(DeviceId deviceId) {
310 // TODO Auto-generated method stub
cheng fan48e832c2015-05-29 01:54:47 +0800311 }
312
313 @Override
314 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
cheng fan48e832c2015-05-29 01:54:47 +0800315 }
316
317 @Override
318 public boolean isReachable(DeviceId deviceId) {
319 // TODO Auto-generated method stub
cheng fan7716ec92015-05-31 01:53:19 +0800320 return true;
cheng fan48e832c2015-05-29 01:54:47 +0800321 }
Saurav Dasa2d37502016-03-25 17:50:40 -0700322
323 @Override
324 public void changePortState(DeviceId deviceId, PortNumber portNumber,
325 boolean enable) {
326 // TODO Auto-generated method stub
327 }
cheng fan48e832c2015-05-29 01:54:47 +0800328}