blob: f87bb07abb099db1464ce1e26bba6549daca0128 [file] [log] [blame]
Jimmy Yanda878fc2016-09-02 16:32:01 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Jimmy Yanda878fc2016-09-02 16:32:01 -07003 *
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 */
16package org.onosproject.roadm;
17
MaoLu2846b112017-05-15 17:18:55 -070018import com.fasterxml.jackson.databind.node.ArrayNode;
19import com.fasterxml.jackson.databind.node.JsonNodeFactory;
Jimmy Yanda878fc2016-09-02 16:32:01 -070020import com.fasterxml.jackson.databind.node.ObjectNode;
21import com.google.common.collect.ImmutableSet;
22import com.google.common.collect.Range;
23import org.onlab.osgi.ServiceDirectory;
MaoLu937cf422017-03-03 23:31:46 -080024import org.onlab.util.Frequency;
Jimmy Yanda878fc2016-09-02 16:32:01 -070025import org.onosproject.net.AnnotationKeys;
MaoLu2846b112017-05-15 17:18:55 -070026import org.onosproject.net.ConnectPoint;
Jimmy Yanda878fc2016-09-02 16:32:01 -070027import org.onosproject.net.DeviceId;
Sean Condonf20b8ef2019-08-13 16:45:52 +010028import org.onosproject.net.Direction;
Andrea Campanellabdeeda12019-08-02 16:12:05 +020029import org.onosproject.net.ModulationScheme;
MaoLu937cf422017-03-03 23:31:46 -080030import org.onosproject.net.OchSignal;
Jimmy Yanda878fc2016-09-02 16:32:01 -070031import org.onosproject.net.Port;
32import org.onosproject.net.PortNumber;
Sean Condonf20b8ef2019-08-13 16:45:52 +010033import org.onosproject.net.behaviour.PowerConfig;
Andrea Campanellabdeeda12019-08-02 16:12:05 +020034import org.onosproject.net.behaviour.protection.ProtectedTransportEndpointState;
35import org.onosproject.net.behaviour.protection.TransportEndpointState;
36import org.onosproject.net.device.DeviceService;
alessiod4a2b842019-04-30 18:43:17 +020037import org.onosproject.net.intent.OpticalPathIntent;
MaoLu2846b112017-05-15 17:18:55 -070038import org.onosproject.net.optical.OpticalAnnotations;
Jimmy Yanda878fc2016-09-02 16:32:01 -070039import org.onosproject.ui.RequestHandler;
40import org.onosproject.ui.UiConnection;
41import org.onosproject.ui.UiMessageHandler;
42import org.onosproject.ui.table.TableModel;
43import org.onosproject.ui.table.TableRequestHandler;
44import org.slf4j.Logger;
45import org.slf4j.LoggerFactory;
46
47import java.util.Collection;
MaoLu937cf422017-03-03 23:31:46 -080048import java.util.Collections;
49import java.util.Comparator;
Jimmy Yanda878fc2016-09-02 16:32:01 -070050import java.util.List;
MaoLu2846b112017-05-15 17:18:55 -070051import java.util.Map;
Sean Condonf20b8ef2019-08-13 16:45:52 +010052import java.util.Optional;
MaoLu937cf422017-03-03 23:31:46 -080053import java.util.Set;
54
55import static org.onosproject.net.Device.Type;
MaoLu2846b112017-05-15 17:18:55 -070056import static org.onosproject.net.behaviour.protection.ProtectedTransportEndpointState.ACTIVE_UNKNOWN;
57import static org.onosproject.roadm.RoadmUtil.OPS_OPT_AUTO;
58import static org.onosproject.roadm.RoadmUtil.OPS_OPT_FORCE;
59import static org.onosproject.roadm.RoadmUtil.OPS_OPT_MANUAL;
Jimmy Yanda878fc2016-09-02 16:32:01 -070060
61/**
62 * Table-View message handler for ROADM port view.
63 */
64public class RoadmPortViewMessageHandler extends UiMessageHandler {
65
66 private static final String ROADM_PORT_DATA_REQ = "roadmPortDataRequest";
67 private static final String ROADM_PORT_DATA_RESP = "roadmPortDataResponse";
68 private static final String ROADM_PORTS = "roadmPorts";
Jimmy Yanda878fc2016-09-02 16:32:01 -070069 private static final String ROADM_SET_TARGET_POWER_REQ = "roadmSetTargetPowerRequest";
70 private static final String ROADM_SET_TARGET_POWER_RESP = "roadmSetTargetPowerResponse";
Andrea Campanellabdeeda12019-08-02 16:12:05 +020071 private static final String ROADM_SET_MODULATION_REQ = "roadmSetModulationRequest";
72 private static final String ROADM_SET_MODULATION_RESP = "roadmSetModulationResponse";
Andrea Campanella3a224b42019-08-29 16:51:14 -070073 private static final String ROADM_SET_FREQ_REQ = "roadmSetFrequencyRequest";
74 private static final String ROADM_SET_FREQ_RESP = "roadmSetFrequencyResponse";
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -070075 private static final String ROADM_SYNC_TARGET_POWER_REQ = "roadmSyncTargetPowerRequest";
76 private static final String ROADM_SYNC_TARGET_POWER_RESP = "roadmSyncTargetPowerResp";
MaoLu937cf422017-03-03 23:31:46 -080077 private static final String ROADM_SHOW_ITEMS_REQ = "roadmShowPortItemsRequest";
78 private static final String ROADM_SHOW_ITEMS_RESP = "roadmShowPortItemsResponse";
79 private static final String ROADM_SET_OPS_MODE_REQ = "roadmSetOpsModeRequest";
80 private static final String ROADM_SET_OPS_MODE_RESP = "roadmSetOpsModeResponse";
Jimmy Yanda878fc2016-09-02 16:32:01 -070081
82 private static final String ID = "id";
alessiod4a2b842019-04-30 18:43:17 +020083 private static final String REVERSE_PORT = "reversePort";
Jimmy Yanda878fc2016-09-02 16:32:01 -070084 private static final String NAME = "name";
MaoLu937cf422017-03-03 23:31:46 -080085 private static final String TYPE = "type";
Jimmy Yanda878fc2016-09-02 16:32:01 -070086 private static final String ENABLED = "enabled";
87 private static final String MIN_FREQ = "minFreq";
88 private static final String MAX_FREQ = "maxFreq";
89 private static final String GRID = "grid";
Andrea Campanella7ebfe322019-08-29 11:46:57 -070090 private static final String CURR_FREQ = "currFreq";
MaoLu2f7eadb2017-05-02 15:38:43 -070091 private static final String POWER_RANGE = "powerRange";
Jimmy Yanda878fc2016-09-02 16:32:01 -070092 private static final String CURRENT_POWER = "currentPower";
Sean Condonf20b8ef2019-08-13 16:45:52 +010093 private static final String CURRENT_INPUT_POWER = "currentInputPower";
Jimmy Yanda878fc2016-09-02 16:32:01 -070094 private static final String TARGET_POWER = "targetPower";
Andrea Campanellabdeeda12019-08-02 16:12:05 +020095 private static final String MODULATION = "modulation";
Jimmy Yanda878fc2016-09-02 16:32:01 -070096 private static final String HAS_TARGET_POWER = "hasTargetPower";
MaoLu937cf422017-03-03 23:31:46 -080097 private static final String SERVICE_STATE = "serviceState";
Jimmy Yanda878fc2016-09-02 16:32:01 -070098
99 private static final String[] COLUMN_IDS = {
Andrea Campanella7ebfe322019-08-29 11:46:57 -0700100 ID, REVERSE_PORT, TYPE, NAME, ENABLED, MIN_FREQ, MAX_FREQ, GRID, CURR_FREQ, POWER_RANGE,
Sean Condonf20b8ef2019-08-13 16:45:52 +0100101 CURRENT_POWER, CURRENT_INPUT_POWER, SERVICE_STATE, TARGET_POWER, MODULATION, HAS_TARGET_POWER
Jimmy Yanda878fc2016-09-02 16:32:01 -0700102 };
103
Jimmy Yanda878fc2016-09-02 16:32:01 -0700104 private RoadmService roadmService;
MaoLu937cf422017-03-03 23:31:46 -0800105 private DeviceService deviceService;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700106
107 private final Logger log = LoggerFactory.getLogger(getClass());
108
109 @Override
110 public void init(UiConnection connection, ServiceDirectory directory) {
111 super.init(connection, directory);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700112 roadmService = get(RoadmService.class);
MaoLu937cf422017-03-03 23:31:46 -0800113 deviceService = get(DeviceService.class);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700114 }
115
116 @Override
117 protected Collection<RequestHandler> createRequestHandlers() {
MaoLu937cf422017-03-03 23:31:46 -0800118 return ImmutableSet.of(new PortTableDataRequestHandler(),
119 new SetTargetPowerRequestHandler(),
120 new CreateShowItemsRequestHandler(),
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -0700121 new CreateOpsModeSetRequestHandler(),
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200122 new SyncTargetPowerRequestHandler(),
Andrea Campanella3a224b42019-08-29 16:51:14 -0700123 new SetModulationRequestHandler(),
124 new SetFrequencyRequestHandler()
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200125 );
Jimmy Yanda878fc2016-09-02 16:32:01 -0700126 }
127
128 // Handler for sample table requests
129 private final class PortTableDataRequestHandler extends TableRequestHandler {
130
131 private PortTableDataRequestHandler() {
132 super(ROADM_PORT_DATA_REQ, ROADM_PORT_DATA_RESP, ROADM_PORTS);
133 }
134
135 @Override
136 protected String[] getColumnIds() {
137 return COLUMN_IDS;
138 }
139
140 @Override
141 protected String noRowsMessage(ObjectNode payload) {
MaoLu937cf422017-03-03 23:31:46 -0800142 return RoadmUtil.NO_ROWS_MESSAGE;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700143 }
144
145 @Override
146 protected void populateTable(TableModel tm, ObjectNode payload) {
MaoLu937cf422017-03-03 23:31:46 -0800147 DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
Jimmy Yanda878fc2016-09-02 16:32:01 -0700148 if (deviceService.isAvailable(deviceId)) {
149 List<Port> ports = deviceService.getPorts(deviceId);
150 for (Port port : ports) {
151 populateRow(tm.addRow(), port, deviceId);
152 }
153 }
154 }
155
156 private void populateRow(TableModel.Row row, Port port, DeviceId deviceId) {
MaoLu937cf422017-03-03 23:31:46 -0800157 PortNumber portNum = port.number();
158 getFrequencyLimit(deviceId, portNum);
159 row.cell(ID, portNum.toLong())
alessiod4a2b842019-04-30 18:43:17 +0200160 .cell(REVERSE_PORT, RoadmUtil.getAnnotation(port.annotations(),
161 OpticalPathIntent.REVERSE_PORT_ANNOTATION_KEY))
Jimmy Yanda878fc2016-09-02 16:32:01 -0700162 .cell(TYPE, port.type())
163 .cell(ENABLED, port.isEnabled())
MaoLu937cf422017-03-03 23:31:46 -0800164 .cell(NAME, RoadmUtil.getAnnotation(port.annotations(), AnnotationKeys.PORT_NAME))
165 .cell(MIN_FREQ, RoadmUtil.asTHz(minFreq))
166 .cell(MAX_FREQ, RoadmUtil.asTHz(maxFreq))
167 .cell(GRID, RoadmUtil.asGHz(channelSpacing))
Andrea Campanella7ebfe322019-08-29 11:46:57 -0700168 .cell(CURR_FREQ, getWavelength(deviceId, portNum))
MaoLu2f7eadb2017-05-02 15:38:43 -0700169 .cell(POWER_RANGE, getPowerRange(deviceId, portNum))
MaoLu937cf422017-03-03 23:31:46 -0800170 .cell(CURRENT_POWER, getCurrentPower(deviceId, portNum))
Sean Condonf20b8ef2019-08-13 16:45:52 +0100171 .cell(CURRENT_INPUT_POWER, getCurrentInputPower(deviceId, portNum))
MaoLu937cf422017-03-03 23:31:46 -0800172 .cell(SERVICE_STATE, getPortServiceState(deviceId, portNum))
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200173 .cell(MODULATION, getModulation(deviceId, portNum))
MaoLu937cf422017-03-03 23:31:46 -0800174 .cell(TARGET_POWER, getTargetPower(deviceId, portNum))
175 .cell(HAS_TARGET_POWER, roadmService.hasPortTargetPower(deviceId, portNum));
176 }
177
178 private String getPortServiceState(DeviceId deviceId, PortNumber portNumber) {
MaoLu2846b112017-05-15 17:18:55 -0700179 if (deviceService.getDevice(deviceId).type() != Type.FIBER_SWITCH) {
180 return RoadmUtil.NA;
181 }
182 Map<ConnectPoint, ProtectedTransportEndpointState> map =
183 roadmService.getProtectionSwitchStates(deviceId);
184 for (ProtectedTransportEndpointState state : map.values()) {
185 for (TransportEndpointState element : state.pathStates()) {
186 if (element.description().output().connectPoint().port().equals(portNumber)) {
187 return RoadmUtil.defaultString(element.attributes()
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200188 .get(OpticalAnnotations.INPUT_PORT_STATUS), RoadmUtil.UNKNOWN);
MaoLu2846b112017-05-15 17:18:55 -0700189 }
190 }
191 }
192 return RoadmUtil.UNKNOWN;
MaoLu937cf422017-03-03 23:31:46 -0800193 }
194
Andrea Campanella7ebfe322019-08-29 11:46:57 -0700195 private Frequency minFreq = null, maxFreq = null, channelSpacing = null, currFreq = null;
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200196
MaoLu937cf422017-03-03 23:31:46 -0800197 // Gets min frequency, max frequency, channel spacing
198 private void getFrequencyLimit(DeviceId deviceId, PortNumber portNumber) {
199 Set<OchSignal> signals = roadmService.queryLambdas(deviceId, portNumber);
200 if (signals.isEmpty()) {
201 return;
202 }
203 Comparator<OchSignal> compare =
204 (OchSignal a, OchSignal b) -> a.spacingMultiplier() - b.spacingMultiplier();
205 OchSignal minOch = Collections.min(signals, compare);
206 OchSignal maxOch = Collections.max(signals, compare);
207 minFreq = minOch.centralFrequency();
208 maxFreq = maxOch.centralFrequency();
209 channelSpacing = minOch.channelSpacing().frequency();
Jimmy Yanda878fc2016-09-02 16:32:01 -0700210 }
211
MaoLu2f7eadb2017-05-02 15:38:43 -0700212 // Returns the power range as a string, N/A if the power range not exists.
213 // The power range would be input power range or target power range determined by port property.
214 // If the port is RX direction then acquire the input power range from driver.
215 // Otherwise there will be a TX direction port, thus acquire the target power range.
216 private String getPowerRange(DeviceId deviceId, PortNumber portNumber) {
Andrea Campanelladadf6402019-08-07 15:24:11 +0200217 Range<Double> range = roadmService.inputPortPowerRange(deviceId, portNumber);
MaoLu2f7eadb2017-05-02 15:38:43 -0700218 if (range == null) {
219 range = roadmService.targetPortPowerRange(deviceId, portNumber);
220 }
MaoLu937cf422017-03-03 23:31:46 -0800221 return RoadmUtil.objectToString(range, RoadmUtil.NA);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700222 }
223
224 // Returns the current power as a string, Unknown if no value can be found.
225 private String getCurrentPower(DeviceId deviceId, PortNumber portNumber) {
Andrea Campanelladadf6402019-08-07 15:24:11 +0200226 Double currentPower = roadmService.getCurrentPortPower(deviceId, portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800227 return RoadmUtil.objectToString(currentPower, RoadmUtil.UNKNOWN);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700228 }
229
Sean Condonf20b8ef2019-08-13 16:45:52 +0100230 // Returns the current input power as a string, Unknown if no value can be found.
231 private String getCurrentInputPower(DeviceId deviceId, PortNumber portNumber) {
232 PowerConfig powerConfig = deviceService.getDevice(deviceId).as(PowerConfig.class);
233 Optional<Double> currentInputPower = powerConfig.currentInputPower(portNumber, Direction.ALL);
234 Double inputPowerVal = null;
235 if (currentInputPower.isPresent()) {
236 inputPowerVal = currentInputPower.orElse(Double.MIN_VALUE);
237 }
238 return RoadmUtil.objectToString(inputPowerVal, RoadmUtil.UNKNOWN);
239 }
240
Jimmy Yanda878fc2016-09-02 16:32:01 -0700241 // Returns target power as a string, Unknown if target power is expected but
242 // cannot be found, N/A if port does not have configurable target power
243 private String getTargetPower(DeviceId deviceId, PortNumber portNumber) {
MaoLu937cf422017-03-03 23:31:46 -0800244 if (!roadmService.hasPortTargetPower(deviceId, portNumber)) {
245 return RoadmUtil.NA;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700246 }
Andrea Campanelladadf6402019-08-07 15:24:11 +0200247 Double targetPower = roadmService.getTargetPortPower(deviceId, portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800248 return RoadmUtil.objectToString(targetPower, RoadmUtil.UNKNOWN);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700249 }
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200250
251 // Returns modulation as a string, Unknown if modulation is expected but
252 // cannot be found
253 private String getModulation(DeviceId deviceId, PortNumber portNumber) {
254 Port port = deviceService.getPort(deviceId, portNumber);
255 ModulationScheme modulation = null;
256 if (port.type().equals(Port.Type.OCH)) {
257 modulation = roadmService.getModulation(deviceId, portNumber);
258 }
259 return RoadmUtil.objectToString(modulation, RoadmUtil.UNKNOWN);
260 }
Andrea Campanella7ebfe322019-08-29 11:46:57 -0700261
262 // Returns modulation as a string, Unknown if modulation is expected but
263 // cannot be found
264 private String getWavelength(DeviceId deviceId, PortNumber portNumber) {
265 Frequency currentFrequency = roadmService.getWavelength(deviceId, portNumber);
266 if (currentFrequency == null) {
267 return "0";
268 } else {
269 return String.valueOf(currentFrequency.asTHz());
270 }
271 }
Jimmy Yanda878fc2016-09-02 16:32:01 -0700272 }
273
274
275 // Handler for setting port target power
276 private final class SetTargetPowerRequestHandler extends RequestHandler {
277
Jimmy Yanda878fc2016-09-02 16:32:01 -0700278 private static final String TARGET_POWER_ERR_MSG = "Target power range is %s.";
279
280 private SetTargetPowerRequestHandler() {
281 super(ROADM_SET_TARGET_POWER_REQ);
282 }
283
284 @Override
285 public void process(ObjectNode payload) {
MaoLu937cf422017-03-03 23:31:46 -0800286 DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
Jimmy Yanda878fc2016-09-02 16:32:01 -0700287 PortNumber portNumber = PortNumber.portNumber(payload.get(ID).asLong());
Andrea Campanelladadf6402019-08-07 15:24:11 +0200288 Range<Double> range = roadmService.targetPortPowerRange(deviceId, portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800289 if (range == null) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700290 log.warn("Unable to determine target power range for device {}", deviceId);
MaoLu937cf422017-03-03 23:31:46 -0800291 return;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700292 }
Andrea Campanelladadf6402019-08-07 15:24:11 +0200293 Double targetPower = payload.get(TARGET_POWER).asDouble();
MaoLu937cf422017-03-03 23:31:46 -0800294 boolean validTargetPower = range.contains(targetPower);
295 if (validTargetPower) {
296 roadmService.setTargetPortPower(deviceId, portNumber, targetPower);
297 }
298 ObjectNode rootNode = objectNode();
299 rootNode.put(ID, payload.get(ID).asText());
300 rootNode.put(RoadmUtil.VALID, validTargetPower);
301 rootNode.put(RoadmUtil.MESSAGE, String.format(TARGET_POWER_ERR_MSG, range.toString()));
302 sendMessage(ROADM_SET_TARGET_POWER_RESP, rootNode);
303 }
304 }
305
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -0700306 // Handler for sync-up port target power
307 private final class SyncTargetPowerRequestHandler extends RequestHandler {
308
309 private static final String SYNCED_TARGET_POWER = "Synced target power is %s.";
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200310
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -0700311 private SyncTargetPowerRequestHandler() {
312 super(ROADM_SYNC_TARGET_POWER_REQ);
313 }
314
315 @Override
316 public void process(ObjectNode payload) {
317 DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
318 PortNumber portNumber = PortNumber.portNumber(payload.get(ID).asLong());
Andrea Campanelladadf6402019-08-07 15:24:11 +0200319 Double targetPower = roadmService.syncTargetPortPower(deviceId, portNumber);
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -0700320 String power = RoadmUtil.objectToString(targetPower, RoadmUtil.UNKNOWN);
321 ObjectNode rootNode = objectNode();
322 rootNode.put(ID, payload.get(ID).asText())
323 .put(RoadmUtil.VALID, true)
324 .put(RoadmUtil.MESSAGE, String.format(SYNCED_TARGET_POWER, power));
325 sendMessage(ROADM_SYNC_TARGET_POWER_RESP, rootNode);
326 }
327 }
328
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200329 // Handler for setting port modulation
330 private final class SetModulationRequestHandler extends RequestHandler {
331
332 private static final String TARGET_MODULATION_MSG = "Target modulation is %s.";
333
334 private SetModulationRequestHandler() {
335 super(ROADM_SET_MODULATION_REQ);
336 }
337
338 @Override
339 public void process(ObjectNode payload) {
340 DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
341 PortNumber portNumber = PortNumber.portNumber(payload.get(ID).asLong());
342 String modulation = payload.get(MODULATION).asText();
343 roadmService.setModulation(deviceId, portNumber, modulation);
344 ObjectNode rootNode = objectNode();
345 rootNode.put(ID, payload.get(ID).asText());
346 rootNode.put(RoadmUtil.VALID, modulation);
347 rootNode.put(RoadmUtil.MESSAGE, String.format(TARGET_MODULATION_MSG, modulation));
348 sendMessage(ROADM_SET_MODULATION_RESP, rootNode);
349 }
350 }
351
Andrea Campanella3a224b42019-08-29 16:51:14 -0700352 // Handler for setting port frequency
353 private final class SetFrequencyRequestHandler extends RequestHandler {
354
355 private static final String TARGET_FREQ_MSG = "Target frequency is %s.";
356
357 private SetFrequencyRequestHandler() {
358 super(ROADM_SET_FREQ_REQ);
359 }
360
361 @Override
362 public void process(ObjectNode payload) {
363 DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
364 PortNumber portNumber = PortNumber.portNumber(payload.get(ID).asLong());
365 String frequency = payload.get(CURR_FREQ).asText();
366 double freqThz = Double.parseDouble(frequency);
367 Frequency freq = Frequency.ofTHz(freqThz);
368 OchSignal ochSignal = RoadmUtil.createOchSignalFromWavelength(freq.asMHz(), deviceService,
369 deviceId, portNumber);
370 roadmService.createConnection(deviceId, 100, true, 0,
371 portNumber, portNumber, ochSignal);
372 ObjectNode rootNode = objectNode();
373 rootNode.put(ID, payload.get(ID).asText());
374 rootNode.put(RoadmUtil.VALID, frequency);
375 rootNode.put(RoadmUtil.MESSAGE, String.format(TARGET_FREQ_MSG, frequency));
376 sendMessage(ROADM_SET_FREQ_RESP, rootNode);
377 }
378 }
379
MaoLu2846b112017-05-15 17:18:55 -0700380 // Protection switch operation type and path index
381 private static final String OPS_ARRAY_INDEX = "index";
382 private static final String OPS_ARRAY_OPERATION = "operation";
383 private static final String[] OPS_NON_AUTO_OPTS = {OPS_OPT_FORCE, OPS_OPT_MANUAL};
384
MaoLu937cf422017-03-03 23:31:46 -0800385 private final class CreateShowItemsRequestHandler extends RequestHandler {
386 private static final String SHOW_TARGET_POWER = "showTargetPower";
387 private static final String SHOW_SERVICE_STATE = "showServiceState";
388 private static final String SHOW_FLOW_ICON = "showFlowIcon";
MaoLu2846b112017-05-15 17:18:55 -0700389 private static final String OPS_PATHS = "opsOperations";
390 private static final String OPS_ARRAY_NAME = "name";
391 private static final String OPS_GROUP_FMT = "GROUP%d ";
MaoLu937cf422017-03-03 23:31:46 -0800392
393 private CreateShowItemsRequestHandler() {
394 super(ROADM_SHOW_ITEMS_REQ);
395 }
396
397 @Override
398 public void process(ObjectNode payload) {
399 DeviceId did = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
400 Type devType = deviceService.getDevice(did).type();
401 // Build response
402 ObjectNode node = objectNode();
MaoLu937cf422017-03-03 23:31:46 -0800403 node.put(SHOW_FLOW_ICON, devType == Type.ROADM);
MaoLu2846b112017-05-15 17:18:55 -0700404 if (devType == Type.FIBER_SWITCH) {
405 node.put(SHOW_TARGET_POWER, false);
406 node.put(SHOW_SERVICE_STATE, true);
407 // add protection switch paths
408 putProtectionSwitchPaths(did, node);
409 } else {
410 node.put(SHOW_TARGET_POWER, true);
411 node.put(SHOW_SERVICE_STATE, false);
412 }
MaoLu937cf422017-03-03 23:31:46 -0800413 sendMessage(ROADM_SHOW_ITEMS_RESP, node);
414 }
MaoLu2846b112017-05-15 17:18:55 -0700415
416 private void putProtectionSwitchPaths(DeviceId deviceId, ObjectNode node) {
417 Map<ConnectPoint, ProtectedTransportEndpointState> states =
418 roadmService.getProtectionSwitchStates(deviceId);
419 ArrayNode nodes = node.putArray(OPS_PATHS);
420 // Add path names for every identifier.
421 int groupIndex = 0;
422 for (ConnectPoint identifier : states.keySet()) {
423 // No group name needed if there is only one connection point identifier.
424 String groupName = states.keySet().size() == 1 ? "" : String.format(OPS_GROUP_FMT, ++groupIndex);
425 // Add AUTOMATIC operation.
426 nodes.add(new ObjectNode(JsonNodeFactory.instance)
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200427 .put(OPS_ARRAY_INDEX, ACTIVE_UNKNOWN)
428 .put(OPS_ARRAY_OPERATION, OPS_OPT_AUTO)
429 .put(OPS_ARRAY_NAME, String.format("%s%s", groupName, OPS_OPT_AUTO)));
MaoLu2846b112017-05-15 17:18:55 -0700430 // Add FORCE and MANUAL operations for every path.
431 for (String opt : OPS_NON_AUTO_OPTS) {
432 int pathIndex = 0;
433 for (TransportEndpointState state : states.get(identifier).pathStates()) {
434 nodes.add(new ObjectNode(JsonNodeFactory.instance)
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200435 .put(OPS_ARRAY_INDEX, pathIndex++)
436 .put(OPS_ARRAY_OPERATION, opt)
437 .put(OPS_ARRAY_NAME,
438 String.format("%s%s %s", groupName, opt, state.id().id().toUpperCase())));
MaoLu2846b112017-05-15 17:18:55 -0700439 }
440 }
441 }
442
443
444 }
MaoLu937cf422017-03-03 23:31:46 -0800445 }
446
447 private final class CreateOpsModeSetRequestHandler extends RequestHandler {
MaoLu937cf422017-03-03 23:31:46 -0800448 private static final String DEVICE_INVALID_ERR_MSG = "Apply failed: device is offline or unavailable.";
449 private static final String TYPE_INVALID_ERR_MSG = "Apply failed: invalid device type.";
450
451 private CreateOpsModeSetRequestHandler() {
452 super(ROADM_SET_OPS_MODE_REQ);
453 }
454
455 @Override
456 public void process(ObjectNode payload) {
457 DeviceId did = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
458 ObjectNode node = objectNode();
459 if (!deviceService.isAvailable(did)) {
460 node.put(RoadmUtil.VALID, false);
461 node.put(RoadmUtil.MESSAGE, DEVICE_INVALID_ERR_MSG);
462 sendMessage(ROADM_SET_OPS_MODE_RESP, node);
463 return;
464 }
465 Type devType = deviceService.getDevice(did).type();
466 if (devType != Type.FIBER_SWITCH) {
467 node.put(RoadmUtil.VALID, false);
468 node.put(RoadmUtil.MESSAGE, TYPE_INVALID_ERR_MSG);
469 sendMessage(ROADM_SET_OPS_MODE_RESP, node);
470 return;
471 }
MaoLu2846b112017-05-15 17:18:55 -0700472 // get switch configuration from payload, and then switch the device.
473 roadmService.configProtectionSwitch(did, string(payload, OPS_ARRAY_OPERATION),
474 roadmService.getProtectionSwitchStates(did).keySet().toArray(new ConnectPoint[0])[0],
475 (int) number(payload, OPS_ARRAY_INDEX));
MaoLu937cf422017-03-03 23:31:46 -0800476 node.put(RoadmUtil.VALID, true);
477 sendMessage(ROADM_SET_OPS_MODE_RESP, node);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700478 }
479 }
480}