blob: 1a27fd3398e0beb848cc0fbaeca1546c0862f71d [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";
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -070073 private static final String ROADM_SYNC_TARGET_POWER_REQ = "roadmSyncTargetPowerRequest";
74 private static final String ROADM_SYNC_TARGET_POWER_RESP = "roadmSyncTargetPowerResp";
MaoLu937cf422017-03-03 23:31:46 -080075 private static final String ROADM_SHOW_ITEMS_REQ = "roadmShowPortItemsRequest";
76 private static final String ROADM_SHOW_ITEMS_RESP = "roadmShowPortItemsResponse";
77 private static final String ROADM_SET_OPS_MODE_REQ = "roadmSetOpsModeRequest";
78 private static final String ROADM_SET_OPS_MODE_RESP = "roadmSetOpsModeResponse";
Jimmy Yanda878fc2016-09-02 16:32:01 -070079
80 private static final String ID = "id";
alessiod4a2b842019-04-30 18:43:17 +020081 private static final String REVERSE_PORT = "reversePort";
Jimmy Yanda878fc2016-09-02 16:32:01 -070082 private static final String NAME = "name";
MaoLu937cf422017-03-03 23:31:46 -080083 private static final String TYPE = "type";
Jimmy Yanda878fc2016-09-02 16:32:01 -070084 private static final String ENABLED = "enabled";
85 private static final String MIN_FREQ = "minFreq";
86 private static final String MAX_FREQ = "maxFreq";
87 private static final String GRID = "grid";
MaoLu2f7eadb2017-05-02 15:38:43 -070088 private static final String POWER_RANGE = "powerRange";
Jimmy Yanda878fc2016-09-02 16:32:01 -070089 private static final String CURRENT_POWER = "currentPower";
Sean Condonf20b8ef2019-08-13 16:45:52 +010090 private static final String CURRENT_INPUT_POWER = "currentInputPower";
Jimmy Yanda878fc2016-09-02 16:32:01 -070091 private static final String TARGET_POWER = "targetPower";
Andrea Campanellabdeeda12019-08-02 16:12:05 +020092 private static final String MODULATION = "modulation";
Jimmy Yanda878fc2016-09-02 16:32:01 -070093 private static final String HAS_TARGET_POWER = "hasTargetPower";
MaoLu937cf422017-03-03 23:31:46 -080094 private static final String SERVICE_STATE = "serviceState";
Jimmy Yanda878fc2016-09-02 16:32:01 -070095
96 private static final String[] COLUMN_IDS = {
alessiod4a2b842019-04-30 18:43:17 +020097 ID, REVERSE_PORT, TYPE, NAME, ENABLED, MIN_FREQ, MAX_FREQ, GRID, POWER_RANGE,
Sean Condonf20b8ef2019-08-13 16:45:52 +010098 CURRENT_POWER, CURRENT_INPUT_POWER, SERVICE_STATE, TARGET_POWER, MODULATION, HAS_TARGET_POWER
Jimmy Yanda878fc2016-09-02 16:32:01 -070099 };
100
Jimmy Yanda878fc2016-09-02 16:32:01 -0700101 private RoadmService roadmService;
MaoLu937cf422017-03-03 23:31:46 -0800102 private DeviceService deviceService;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700103
104 private final Logger log = LoggerFactory.getLogger(getClass());
105
106 @Override
107 public void init(UiConnection connection, ServiceDirectory directory) {
108 super.init(connection, directory);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700109 roadmService = get(RoadmService.class);
MaoLu937cf422017-03-03 23:31:46 -0800110 deviceService = get(DeviceService.class);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700111 }
112
113 @Override
114 protected Collection<RequestHandler> createRequestHandlers() {
MaoLu937cf422017-03-03 23:31:46 -0800115 return ImmutableSet.of(new PortTableDataRequestHandler(),
116 new SetTargetPowerRequestHandler(),
117 new CreateShowItemsRequestHandler(),
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -0700118 new CreateOpsModeSetRequestHandler(),
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200119 new SyncTargetPowerRequestHandler(),
120 new SetModulationRequestHandler()
121 );
Jimmy Yanda878fc2016-09-02 16:32:01 -0700122 }
123
124 // Handler for sample table requests
125 private final class PortTableDataRequestHandler extends TableRequestHandler {
126
127 private PortTableDataRequestHandler() {
128 super(ROADM_PORT_DATA_REQ, ROADM_PORT_DATA_RESP, ROADM_PORTS);
129 }
130
131 @Override
132 protected String[] getColumnIds() {
133 return COLUMN_IDS;
134 }
135
136 @Override
137 protected String noRowsMessage(ObjectNode payload) {
MaoLu937cf422017-03-03 23:31:46 -0800138 return RoadmUtil.NO_ROWS_MESSAGE;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700139 }
140
141 @Override
142 protected void populateTable(TableModel tm, ObjectNode payload) {
MaoLu937cf422017-03-03 23:31:46 -0800143 DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
Jimmy Yanda878fc2016-09-02 16:32:01 -0700144 if (deviceService.isAvailable(deviceId)) {
145 List<Port> ports = deviceService.getPorts(deviceId);
146 for (Port port : ports) {
147 populateRow(tm.addRow(), port, deviceId);
148 }
149 }
150 }
151
152 private void populateRow(TableModel.Row row, Port port, DeviceId deviceId) {
MaoLu937cf422017-03-03 23:31:46 -0800153 PortNumber portNum = port.number();
154 getFrequencyLimit(deviceId, portNum);
155 row.cell(ID, portNum.toLong())
alessiod4a2b842019-04-30 18:43:17 +0200156 .cell(REVERSE_PORT, RoadmUtil.getAnnotation(port.annotations(),
157 OpticalPathIntent.REVERSE_PORT_ANNOTATION_KEY))
Jimmy Yanda878fc2016-09-02 16:32:01 -0700158 .cell(TYPE, port.type())
159 .cell(ENABLED, port.isEnabled())
MaoLu937cf422017-03-03 23:31:46 -0800160 .cell(NAME, RoadmUtil.getAnnotation(port.annotations(), AnnotationKeys.PORT_NAME))
161 .cell(MIN_FREQ, RoadmUtil.asTHz(minFreq))
162 .cell(MAX_FREQ, RoadmUtil.asTHz(maxFreq))
163 .cell(GRID, RoadmUtil.asGHz(channelSpacing))
MaoLu2f7eadb2017-05-02 15:38:43 -0700164 .cell(POWER_RANGE, getPowerRange(deviceId, portNum))
MaoLu937cf422017-03-03 23:31:46 -0800165 .cell(CURRENT_POWER, getCurrentPower(deviceId, portNum))
Sean Condonf20b8ef2019-08-13 16:45:52 +0100166 .cell(CURRENT_INPUT_POWER, getCurrentInputPower(deviceId, portNum))
MaoLu937cf422017-03-03 23:31:46 -0800167 .cell(SERVICE_STATE, getPortServiceState(deviceId, portNum))
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200168 .cell(MODULATION, getModulation(deviceId, portNum))
MaoLu937cf422017-03-03 23:31:46 -0800169 .cell(TARGET_POWER, getTargetPower(deviceId, portNum))
170 .cell(HAS_TARGET_POWER, roadmService.hasPortTargetPower(deviceId, portNum));
171 }
172
173 private String getPortServiceState(DeviceId deviceId, PortNumber portNumber) {
MaoLu2846b112017-05-15 17:18:55 -0700174 if (deviceService.getDevice(deviceId).type() != Type.FIBER_SWITCH) {
175 return RoadmUtil.NA;
176 }
177 Map<ConnectPoint, ProtectedTransportEndpointState> map =
178 roadmService.getProtectionSwitchStates(deviceId);
179 for (ProtectedTransportEndpointState state : map.values()) {
180 for (TransportEndpointState element : state.pathStates()) {
181 if (element.description().output().connectPoint().port().equals(portNumber)) {
182 return RoadmUtil.defaultString(element.attributes()
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200183 .get(OpticalAnnotations.INPUT_PORT_STATUS), RoadmUtil.UNKNOWN);
MaoLu2846b112017-05-15 17:18:55 -0700184 }
185 }
186 }
187 return RoadmUtil.UNKNOWN;
MaoLu937cf422017-03-03 23:31:46 -0800188 }
189
190 private Frequency minFreq = null, maxFreq = null, channelSpacing = null;
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200191
MaoLu937cf422017-03-03 23:31:46 -0800192 // Gets min frequency, max frequency, channel spacing
193 private void getFrequencyLimit(DeviceId deviceId, PortNumber portNumber) {
194 Set<OchSignal> signals = roadmService.queryLambdas(deviceId, portNumber);
195 if (signals.isEmpty()) {
196 return;
197 }
198 Comparator<OchSignal> compare =
199 (OchSignal a, OchSignal b) -> a.spacingMultiplier() - b.spacingMultiplier();
200 OchSignal minOch = Collections.min(signals, compare);
201 OchSignal maxOch = Collections.max(signals, compare);
202 minFreq = minOch.centralFrequency();
203 maxFreq = maxOch.centralFrequency();
204 channelSpacing = minOch.channelSpacing().frequency();
Jimmy Yanda878fc2016-09-02 16:32:01 -0700205 }
206
MaoLu2f7eadb2017-05-02 15:38:43 -0700207 // Returns the power range as a string, N/A if the power range not exists.
208 // The power range would be input power range or target power range determined by port property.
209 // If the port is RX direction then acquire the input power range from driver.
210 // Otherwise there will be a TX direction port, thus acquire the target power range.
211 private String getPowerRange(DeviceId deviceId, PortNumber portNumber) {
Andrea Campanelladadf6402019-08-07 15:24:11 +0200212 Range<Double> range = roadmService.inputPortPowerRange(deviceId, portNumber);
MaoLu2f7eadb2017-05-02 15:38:43 -0700213 if (range == null) {
214 range = roadmService.targetPortPowerRange(deviceId, portNumber);
215 }
MaoLu937cf422017-03-03 23:31:46 -0800216 return RoadmUtil.objectToString(range, RoadmUtil.NA);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700217 }
218
219 // Returns the current power as a string, Unknown if no value can be found.
220 private String getCurrentPower(DeviceId deviceId, PortNumber portNumber) {
Andrea Campanelladadf6402019-08-07 15:24:11 +0200221 Double currentPower = roadmService.getCurrentPortPower(deviceId, portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800222 return RoadmUtil.objectToString(currentPower, RoadmUtil.UNKNOWN);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700223 }
224
Sean Condonf20b8ef2019-08-13 16:45:52 +0100225 // Returns the current input power as a string, Unknown if no value can be found.
226 private String getCurrentInputPower(DeviceId deviceId, PortNumber portNumber) {
227 PowerConfig powerConfig = deviceService.getDevice(deviceId).as(PowerConfig.class);
228 Optional<Double> currentInputPower = powerConfig.currentInputPower(portNumber, Direction.ALL);
229 Double inputPowerVal = null;
230 if (currentInputPower.isPresent()) {
231 inputPowerVal = currentInputPower.orElse(Double.MIN_VALUE);
232 }
233 return RoadmUtil.objectToString(inputPowerVal, RoadmUtil.UNKNOWN);
234 }
235
Jimmy Yanda878fc2016-09-02 16:32:01 -0700236 // Returns target power as a string, Unknown if target power is expected but
237 // cannot be found, N/A if port does not have configurable target power
238 private String getTargetPower(DeviceId deviceId, PortNumber portNumber) {
MaoLu937cf422017-03-03 23:31:46 -0800239 if (!roadmService.hasPortTargetPower(deviceId, portNumber)) {
240 return RoadmUtil.NA;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700241 }
Andrea Campanelladadf6402019-08-07 15:24:11 +0200242 Double targetPower = roadmService.getTargetPortPower(deviceId, portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800243 return RoadmUtil.objectToString(targetPower, RoadmUtil.UNKNOWN);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700244 }
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200245
246 // Returns modulation as a string, Unknown if modulation is expected but
247 // cannot be found
248 private String getModulation(DeviceId deviceId, PortNumber portNumber) {
249 Port port = deviceService.getPort(deviceId, portNumber);
250 ModulationScheme modulation = null;
251 if (port.type().equals(Port.Type.OCH)) {
252 modulation = roadmService.getModulation(deviceId, portNumber);
253 }
254 return RoadmUtil.objectToString(modulation, RoadmUtil.UNKNOWN);
255 }
Jimmy Yanda878fc2016-09-02 16:32:01 -0700256 }
257
258
259 // Handler for setting port target power
260 private final class SetTargetPowerRequestHandler extends RequestHandler {
261
Jimmy Yanda878fc2016-09-02 16:32:01 -0700262 private static final String TARGET_POWER_ERR_MSG = "Target power range is %s.";
263
264 private SetTargetPowerRequestHandler() {
265 super(ROADM_SET_TARGET_POWER_REQ);
266 }
267
268 @Override
269 public void process(ObjectNode payload) {
MaoLu937cf422017-03-03 23:31:46 -0800270 DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
Jimmy Yanda878fc2016-09-02 16:32:01 -0700271 PortNumber portNumber = PortNumber.portNumber(payload.get(ID).asLong());
Andrea Campanelladadf6402019-08-07 15:24:11 +0200272 Range<Double> range = roadmService.targetPortPowerRange(deviceId, portNumber);
MaoLu937cf422017-03-03 23:31:46 -0800273 if (range == null) {
Jimmy Yanda878fc2016-09-02 16:32:01 -0700274 log.warn("Unable to determine target power range for device {}", deviceId);
MaoLu937cf422017-03-03 23:31:46 -0800275 return;
Jimmy Yanda878fc2016-09-02 16:32:01 -0700276 }
Andrea Campanelladadf6402019-08-07 15:24:11 +0200277 Double targetPower = payload.get(TARGET_POWER).asDouble();
MaoLu937cf422017-03-03 23:31:46 -0800278 boolean validTargetPower = range.contains(targetPower);
279 if (validTargetPower) {
280 roadmService.setTargetPortPower(deviceId, portNumber, targetPower);
281 }
282 ObjectNode rootNode = objectNode();
283 rootNode.put(ID, payload.get(ID).asText());
284 rootNode.put(RoadmUtil.VALID, validTargetPower);
285 rootNode.put(RoadmUtil.MESSAGE, String.format(TARGET_POWER_ERR_MSG, range.toString()));
286 sendMessage(ROADM_SET_TARGET_POWER_RESP, rootNode);
287 }
288 }
289
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -0700290 // Handler for sync-up port target power
291 private final class SyncTargetPowerRequestHandler extends RequestHandler {
292
293 private static final String SYNCED_TARGET_POWER = "Synced target power is %s.";
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200294
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -0700295 private SyncTargetPowerRequestHandler() {
296 super(ROADM_SYNC_TARGET_POWER_REQ);
297 }
298
299 @Override
300 public void process(ObjectNode payload) {
301 DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
302 PortNumber portNumber = PortNumber.portNumber(payload.get(ID).asLong());
Andrea Campanelladadf6402019-08-07 15:24:11 +0200303 Double targetPower = roadmService.syncTargetPortPower(deviceId, portNumber);
Boyuan Yanf3f6a8d2019-05-26 18:35:54 -0700304 String power = RoadmUtil.objectToString(targetPower, RoadmUtil.UNKNOWN);
305 ObjectNode rootNode = objectNode();
306 rootNode.put(ID, payload.get(ID).asText())
307 .put(RoadmUtil.VALID, true)
308 .put(RoadmUtil.MESSAGE, String.format(SYNCED_TARGET_POWER, power));
309 sendMessage(ROADM_SYNC_TARGET_POWER_RESP, rootNode);
310 }
311 }
312
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200313 // Handler for setting port modulation
314 private final class SetModulationRequestHandler extends RequestHandler {
315
316 private static final String TARGET_MODULATION_MSG = "Target modulation is %s.";
317
318 private SetModulationRequestHandler() {
319 super(ROADM_SET_MODULATION_REQ);
320 }
321
322 @Override
323 public void process(ObjectNode payload) {
324 DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
325 PortNumber portNumber = PortNumber.portNumber(payload.get(ID).asLong());
326 String modulation = payload.get(MODULATION).asText();
327 roadmService.setModulation(deviceId, portNumber, modulation);
328 ObjectNode rootNode = objectNode();
329 rootNode.put(ID, payload.get(ID).asText());
330 rootNode.put(RoadmUtil.VALID, modulation);
331 rootNode.put(RoadmUtil.MESSAGE, String.format(TARGET_MODULATION_MSG, modulation));
332 sendMessage(ROADM_SET_MODULATION_RESP, rootNode);
333 }
334 }
335
MaoLu2846b112017-05-15 17:18:55 -0700336 // Protection switch operation type and path index
337 private static final String OPS_ARRAY_INDEX = "index";
338 private static final String OPS_ARRAY_OPERATION = "operation";
339 private static final String[] OPS_NON_AUTO_OPTS = {OPS_OPT_FORCE, OPS_OPT_MANUAL};
340
MaoLu937cf422017-03-03 23:31:46 -0800341 private final class CreateShowItemsRequestHandler extends RequestHandler {
342 private static final String SHOW_TARGET_POWER = "showTargetPower";
343 private static final String SHOW_SERVICE_STATE = "showServiceState";
344 private static final String SHOW_FLOW_ICON = "showFlowIcon";
MaoLu2846b112017-05-15 17:18:55 -0700345 private static final String OPS_PATHS = "opsOperations";
346 private static final String OPS_ARRAY_NAME = "name";
347 private static final String OPS_GROUP_FMT = "GROUP%d ";
MaoLu937cf422017-03-03 23:31:46 -0800348
349 private CreateShowItemsRequestHandler() {
350 super(ROADM_SHOW_ITEMS_REQ);
351 }
352
353 @Override
354 public void process(ObjectNode payload) {
355 DeviceId did = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
356 Type devType = deviceService.getDevice(did).type();
357 // Build response
358 ObjectNode node = objectNode();
MaoLu937cf422017-03-03 23:31:46 -0800359 node.put(SHOW_FLOW_ICON, devType == Type.ROADM);
MaoLu2846b112017-05-15 17:18:55 -0700360 if (devType == Type.FIBER_SWITCH) {
361 node.put(SHOW_TARGET_POWER, false);
362 node.put(SHOW_SERVICE_STATE, true);
363 // add protection switch paths
364 putProtectionSwitchPaths(did, node);
365 } else {
366 node.put(SHOW_TARGET_POWER, true);
367 node.put(SHOW_SERVICE_STATE, false);
368 }
MaoLu937cf422017-03-03 23:31:46 -0800369 sendMessage(ROADM_SHOW_ITEMS_RESP, node);
370 }
MaoLu2846b112017-05-15 17:18:55 -0700371
372 private void putProtectionSwitchPaths(DeviceId deviceId, ObjectNode node) {
373 Map<ConnectPoint, ProtectedTransportEndpointState> states =
374 roadmService.getProtectionSwitchStates(deviceId);
375 ArrayNode nodes = node.putArray(OPS_PATHS);
376 // Add path names for every identifier.
377 int groupIndex = 0;
378 for (ConnectPoint identifier : states.keySet()) {
379 // No group name needed if there is only one connection point identifier.
380 String groupName = states.keySet().size() == 1 ? "" : String.format(OPS_GROUP_FMT, ++groupIndex);
381 // Add AUTOMATIC operation.
382 nodes.add(new ObjectNode(JsonNodeFactory.instance)
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200383 .put(OPS_ARRAY_INDEX, ACTIVE_UNKNOWN)
384 .put(OPS_ARRAY_OPERATION, OPS_OPT_AUTO)
385 .put(OPS_ARRAY_NAME, String.format("%s%s", groupName, OPS_OPT_AUTO)));
MaoLu2846b112017-05-15 17:18:55 -0700386 // Add FORCE and MANUAL operations for every path.
387 for (String opt : OPS_NON_AUTO_OPTS) {
388 int pathIndex = 0;
389 for (TransportEndpointState state : states.get(identifier).pathStates()) {
390 nodes.add(new ObjectNode(JsonNodeFactory.instance)
Andrea Campanellabdeeda12019-08-02 16:12:05 +0200391 .put(OPS_ARRAY_INDEX, pathIndex++)
392 .put(OPS_ARRAY_OPERATION, opt)
393 .put(OPS_ARRAY_NAME,
394 String.format("%s%s %s", groupName, opt, state.id().id().toUpperCase())));
MaoLu2846b112017-05-15 17:18:55 -0700395 }
396 }
397 }
398
399
400 }
MaoLu937cf422017-03-03 23:31:46 -0800401 }
402
403 private final class CreateOpsModeSetRequestHandler extends RequestHandler {
MaoLu937cf422017-03-03 23:31:46 -0800404 private static final String DEVICE_INVALID_ERR_MSG = "Apply failed: device is offline or unavailable.";
405 private static final String TYPE_INVALID_ERR_MSG = "Apply failed: invalid device type.";
406
407 private CreateOpsModeSetRequestHandler() {
408 super(ROADM_SET_OPS_MODE_REQ);
409 }
410
411 @Override
412 public void process(ObjectNode payload) {
413 DeviceId did = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
414 ObjectNode node = objectNode();
415 if (!deviceService.isAvailable(did)) {
416 node.put(RoadmUtil.VALID, false);
417 node.put(RoadmUtil.MESSAGE, DEVICE_INVALID_ERR_MSG);
418 sendMessage(ROADM_SET_OPS_MODE_RESP, node);
419 return;
420 }
421 Type devType = deviceService.getDevice(did).type();
422 if (devType != Type.FIBER_SWITCH) {
423 node.put(RoadmUtil.VALID, false);
424 node.put(RoadmUtil.MESSAGE, TYPE_INVALID_ERR_MSG);
425 sendMessage(ROADM_SET_OPS_MODE_RESP, node);
426 return;
427 }
MaoLu2846b112017-05-15 17:18:55 -0700428 // get switch configuration from payload, and then switch the device.
429 roadmService.configProtectionSwitch(did, string(payload, OPS_ARRAY_OPERATION),
430 roadmService.getProtectionSwitchStates(did).keySet().toArray(new ConnectPoint[0])[0],
431 (int) number(payload, OPS_ARRAY_INDEX));
MaoLu937cf422017-03-03 23:31:46 -0800432 node.put(RoadmUtil.VALID, true);
433 sendMessage(ROADM_SET_OPS_MODE_RESP, node);
Jimmy Yanda878fc2016-09-02 16:32:01 -0700434 }
435 }
436}