blob: 61a3727d42ce3977fd20cbb6d701fb6c955341f8 [file] [log] [blame]
Laszlo Papp8b3a5f62017-10-05 13:32:00 +01001/*
2 * Copyright 2017 Open Networking Foundation
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
17package org.onosproject.drivers.polatis.netconf;
18
19import com.google.common.collect.Range;
20import org.apache.commons.configuration.HierarchicalConfiguration;
21import org.onosproject.net.Direction;
22import org.onosproject.net.OchSignal;
23import org.onosproject.net.PortNumber;
24import org.onosproject.net.behaviour.PowerConfig;
25import org.onosproject.net.driver.AbstractHandlerBehaviour;
26import org.slf4j.Logger;
27
Laszlo Papp8cd61fb2017-10-13 16:45:00 +010028import java.util.ArrayList;
29import java.util.List;
Laszlo Papp8b87a192017-10-19 18:47:12 +010030import java.util.NoSuchElementException;
Laszlo Papp8b3a5f62017-10-05 13:32:00 +010031import java.util.Optional;
32
33import static org.onosproject.drivers.polatis.netconf.PolatisOpticalUtility.POWER_MULTIPLIER;
Laszlo Papp8b87a192017-10-19 18:47:12 +010034import static org.onosproject.drivers.polatis.netconf.PolatisOpticalUtility.VOA_MULTIPLIER;
Laszlo Papp8b3a5f62017-10-05 13:32:00 +010035import static org.onosproject.drivers.polatis.netconf.PolatisOpticalUtility.POWER_RANGE;
Laszlo Papp81cc6422017-10-18 02:24:09 +010036import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.netconfGet;
Laszlo Papp8b87a192017-10-19 18:47:12 +010037import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.netconfEditConfig;
Laszlo Papp81cc6422017-10-18 02:24:09 +010038import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.configAt;
39import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.configsAt;
Laszlo Papp8b87a192017-10-19 18:47:12 +010040import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.xml;
Laszlo Papp81cc6422017-10-18 02:24:09 +010041import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.xmlOpen;
42import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.xmlClose;
43import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_PORT;
44import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_PORTID;
45import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_OPM;
46import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_OPM_XMLNS;
47import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_DATA_OPM;
48import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_DATA_OPM_PORT;
Laszlo Papp8b87a192017-10-19 18:47:12 +010049import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_VOA;
50import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_VOA_XMLNS;
51import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.KEY_DATA_VOA_PORT;
52import static org.onosproject.drivers.polatis.netconf.PolatisNetconfUtility.CFG_MODE_MERGE;
Laszlo Papp81cc6422017-10-18 02:24:09 +010053
Laszlo Papp8b3a5f62017-10-05 13:32:00 +010054import static org.slf4j.LoggerFactory.getLogger;
55
56/**
57 * Get current or target port/channel power from a Polatis optical netconf device.
58 * Set target port power or channel attenuation to an optical netconf device.
59 */
60public class PolatisPowerConfig<T> extends AbstractHandlerBehaviour
61 implements PowerConfig<T> {
62
Laszlo Papp81cc6422017-10-18 02:24:09 +010063 private static final String KEY_POWER = "power";
Laszlo Papp8b87a192017-10-19 18:47:12 +010064 private static final String KEY_ATTEN_LEVEL = "atten-level";
65 private static final String KEY_ATTEN_MODE = "atten-mode";
66 private static final String VALUE_ATTEN_MODE = "VOA_MODE_ABSOLUTE";
Laszlo Papp81cc6422017-10-18 02:24:09 +010067
Laszlo Papp8b3a5f62017-10-05 13:32:00 +010068 private static final Logger log = getLogger(PolatisPowerConfig.class);
69
70 @Override
71 public Optional<Long> getTargetPower(PortNumber port, T component) {
72 return Optional.ofNullable(acquireTargetPower(port, component));
73 }
74
75 @Override
76 public void setTargetPower(PortNumber port, T component, long power) {
77 if (component instanceof OchSignal) {
78 log.warn("Channel power is not applicable.");
79 return;
80 }
81 setPortTargetPower(port, power);
82 }
83
84 @Override
85 public Optional<Long> currentPower(PortNumber port, T component) {
86 return Optional.ofNullable(acquireCurrentPower(port, component));
87 }
88
89 @Override
90 public Optional<Range<Long>> getTargetPowerRange(PortNumber port, T component) {
91 return Optional.ofNullable(getTxPowerRange(port, component));
92 }
93
94 @Override
95 public Optional<Range<Long>> getInputPowerRange(PortNumber port, T component) {
96 return Optional.ofNullable(getRxPowerRange(port, component));
97 }
98
Laszlo Papp8cd61fb2017-10-13 16:45:00 +010099 @Override
100 public List<PortNumber> getPorts(T component) {
101 if (component instanceof OchSignal) {
102 log.warn("Channel component is not applicable.");
103 return new ArrayList<PortNumber>();
104 }
105 log.debug("Get port config ports...");
106 return acquirePorts();
107 }
108
109 private List<PortNumber> acquirePorts() {
110 String filter = getPortPowerFilter(null);
111 String reply = netconfGet(handler(), filter);
112 List<HierarchicalConfiguration> subtrees = configsAt(reply, KEY_DATA_OPM);
113 List<PortNumber> ports = new ArrayList<PortNumber>();
114 for (HierarchicalConfiguration portConfig : subtrees) {
115 ports.add(PortNumber.portNumber(portConfig.getLong(KEY_PORTID)));
116 }
117 return ports;
118 }
119
120 /**
121 * Get the filter string for the OPM power NETCONF request.
122 *
123 * @param port the port, null to return all the opm ports
124 * @return filter string
125 */
Laszlo Papp8b3a5f62017-10-05 13:32:00 +0100126 private String getPortPowerFilter(PortNumber port) {
Laszlo Papp8cd61fb2017-10-13 16:45:00 +0100127 StringBuilder filter = new StringBuilder(xmlOpen(KEY_OPM_XMLNS))
Laszlo Papp8b3a5f62017-10-05 13:32:00 +0100128 .append(xmlOpen(KEY_PORT))
Laszlo Papp8cd61fb2017-10-13 16:45:00 +0100129 .append(xmlOpen(KEY_PORTID));
130 if (port != null) {
131 filter.append(port.toLong());
132 }
133 return filter.append(xmlClose(KEY_PORTID))
Laszlo Papp8b3a5f62017-10-05 13:32:00 +0100134 .append(xmlClose(KEY_PORT))
135 .append(xmlClose(KEY_OPM))
136 .toString();
137 }
138
139 private Long acquireTargetPower(PortNumber port, T component) {
140 if (component instanceof OchSignal) {
141 log.warn("Channel power is not applicable.");
142 return null;
143 }
144 log.debug("Get port{} target power...", port);
Laszlo Papp8b87a192017-10-19 18:47:12 +0100145 return acquirePortAttenuation(port);
146 }
147
148 /**
149 * Get the filter string for the attenuation NETCONF request.
150 *
151 * @param port the port, null to return all the attenuation ports
152 * @return filter string
153 */
154 private String getPortAttenuationFilter(PortNumber port) {
155 StringBuilder filter = new StringBuilder(xmlOpen(KEY_VOA_XMLNS))
156 .append(xmlOpen(KEY_PORT))
157 .append(xmlOpen(KEY_PORTID));
158 if (port != null) {
159 filter.append(port.toLong());
160 }
161 return filter.append(xmlClose(KEY_PORTID))
162 .append(xmlOpen(KEY_ATTEN_LEVEL))
163 .append(xmlClose(KEY_ATTEN_LEVEL))
164 .append(xmlClose(KEY_PORT))
165 .append(xmlClose(KEY_VOA))
166 .toString();
167 }
168
169 private Long acquirePortAttenuation(PortNumber port) {
170 String filter = getPortAttenuationFilter(port);
171 String reply = netconfGet(handler(), filter);
172 HierarchicalConfiguration info = configAt(reply, KEY_DATA_VOA_PORT);
173 if (info == null) {
174 return null;
175 }
176 long attenuation = 0;
177 try {
178 attenuation = (long) (info.getDouble(KEY_ATTEN_LEVEL) * VOA_MULTIPLIER);
179 } catch (NoSuchElementException e) {
180 log.debug("Could not find atten-level for port {}", port);
181 }
182
183 return attenuation;
Laszlo Papp8b3a5f62017-10-05 13:32:00 +0100184 }
185
186 private Long acquireCurrentPower(PortNumber port, T component) {
187 if (component instanceof OchSignal) {
188 log.warn("Channel power is not applicable.");
189 return null;
190 }
191 log.debug("Get port{} current power...", port);
192 return acquirePortPower(port);
193 }
194
195 private Long acquirePortPower(PortNumber port) {
196 String filter = getPortPowerFilter(port);
197 String reply = netconfGet(handler(), filter);
198 HierarchicalConfiguration info = configAt(reply, KEY_DATA_OPM_PORT);
199 if (info == null) {
200 return null;
201 }
202 return (long) (info.getDouble(KEY_POWER) * POWER_MULTIPLIER);
203 }
204
205 private boolean setPortTargetPower(PortNumber port, long power) {
206 log.debug("Set port{} target power...", port);
Laszlo Papp8b87a192017-10-19 18:47:12 +0100207 String cfg = new StringBuilder(xmlOpen(KEY_VOA_XMLNS))
208 .append(xmlOpen(KEY_PORT))
209 .append(xml(KEY_PORTID, Long.toString(port.toLong())))
210 .append(xml(KEY_ATTEN_MODE, VALUE_ATTEN_MODE))
Laszlo Pappda059e72017-10-23 11:39:31 +0100211 .append(xml(KEY_ATTEN_LEVEL, Double.toString((double) power / VOA_MULTIPLIER)))
Laszlo Papp8b87a192017-10-19 18:47:12 +0100212 .append(xmlClose(KEY_PORT))
Laszlo Pappda059e72017-10-23 11:39:31 +0100213 .append(xmlClose(KEY_VOA))
Laszlo Papp8b87a192017-10-19 18:47:12 +0100214 .toString();
215 return netconfEditConfig(handler(), CFG_MODE_MERGE, cfg);
Laszlo Papp8b3a5f62017-10-05 13:32:00 +0100216 }
217
218 private Range<Long> getPowerRange() {
219 return POWER_RANGE;
220 }
221
222 private Range<Long> getTxPowerRange(PortNumber port, T component) {
223 if (component instanceof Direction) {
224 log.debug("Get target port{} power range...", port);
225 return getPowerRange();
226 } else {
Laszlo Papp8b3a5f62017-10-05 13:32:00 +0100227 log.warn("Channel power is not applicable.");
228 return null;
229 }
230 }
231
232 private Range<Long> getRxPowerRange(PortNumber port, T component) {
233 log.debug("Get input port{} power range...", port);
234 return getPowerRange();
235 }
236}