Thomas Vachuska | 781d18b | 2014-10-27 10:31:25 -0700 | [diff] [blame] | 1 | /* |
Thomas Vachuska | 4f1a60c | 2014-10-28 13:39:07 -0700 | [diff] [blame] | 2 | * Copyright 2014 Open Networking Laboratory |
Thomas Vachuska | 781d18b | 2014-10-27 10:31:25 -0700 | [diff] [blame] | 3 | * |
Thomas Vachuska | 4f1a60c | 2014-10-28 13:39:07 -0700 | [diff] [blame] | 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 |
Thomas Vachuska | 781d18b | 2014-10-27 10:31:25 -0700 | [diff] [blame] | 7 | * |
Thomas Vachuska | 4f1a60c | 2014-10-28 13:39:07 -0700 | [diff] [blame] | 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. |
Thomas Vachuska | 781d18b | 2014-10-27 10:31:25 -0700 | [diff] [blame] | 15 | */ |
Brian O'Connor | abafb50 | 2014-12-02 22:26:20 -0800 | [diff] [blame] | 16 | package org.onosproject.optical.cfg; |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 17 | |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 18 | import org.codehaus.jackson.JsonNode; |
| 19 | import org.codehaus.jackson.JsonParseException; |
| 20 | import org.codehaus.jackson.annotate.JsonIgnoreProperties; |
| 21 | import org.codehaus.jackson.map.JsonMappingException; |
| 22 | import org.codehaus.jackson.map.ObjectMapper; |
Brian O'Connor | abafb50 | 2014-12-02 22:26:20 -0800 | [diff] [blame] | 23 | import org.onosproject.net.ConnectPoint; |
| 24 | import org.onosproject.net.DefaultAnnotations; |
| 25 | import org.onosproject.net.Device; |
| 26 | import org.onosproject.net.DeviceId; |
| 27 | import org.onosproject.net.Link; |
| 28 | import org.onosproject.net.MastershipRole; |
| 29 | import org.onosproject.net.PortNumber; |
| 30 | import org.onosproject.net.device.DefaultDeviceDescription; |
| 31 | import org.onosproject.net.device.DeviceDescription; |
| 32 | import org.onosproject.net.device.DeviceProvider; |
| 33 | import org.onosproject.net.device.DeviceProviderRegistry; |
| 34 | import org.onosproject.net.device.DeviceProviderService; |
| 35 | import org.onosproject.net.link.DefaultLinkDescription; |
| 36 | import org.onosproject.net.link.LinkProvider; |
| 37 | import org.onosproject.net.link.LinkProviderRegistry; |
| 38 | import org.onosproject.net.link.LinkProviderService; |
| 39 | import org.onosproject.net.provider.AbstractProvider; |
| 40 | import org.onosproject.net.provider.ProviderId; |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 41 | import org.onlab.packet.ChassisId; |
| 42 | import org.slf4j.Logger; |
| 43 | import org.slf4j.LoggerFactory; |
| 44 | |
Thomas Vachuska | badb93f | 2014-11-15 23:51:17 -0800 | [diff] [blame] | 45 | import java.io.File; |
| 46 | import java.io.IOException; |
| 47 | import java.util.ArrayList; |
| 48 | import java.util.Iterator; |
| 49 | import java.util.List; |
| 50 | import java.util.Map; |
| 51 | import java.util.Set; |
| 52 | |
Brian O'Connor | abafb50 | 2014-12-02 22:26:20 -0800 | [diff] [blame] | 53 | import static org.onosproject.net.DeviceId.deviceId; |
Thomas Vachuska | badb93f | 2014-11-15 23:51:17 -0800 | [diff] [blame] | 54 | |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 55 | /** |
| 56 | * OpticalConfigProvider emulates the SB network provider for optical switches, |
| 57 | * optical links and any other state that needs to be configured for correct network |
| 58 | * operations. |
| 59 | * |
| 60 | */ |
Thomas Vachuska | 112c703 | 2014-11-16 11:05:14 -0800 | [diff] [blame] | 61 | @Deprecated |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 62 | @JsonIgnoreProperties(ignoreUnknown = true) |
Praseed Balakrishnan | 0bb2d7d | 2014-11-06 12:29:09 -0800 | [diff] [blame] | 63 | //@Component(immediate = true) |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 64 | public class OpticalConfigProvider extends AbstractProvider implements DeviceProvider, LinkProvider { |
| 65 | |
| 66 | protected static final Logger log = LoggerFactory |
| 67 | .getLogger(OpticalConfigProvider.class); |
| 68 | |
| 69 | // TODO: fix hard coded file path later. |
| 70 | private static final String DEFAULT_CONFIG_FILE = |
Marc De Leenheer | 631ffce | 2014-10-28 16:29:07 -0700 | [diff] [blame] | 71 | "config/demo-3-roadm-2-ps.json"; |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 72 | private String configFileName = DEFAULT_CONFIG_FILE; |
| 73 | |
Thomas Vachuska | badb93f | 2014-11-15 23:51:17 -0800 | [diff] [blame] | 74 | // @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 75 | protected LinkProviderRegistry linkProviderRegistry; |
| 76 | |
Thomas Vachuska | badb93f | 2014-11-15 23:51:17 -0800 | [diff] [blame] | 77 | // @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 78 | protected DeviceProviderRegistry deviceProviderRegistry; |
| 79 | |
| 80 | private static final String OPTICAL_ANNOTATION = "optical."; |
| 81 | |
| 82 | private LinkProviderService linkProviderService; |
| 83 | private DeviceProviderService deviceProviderService; |
| 84 | |
| 85 | private static final List<Roadm> RAW_ROADMS = new ArrayList<>(); |
| 86 | private static final List<WdmLink> RAW_WDMLINKS = new ArrayList<>(); |
| 87 | private static final List<PktOptLink> RAW_PKTOPTLINKS = new ArrayList<>(); |
| 88 | |
| 89 | private static final String ROADM = "Roadm"; |
| 90 | private static final String WDM_LINK = "wdmLink"; |
| 91 | private static final String PKT_OPT_LINK = "pktOptLink"; |
| 92 | |
| 93 | protected OpticalNetworkConfig opticalNetworkConfig; |
| 94 | |
| 95 | public OpticalConfigProvider() { |
Brian O'Connor | abafb50 | 2014-12-02 22:26:20 -0800 | [diff] [blame] | 96 | super(new ProviderId("optical", "org.onosproject.provider" + |
Praseed Balakrishnan | 69d95be | 2014-10-22 13:55:05 -0700 | [diff] [blame] | 97 | ".opticalConfig")); |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 98 | } |
| 99 | |
Thomas Vachuska | badb93f | 2014-11-15 23:51:17 -0800 | [diff] [blame] | 100 | // @Activate |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 101 | protected void activate() { |
| 102 | linkProviderService = linkProviderRegistry.register(this); |
| 103 | deviceProviderService = deviceProviderRegistry.register(this); |
| 104 | log.info("Starting optical network configuration process..."); |
| 105 | log.info("Optical config file set to {}", configFileName); |
| 106 | |
| 107 | loadOpticalConfig(); |
| 108 | parseOpticalConfig(); |
| 109 | publishOpticalConfig(); |
| 110 | } |
| 111 | |
Thomas Vachuska | badb93f | 2014-11-15 23:51:17 -0800 | [diff] [blame] | 112 | // @Deactivate |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 113 | protected void deactivate() { |
| 114 | linkProviderRegistry.unregister(this); |
| 115 | linkProviderService = null; |
| 116 | deviceProviderRegistry.unregister(this); |
| 117 | deviceProviderService = null; |
| 118 | RAW_ROADMS.clear(); |
| 119 | RAW_WDMLINKS.clear(); |
| 120 | RAW_PKTOPTLINKS.clear(); |
| 121 | log.info("Stopped"); |
| 122 | } |
| 123 | |
| 124 | private void loadOpticalConfig() { |
| 125 | ObjectMapper mapper = new ObjectMapper(); |
| 126 | opticalNetworkConfig = new OpticalNetworkConfig(); |
| 127 | try { |
| 128 | opticalNetworkConfig = mapper.readValue(new File(configFileName), OpticalNetworkConfig.class); |
| 129 | } catch (JsonParseException e) { |
| 130 | String err = String.format("JsonParseException while loading network " |
| 131 | + "config from file: %s: %s", configFileName, e.getMessage()); |
| 132 | log.error(err, e); |
| 133 | } catch (JsonMappingException e) { |
| 134 | String err = String.format( |
| 135 | "JsonMappingException while loading network config " |
| 136 | + "from file: %s: %s", configFileName, e.getMessage()); |
| 137 | log.error(err, e); |
| 138 | } catch (IOException e) { |
| 139 | String err = String.format("IOException while loading network config " |
| 140 | + "from file: %s %s", configFileName, e.getMessage()); |
| 141 | log.error(err, e); |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | private void parseOpticalConfig() { |
| 146 | List<OpticalSwitchDescription> swList = opticalNetworkConfig.getOpticalSwitches(); |
| 147 | List<OpticalLinkDescription> lkList = opticalNetworkConfig.getOpticalLinks(); |
| 148 | |
| 149 | for (OpticalSwitchDescription sw : swList) { |
| 150 | String swtype = sw.getType(); |
| 151 | boolean allow = sw.isAllowed(); |
| 152 | if (swtype.equals(ROADM) && allow) { |
| 153 | int regNum = 0; |
| 154 | Set<Map.Entry<String, JsonNode>> m = sw.params.entrySet(); |
| 155 | for (Map.Entry<String, JsonNode> e : m) { |
| 156 | String key = e.getKey(); |
| 157 | JsonNode j = e.getValue(); |
| 158 | if (key.equals("numRegen")) { |
| 159 | regNum = j.asInt(); |
| 160 | } |
| 161 | } |
| 162 | |
| 163 | Roadm newRoadm = new Roadm(); |
| 164 | newRoadm.setName(sw.name); |
| 165 | newRoadm.setNodeId(sw.nodeDpid); |
| 166 | newRoadm.setLongtitude(sw.longitude); |
| 167 | newRoadm.setLatitude(sw.latitude); |
| 168 | newRoadm.setRegenNum(regNum); |
| 169 | |
| 170 | RAW_ROADMS.add(newRoadm); |
| 171 | log.info(newRoadm.toString()); |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | for (OpticalLinkDescription lk : lkList) { |
| 176 | String lktype = lk.getType(); |
| 177 | switch (lktype) { |
| 178 | case WDM_LINK: |
| 179 | WdmLink newWdmLink = new WdmLink(); |
| 180 | newWdmLink.setSrcNodeId(lk.getNodeDpid1()); |
| 181 | newWdmLink.setSnkNodeId(lk.getNodeDpid2()); |
| 182 | newWdmLink.setAdminWeight(1000); // default weight for each WDM link. |
| 183 | Set<Map.Entry<String, JsonNode>> m = lk.params.entrySet(); |
| 184 | for (Map.Entry<String, JsonNode> e : m) { |
| 185 | String key = e.getKey(); |
| 186 | JsonNode j = e.getValue(); |
| 187 | if (key.equals("nodeName1")) { |
| 188 | newWdmLink.setSrcNodeName(j.asText()); |
| 189 | } else if (key.equals("nodeName2")) { |
| 190 | newWdmLink.setSnkNodeName(j.asText()); |
| 191 | } else if (key.equals("port1")) { |
| 192 | newWdmLink.setSrcPort(j.asInt()); |
| 193 | } else if (key.equals("port2")) { |
| 194 | newWdmLink.setSnkPort(j.asInt()); |
| 195 | } else if (key.equals("distKms")) { |
| 196 | newWdmLink.setDistance(j.asDouble()); |
| 197 | } else if (key.equals("numWaves")) { |
| 198 | newWdmLink.setWavelengthNumber(j.asInt()); |
| 199 | } else { |
| 200 | log.error("error found"); |
| 201 | // TODO add exception processing; |
| 202 | } |
| 203 | } |
| 204 | RAW_WDMLINKS.add(newWdmLink); |
| 205 | log.info(newWdmLink.toString()); |
| 206 | |
| 207 | break; |
| 208 | |
| 209 | case PKT_OPT_LINK: |
| 210 | PktOptLink newPktOptLink = new PktOptLink(); |
| 211 | newPktOptLink.setSrcNodeId(lk.getNodeDpid1()); |
| 212 | newPktOptLink.setSnkNodeId(lk.getNodeDpid2()); |
| 213 | newPktOptLink.setAdminWeight(10); // default weight for each packet-optical link. |
| 214 | Set<Map.Entry<String, JsonNode>> ptm = lk.params.entrySet(); |
| 215 | for (Map.Entry<String, JsonNode> e : ptm) { |
| 216 | String key = e.getKey(); |
| 217 | JsonNode j = e.getValue(); |
| 218 | if (key.equals("nodeName1")) { |
| 219 | newPktOptLink.setSrcNodeName(j.asText()); |
| 220 | } else if (key.equals("nodeName2")) { |
| 221 | newPktOptLink.setSnkNodeName(j.asText()); |
| 222 | } else if (key.equals("port1")) { |
| 223 | newPktOptLink.setSrcPort(j.asInt()); |
| 224 | } else if (key.equals("port2")) { |
| 225 | newPktOptLink.setSnkPort(j.asInt()); |
| 226 | } else if (key.equals("bandWidth")) { |
| 227 | newPktOptLink.setBandwdith(j.asDouble()); |
| 228 | } else { |
| 229 | log.error("error found"); |
| 230 | // TODO add exception processing; |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | RAW_PKTOPTLINKS.add(newPktOptLink); |
| 235 | log.info(newPktOptLink.toString()); |
| 236 | break; |
| 237 | default: |
| 238 | } |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | private void publishOpticalConfig() { |
| 243 | if (deviceProviderService == null || linkProviderService == null) { |
| 244 | return; |
| 245 | } |
| 246 | |
| 247 | // Discover the optical ROADM objects |
| 248 | Iterator<Roadm> iterWdmNode = RAW_ROADMS.iterator(); |
| 249 | while (iterWdmNode.hasNext()) { |
| 250 | Roadm value = iterWdmNode.next(); |
| 251 | DeviceId did = deviceId("of:" + value.getNodeId().replace(":", "")); |
Praseed Balakrishnan | 69d95be | 2014-10-22 13:55:05 -0700 | [diff] [blame] | 252 | ChassisId cid = new ChassisId(); |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 253 | DefaultAnnotations extendedAttributes = DefaultAnnotations.builder() |
| 254 | .set(OPTICAL_ANNOTATION + "switchType", "ROADM") |
| 255 | .set(OPTICAL_ANNOTATION + "switchName", value.getName()) |
| 256 | .set(OPTICAL_ANNOTATION + "latitude", Double.toString(value.getLatitude())) |
| 257 | .set(OPTICAL_ANNOTATION + "longtitude", Double.toString(value.getLongtitude())) |
| 258 | .set(OPTICAL_ANNOTATION + "regNum", Integer.toString(value.getRegenNum())) |
| 259 | .build(); |
| 260 | |
| 261 | DeviceDescription description = |
| 262 | new DefaultDeviceDescription(did.uri(), |
| 263 | Device.Type.SWITCH, |
| 264 | "", |
| 265 | "", |
| 266 | "", |
| 267 | "", |
| 268 | cid, |
| 269 | extendedAttributes); |
| 270 | deviceProviderService.deviceConnected(did, description); |
| 271 | } |
| 272 | |
| 273 | // Discover the optical WDM link objects |
| 274 | Iterator<WdmLink> iterWdmlink = RAW_WDMLINKS.iterator(); |
| 275 | while (iterWdmlink.hasNext()) { |
| 276 | WdmLink value = iterWdmlink.next(); |
| 277 | |
| 278 | DeviceId srcNodeId = deviceId("of:" + value.getSrcNodeId().replace(":", "")); |
| 279 | DeviceId snkNodeId = deviceId("of:" + value.getSnkNodeId().replace(":", "")); |
| 280 | |
| 281 | PortNumber srcPort = PortNumber.portNumber(value.getSrcPort()); |
| 282 | PortNumber snkPort = PortNumber.portNumber(value.getSnkPort()); |
| 283 | |
| 284 | ConnectPoint srcPoint = new ConnectPoint(srcNodeId, srcPort); |
| 285 | ConnectPoint snkPoint = new ConnectPoint(snkNodeId, snkPort); |
| 286 | |
| 287 | DefaultAnnotations extendedAttributes = DefaultAnnotations.builder() |
| 288 | .set(OPTICAL_ANNOTATION + "linkType", "WDM") |
| 289 | .set(OPTICAL_ANNOTATION + "distance", Double.toString(value.getDistance())) |
| 290 | .set(OPTICAL_ANNOTATION + "cost", Double.toString(value.getDistance())) |
| 291 | .set(OPTICAL_ANNOTATION + "adminWeight", Double.toString(value.getAdminWeight())) |
| 292 | .set(OPTICAL_ANNOTATION + "wavelengthNum", Integer.toString(value.getWavelengthNumber())) |
| 293 | .build(); |
| 294 | |
| 295 | DefaultLinkDescription linkDescription = |
| 296 | new DefaultLinkDescription(srcPoint, |
| 297 | snkPoint, |
Thomas Vachuska | 0e752bd | 2014-10-22 22:33:41 -0700 | [diff] [blame] | 298 | Link.Type.OPTICAL, |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 299 | extendedAttributes); |
| 300 | |
| 301 | linkProviderService.linkDetected(linkDescription); |
| 302 | log.info(String.format("WDM link: %s : %s", |
| 303 | linkDescription.src().toString(), linkDescription.dst().toString())); |
weibit | aca1460 | 2014-10-24 10:26:26 -0700 | [diff] [blame] | 304 | |
| 305 | |
| 306 | DefaultLinkDescription linkDescriptionReverse = |
| 307 | new DefaultLinkDescription(snkPoint, |
| 308 | srcPoint, |
| 309 | Link.Type.OPTICAL, |
| 310 | extendedAttributes); |
| 311 | |
| 312 | linkProviderService.linkDetected(linkDescriptionReverse); |
| 313 | log.info(String.format("WDM link: %s : %s", |
| 314 | linkDescriptionReverse.src().toString(), linkDescriptionReverse.dst().toString())); |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 315 | } |
| 316 | |
| 317 | // Discover the packet optical link objects |
| 318 | Iterator<PktOptLink> iterPktOptlink = RAW_PKTOPTLINKS.iterator(); |
| 319 | while (iterPktOptlink.hasNext()) { |
| 320 | PktOptLink value = iterPktOptlink.next(); |
| 321 | DeviceId srcNodeId = deviceId("of:" + value.getSrcNodeId().replace(":", "")); |
| 322 | DeviceId snkNodeId = deviceId("of:" + value.getSnkNodeId().replace(":", "")); |
| 323 | |
| 324 | PortNumber srcPort = PortNumber.portNumber(value.getSrcPort()); |
| 325 | PortNumber snkPort = PortNumber.portNumber(value.getSnkPort()); |
| 326 | |
| 327 | ConnectPoint srcPoint = new ConnectPoint(srcNodeId, srcPort); |
| 328 | ConnectPoint snkPoint = new ConnectPoint(snkNodeId, snkPort); |
| 329 | |
| 330 | DefaultAnnotations extendedAttributes = DefaultAnnotations.builder() |
| 331 | .set(OPTICAL_ANNOTATION + "linkType", "PktOptLink") |
| 332 | .set(OPTICAL_ANNOTATION + "bandwidth", Double.toString(value.getBandwidth())) |
| 333 | .set(OPTICAL_ANNOTATION + "cost", Double.toString(value.getBandwidth())) |
| 334 | .set(OPTICAL_ANNOTATION + "adminWeight", Double.toString(value.getAdminWeight())) |
| 335 | .build(); |
| 336 | |
| 337 | DefaultLinkDescription linkDescription = |
| 338 | new DefaultLinkDescription(srcPoint, |
| 339 | snkPoint, |
Thomas Vachuska | 0e752bd | 2014-10-22 22:33:41 -0700 | [diff] [blame] | 340 | Link.Type.OPTICAL, |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 341 | extendedAttributes); |
| 342 | |
| 343 | linkProviderService.linkDetected(linkDescription); |
| 344 | log.info(String.format("Packet-optical link: %s : %s", |
| 345 | linkDescription.src().toString(), linkDescription.dst().toString())); |
weibit | aca1460 | 2014-10-24 10:26:26 -0700 | [diff] [blame] | 346 | |
| 347 | DefaultLinkDescription linkDescriptionReverse = |
| 348 | new DefaultLinkDescription(snkPoint, |
| 349 | srcPoint, |
| 350 | Link.Type.OPTICAL, |
| 351 | extendedAttributes); |
| 352 | |
| 353 | linkProviderService.linkDetected(linkDescriptionReverse); |
| 354 | log.info(String.format("Packet-optical link: %s : %s", |
| 355 | linkDescriptionReverse.src().toString(), linkDescriptionReverse.dst().toString())); |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 356 | } |
| 357 | |
| 358 | } |
| 359 | |
| 360 | @Override |
Ayaka Koshibe | 78bcbc1 | 2014-11-19 14:28:58 -0800 | [diff] [blame] | 361 | public void triggerProbe(DeviceId deviceId) { |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 362 | // TODO We may want to consider re-reading config files and publishing them based on this event. |
| 363 | } |
| 364 | |
| 365 | @Override |
Yuta HIGUCHI | 5481532 | 2014-10-31 23:17:08 -0700 | [diff] [blame] | 366 | public void roleChanged(DeviceId device, MastershipRole newRole) { |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 367 | } |
| 368 | |
Ayaka Koshibe | e60d452 | 2014-10-28 15:07:00 -0700 | [diff] [blame] | 369 | @Override |
Yuta HIGUCHI | 5481532 | 2014-10-31 23:17:08 -0700 | [diff] [blame] | 370 | public boolean isReachable(DeviceId device) { |
Ayaka Koshibe | e60d452 | 2014-10-28 15:07:00 -0700 | [diff] [blame] | 371 | return false; |
| 372 | } |
weibit | 38c42ed | 2014-10-09 19:03:54 -0700 | [diff] [blame] | 373 | } |