yjimmyy
Committed by Gerrit Code Review

Implement PowerConfig for Oplink Devices

Change-Id: I939126580f8d3cdcdbcd9a46f6ee5cacbd25051d
...@@ -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 }
......
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:
......