Committed by
Gerrit Code Review
Implement PowerConfig for Oplink Devices
Change-Id: I939126580f8d3cdcdbcd9a46f6ee5cacbd25051d
Showing
7 changed files
with
224 additions
and
3 deletions
| ... | @@ -15,6 +15,8 @@ | ... | @@ -15,6 +15,8 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net; | 16 | package org.onosproject.net; |
| 17 | 17 | ||
| 18 | +import com.google.common.annotations.Beta; | ||
| 19 | + | ||
| 18 | /** | 20 | /** |
| 19 | * Collection of keys for annotation. | 21 | * Collection of keys for annotation. |
| 20 | * <p> | 22 | * <p> |
| ... | @@ -110,6 +112,18 @@ public final class AnnotationKeys { | ... | @@ -110,6 +112,18 @@ public final class AnnotationKeys { |
| 110 | public static final String STATIC_LAMBDA = "staticLambda"; | 112 | public static final String STATIC_LAMBDA = "staticLambda"; |
| 111 | 113 | ||
| 112 | /** | 114 | /** |
| 115 | + * Annotation key for optical port's target power. | ||
| 116 | + */ | ||
| 117 | + @Beta | ||
| 118 | + public static final String TARGET_POWER = "targetPower"; | ||
| 119 | + | ||
| 120 | + /** | ||
| 121 | + * Annotation key for optical port's current power. | ||
| 122 | + */ | ||
| 123 | + @Beta | ||
| 124 | + public static final String CURRENT_POWER = "currentPower"; | ||
| 125 | + | ||
| 126 | + /** | ||
| 113 | * Annotation key for the static port. | 127 | * Annotation key for the static port. |
| 114 | */ | 128 | */ |
| 115 | public static final String STATIC_PORT = "staticPort"; | 129 | public static final String STATIC_PORT = "staticPort"; | ... | ... |
| 1 | /* | 1 | /* |
| 2 | - * Copyright 2016-present Open Networking Laboratory | 2 | + * Copyright 2016 Open Networking Laboratory |
| 3 | * | 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. | 5 | * you may not use this file except in compliance with the License. |
| ... | @@ -25,7 +25,14 @@ import java.util.List; | ... | @@ -25,7 +25,14 @@ import java.util.List; |
| 25 | import java.util.Set; | 25 | import java.util.Set; |
| 26 | import java.util.concurrent.atomic.AtomicBoolean; | 26 | import java.util.concurrent.atomic.AtomicBoolean; |
| 27 | 27 | ||
| 28 | +import org.onosproject.net.AnnotationKeys; | ||
| 29 | +import org.onosproject.net.DefaultAnnotations; | ||
| 28 | import org.onosproject.net.Device; | 30 | import org.onosproject.net.Device; |
| 31 | +import org.onosproject.net.Port; | ||
| 32 | +import org.onosproject.net.PortNumber; | ||
| 33 | +import org.onosproject.net.device.DefaultPortDescription; | ||
| 34 | +import org.onosproject.net.device.DeviceService; | ||
| 35 | +import org.onosproject.net.device.PortDescription; | ||
| 29 | import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; | 36 | import org.onosproject.openflow.controller.OpenFlowOpticalSwitch; |
| 30 | import org.onosproject.openflow.controller.PortDescPropertyType; | 37 | import org.onosproject.openflow.controller.PortDescPropertyType; |
| 31 | import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; | 38 | import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; |
| ... | @@ -37,10 +44,16 @@ import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply; | ... | @@ -37,10 +44,16 @@ import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply; |
| 37 | import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest; | 44 | import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest; |
| 38 | import org.projectfloodlight.openflow.protocol.OFMessage; | 45 | import org.projectfloodlight.openflow.protocol.OFMessage; |
| 39 | import org.projectfloodlight.openflow.protocol.OFObject; | 46 | import org.projectfloodlight.openflow.protocol.OFObject; |
| 47 | +import org.projectfloodlight.openflow.protocol.OFOplinkPortPower; | ||
| 40 | import org.projectfloodlight.openflow.protocol.OFPortDesc; | 48 | import org.projectfloodlight.openflow.protocol.OFPortDesc; |
| 41 | import org.projectfloodlight.openflow.protocol.OFPortOptical; | 49 | import org.projectfloodlight.openflow.protocol.OFPortOptical; |
| 42 | import org.projectfloodlight.openflow.protocol.OFStatsReply; | 50 | import org.projectfloodlight.openflow.protocol.OFStatsReply; |
| 51 | +import org.projectfloodlight.openflow.protocol.OFStatsRequest; | ||
| 43 | import org.projectfloodlight.openflow.protocol.OFStatsType; | 52 | import org.projectfloodlight.openflow.protocol.OFStatsType; |
| 53 | +import org.projectfloodlight.openflow.protocol.OFType; | ||
| 54 | +import org.projectfloodlight.openflow.protocol.OFOplinkPortPowerRequest; | ||
| 55 | +import org.projectfloodlight.openflow.protocol.OFOplinkPortPowerReply; | ||
| 56 | + | ||
| 44 | 57 | ||
| 45 | /** | 58 | /** |
| 46 | * Driver for Oplink single WSS 8D ROADM. | 59 | * Driver for Oplink single WSS 8D ROADM. |
| ... | @@ -49,6 +62,7 @@ import org.projectfloodlight.openflow.protocol.OFStatsType; | ... | @@ -49,6 +62,7 @@ import org.projectfloodlight.openflow.protocol.OFStatsType; |
| 49 | * The device consists of Och ports, and performances wavelength cross-connect among the ports. | 62 | * The device consists of Och ports, and performances wavelength cross-connect among the ports. |
| 50 | */ | 63 | */ |
| 51 | public class OplinkRoadmHandshaker extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch { | 64 | public class OplinkRoadmHandshaker extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch { |
| 65 | + | ||
| 52 | private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false); | 66 | private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false); |
| 53 | private List<OFPortOptical> opticalPorts; | 67 | private List<OFPortOptical> opticalPorts; |
| 54 | 68 | ||
| ... | @@ -159,7 +173,26 @@ public class OplinkRoadmHandshaker extends AbstractOpenFlowSwitch implements Ope | ... | @@ -159,7 +173,26 @@ public class OplinkRoadmHandshaker extends AbstractOpenFlowSwitch implements Ope |
| 159 | @Override | 173 | @Override |
| 160 | public final void sendMsg(OFMessage m) { | 174 | public final void sendMsg(OFMessage m) { |
| 161 | OFMessage newMsg = m; | 175 | OFMessage newMsg = m; |
| 162 | - //Stub for later enhancement. | 176 | + |
| 177 | + if (m.getType() == OFType.STATS_REQUEST) { | ||
| 178 | + OFStatsRequest sr = (OFStatsRequest) m; | ||
| 179 | + log.debug("OPLK ROADM rebuilding stats request type {}", sr.getStatsType()); | ||
| 180 | + switch (sr.getStatsType()) { | ||
| 181 | + case PORT: | ||
| 182 | + //replace with Oplink experiment stats message to get the port current power | ||
| 183 | + OFOplinkPortPowerRequest pRequest = this.factory().buildOplinkPortPowerRequest() | ||
| 184 | + .setXid(sr.getXid()) | ||
| 185 | + .setFlags(sr.getFlags()) | ||
| 186 | + .build(); | ||
| 187 | + newMsg = pRequest; | ||
| 188 | + break; | ||
| 189 | + default: | ||
| 190 | + break; | ||
| 191 | + } | ||
| 192 | + } else { | ||
| 193 | + log.debug("OPLK ROADM sends msg:{}, as is", m.getType()); | ||
| 194 | + } | ||
| 195 | + | ||
| 163 | super.sendMsg(newMsg); | 196 | super.sendMsg(newMsg); |
| 164 | } | 197 | } |
| 165 | 198 | ||
| ... | @@ -185,4 +218,38 @@ public class OplinkRoadmHandshaker extends AbstractOpenFlowSwitch implements Ope | ... | @@ -185,4 +218,38 @@ public class OplinkRoadmHandshaker extends AbstractOpenFlowSwitch implements Ope |
| 185 | opticalPorts = new ArrayList<>(); | 218 | opticalPorts = new ArrayList<>(); |
| 186 | opticalPorts.addAll(wPorts.getEntries()); | 219 | opticalPorts.addAll(wPorts.getEntries()); |
| 187 | } | 220 | } |
| 221 | + | ||
| 222 | + @Override | ||
| 223 | + public List<PortDescription> processExpPortStats(OFMessage msg) { | ||
| 224 | + if (msg instanceof OFOplinkPortPowerReply) { | ||
| 225 | + return buildPortPowerDescriptions(((OFOplinkPortPowerReply) msg).getEntries()); | ||
| 226 | + } | ||
| 227 | + return Collections.emptyList(); | ||
| 228 | + } | ||
| 229 | + | ||
| 230 | + private OFOplinkPortPower getPortPower(List<OFOplinkPortPower> portPowers, PortNumber portNum) { | ||
| 231 | + for (OFOplinkPortPower power : portPowers) { | ||
| 232 | + if (power.getPort() == portNum.toLong()) { | ||
| 233 | + return power; | ||
| 234 | + } | ||
| 235 | + } | ||
| 236 | + return null; | ||
| 237 | + } | ||
| 238 | + | ||
| 239 | + private List<PortDescription> buildPortPowerDescriptions(List<OFOplinkPortPower> portPowers) { | ||
| 240 | + DeviceService deviceService = this.handler().get(DeviceService.class); | ||
| 241 | + List<Port> ports = deviceService.getPorts(this.data().deviceId()); | ||
| 242 | + final List<PortDescription> portDescs = new ArrayList<>(); | ||
| 243 | + for (Port port : ports) { | ||
| 244 | + DefaultAnnotations.Builder builder = DefaultAnnotations.builder(); | ||
| 245 | + builder.putAll(port.annotations()); | ||
| 246 | + OFOplinkPortPower power = getPortPower(portPowers, port.number()); | ||
| 247 | + if (power != null) { | ||
| 248 | + builder.set(AnnotationKeys.CURRENT_POWER, Long.toString(power.getPowerValue())); | ||
| 249 | + } | ||
| 250 | + portDescs.add(new DefaultPortDescription(port.number(), port.isEnabled(), | ||
| 251 | + port.type(), port.portSpeed(), builder.build())); | ||
| 252 | + } | ||
| 253 | + return portDescs; | ||
| 254 | + } | ||
| 188 | } | 255 | } | ... | ... |
drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkRoadmPowerConfig.java
0 → 100644
| 1 | +/* | ||
| 2 | + * Copyright 2016 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 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.driver.optical.power; | ||
| 18 | + | ||
| 19 | +import java.util.Optional; | ||
| 20 | + | ||
| 21 | +import org.onosproject.net.AnnotationKeys; | ||
| 22 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
| 23 | +import org.onosproject.net.Direction; | ||
| 24 | +import org.onosproject.net.Port; | ||
| 25 | +import org.onosproject.net.PortNumber; | ||
| 26 | +import org.onosproject.net.behaviour.PowerConfig; | ||
| 27 | +import org.onosproject.net.device.DeviceService; | ||
| 28 | +import org.onosproject.openflow.controller.Dpid; | ||
| 29 | +import org.onosproject.openflow.controller.OpenFlowController; | ||
| 30 | +import org.onosproject.openflow.controller.OpenFlowSwitch; | ||
| 31 | +import org.slf4j.Logger; | ||
| 32 | +import org.slf4j.LoggerFactory; | ||
| 33 | + | ||
| 34 | +/** | ||
| 35 | + * Port Power (Gain and attenuation) implementation for Oplink ROADM. | ||
| 36 | + * | ||
| 37 | + * An Oplink ROADM port exposes OchSignal resources. | ||
| 38 | + * Optical Power can be set at port level or channel/wavelength level (attenuation). | ||
| 39 | + * | ||
| 40 | + */ | ||
| 41 | + | ||
| 42 | +public class OplinkRoadmPowerConfig extends AbstractHandlerBehaviour | ||
| 43 | + implements PowerConfig<Direction> { | ||
| 44 | + protected final Logger log = LoggerFactory.getLogger(getClass()); | ||
| 45 | + | ||
| 46 | + private OpenFlowSwitch getOpenFlowDevice() { | ||
| 47 | + final OpenFlowController controller = this.handler().get(OpenFlowController.class); | ||
| 48 | + final Dpid dpid = Dpid.dpid(this.data().deviceId().uri()); | ||
| 49 | + OpenFlowSwitch sw = controller.getSwitch(dpid); | ||
| 50 | + if (sw == null || !sw.isConnected()) { | ||
| 51 | + return null; | ||
| 52 | + } else { | ||
| 53 | + return sw; | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @Override | ||
| 58 | + public Optional<Long> getTargetPower(PortNumber portNum, Direction component) { | ||
| 59 | + // Will be implemented in the future. | ||
| 60 | + return Optional.empty(); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + @Override | ||
| 64 | + public Optional<Long> currentPower(PortNumber portNum, Direction component) { | ||
| 65 | + Long returnVal = null; | ||
| 66 | + // Check if switch is connected, otherwise do not return value in store, | ||
| 67 | + // which is obsolete. | ||
| 68 | + if (getOpenFlowDevice() != null) { | ||
| 69 | + DeviceService deviceService = this.handler().get(DeviceService.class); | ||
| 70 | + Port port = deviceService.getPort(this.data().deviceId(), portNum); | ||
| 71 | + if (port != null) { | ||
| 72 | + String currentPower = port.annotations().value(AnnotationKeys.CURRENT_POWER); | ||
| 73 | + if (currentPower != null) { | ||
| 74 | + returnVal = Long.valueOf(currentPower); | ||
| 75 | + } | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | + return Optional.ofNullable(returnVal); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + @Override | ||
| 82 | + public void setTargetPower(PortNumber portNum, Direction component, long power) { | ||
| 83 | + OpenFlowSwitch device = getOpenFlowDevice(); | ||
| 84 | + if (device != null) { | ||
| 85 | + device.sendMsg(device.factory().buildOplinkPortPowerSet() | ||
| 86 | + .setXid(0) | ||
| 87 | + .setPort((int) portNum.toLong()) | ||
| 88 | + .setPowerValue((int) power) | ||
| 89 | + .build()); | ||
| 90 | + } else { | ||
| 91 | + log.warn("OpenFlow handshaker driver not found or device is not connected"); | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2016-present 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 | + */ | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * Implementations of the power config behaviours for optical devices. | ||
| 19 | + */ | ||
| 20 | +package org.onosproject.driver.optical.power; |
| ... | @@ -56,6 +56,8 @@ | ... | @@ -56,6 +56,8 @@ |
| 56 | impl="org.onosproject.driver.optical.query.OplinkRoadmLambdaQuery"/> | 56 | impl="org.onosproject.driver.optical.query.OplinkRoadmLambdaQuery"/> |
| 57 | <behaviour api="org.onosproject.net.optical.OpticalDevice" | 57 | <behaviour api="org.onosproject.net.optical.OpticalDevice" |
| 58 | impl="org.onosproject.net.optical.DefaultOpticalDevice"/> | 58 | impl="org.onosproject.net.optical.DefaultOpticalDevice"/> |
| 59 | + <behaviour api="org.onosproject.net.behaviour.PowerConfig" | ||
| 60 | + impl="org.onosproject.driver.optical.power.OplinkRoadmPowerConfig"/> | ||
| 59 | </driver> | 61 | </driver> |
| 60 | 62 | ||
| 61 | </drivers> | 63 | </drivers> | ... | ... |
| ... | @@ -15,8 +15,11 @@ | ... | @@ -15,8 +15,11 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.openflow.controller; | 16 | package org.onosproject.openflow.controller; |
| 17 | 17 | ||
| 18 | +import java.util.Collections; | ||
| 18 | import java.util.List; | 19 | import java.util.List; |
| 19 | 20 | ||
| 21 | +import org.onosproject.net.device.PortDescription; | ||
| 22 | +import org.projectfloodlight.openflow.protocol.OFMessage; | ||
| 20 | import org.projectfloodlight.openflow.protocol.OFPortDesc; | 23 | import org.projectfloodlight.openflow.protocol.OFPortDesc; |
| 21 | 24 | ||
| 22 | import com.google.common.annotations.Beta; | 25 | import com.google.common.annotations.Beta; |
| ... | @@ -38,4 +41,15 @@ public interface OpenFlowOpticalSwitch extends OpenFlowSwitch, WithTypedPorts { | ... | @@ -38,4 +41,15 @@ public interface OpenFlowOpticalSwitch extends OpenFlowSwitch, WithTypedPorts { |
| 38 | @Beta | 41 | @Beta |
| 39 | @Override | 42 | @Override |
| 40 | abstract List<OFPortDesc> getPorts(); | 43 | abstract List<OFPortDesc> getPorts(); |
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * Returns updated PortDescriptions built from experimenter message | ||
| 47 | + * received from device. | ||
| 48 | + * | ||
| 49 | + * @param msg OpenFlow message from device. | ||
| 50 | + * @return List of updated PortDescriptions. | ||
| 51 | + */ | ||
| 52 | + default List<PortDescription> processExpPortStats(OFMessage msg) { | ||
| 53 | + return Collections.emptyList(); | ||
| 54 | + } | ||
| 41 | } | 55 | } | ... | ... |
| ... | @@ -547,7 +547,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr | ... | @@ -547,7 +547,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr |
| 547 | 547 | ||
| 548 | private PortDescription buildPortDescription(PortDescPropertyType ptype, OFObject port, | 548 | private PortDescription buildPortDescription(PortDescPropertyType ptype, OFObject port, |
| 549 | OpenFlowOpticalSwitch opsw) { | 549 | OpenFlowOpticalSwitch opsw) { |
| 550 | - if (port instanceof OFPortOptical) { | 550 | + if (port instanceof OFPortOptical) { |
| 551 | return buildPortDescription(ptype, (OFPortOptical) port, opsw); | 551 | return buildPortDescription(ptype, (OFPortOptical) port, opsw); |
| 552 | } | 552 | } |
| 553 | return buildPortDescription(ptype, (OFExpPort) port); | 553 | return buildPortDescription(ptype, (OFExpPort) port); |
| ... | @@ -833,6 +833,16 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr | ... | @@ -833,6 +833,16 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr |
| 833 | statsEntries.clear(); | 833 | statsEntries.clear(); |
| 834 | } | 834 | } |
| 835 | } | 835 | } |
| 836 | + } else if (((OFStatsReply) msg).getStatsType() == OFStatsType.EXPERIMENTER) { | ||
| 837 | + OpenFlowSwitch sw = controller.getSwitch(dpid); | ||
| 838 | + if (sw instanceof OpenFlowOpticalSwitch) { | ||
| 839 | + // Optical switch uses experimenter stats message to update power | ||
| 840 | + List<PortDescription> portDescs = | ||
| 841 | + ((OpenFlowOpticalSwitch) sw).processExpPortStats(msg); | ||
| 842 | + if (!portDescs.isEmpty()) { | ||
| 843 | + providerService.updatePorts(DeviceId.deviceId(Dpid.uri(dpid)), portDescs); | ||
| 844 | + } | ||
| 845 | + } | ||
| 836 | } | 846 | } |
| 837 | break; | 847 | break; |
| 838 | case ERROR: | 848 | case ERROR: | ... | ... |
-
Please register or login to post a comment