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