change roadm app to support EDFA/ROADM/OPS devices, add OPS PowerConfig/LambdaQuery behaviour
Change-Id: Ieb6de727e766fdeb63740c0704f83fd11e44b935
diff --git a/apps/roadm/src/main/java/org/onosproject/roadm/RoadmFlowViewMessageHandler.java b/apps/roadm/src/main/java/org/onosproject/roadm/RoadmFlowViewMessageHandler.java
index 08e74f0..d0012d6 100644
--- a/apps/roadm/src/main/java/org/onosproject/roadm/RoadmFlowViewMessageHandler.java
+++ b/apps/roadm/src/main/java/org/onosproject/roadm/RoadmFlowViewMessageHandler.java
@@ -19,8 +19,11 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Range;
import org.onlab.osgi.ServiceDirectory;
+import org.onlab.util.Frequency;
+import org.onlab.util.Spectrum;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
import org.onosproject.net.OchSignal;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.FlowEntry;
@@ -42,6 +45,7 @@
import static org.onosproject.ui.JsonUtils.node;
import static org.onosproject.ui.JsonUtils.number;
+import static org.onosproject.net.Device.Type;
/**
* Table-View message handler for ROADM flow view.
@@ -60,9 +64,8 @@
private static final String ROADM_CREATE_FLOW_REQ = "roadmCreateFlowRequest";
private static final String ROADM_CREATE_FLOW_RESP = "roadmCreateFlowResponse";
- private static final String NO_ROWS_MESSAGE = "No items found";
-
- private static final String DEV_ID = "devId";
+ private static final String ROADM_SHOW_ITEMS_REQ = "roadmShowFlowItemsRequest";
+ private static final String ROADM_SHOW_ITEMS_RESP = "roadmShowFlowItemsResponse";
private static final String ID = "id";
private static final String FLOW_ID = "flowId";
@@ -80,28 +83,26 @@
private static final String CURRENT_POWER = "currentPower";
private static final String ATTENUATION = "attenuation";
private static final String HAS_ATTENUATION = "hasAttenuation";
+ private static final String CHANNEL_FREQUENCY = "channelFrequency";
private static final String[] COLUMN_IDS = {
ID, FLOW_ID, APP_ID, GROUP_ID, TABLE_ID, PRIORITY, TIMEOUT,
- PERMANENT, STATE, IN_PORT, OUT_PORT, CHANNEL_SPACING,
- CHANNEL_MULTIPLIER, CURRENT_POWER, ATTENUATION, HAS_ATTENUATION
+ PERMANENT, STATE, IN_PORT, OUT_PORT, CHANNEL_SPACING, CHANNEL_MULTIPLIER,
+ CHANNEL_FREQUENCY, CURRENT_POWER, ATTENUATION, HAS_ATTENUATION
};
- private static final String NA = "N/A";
- private static final String UNKNOWN = "Unknown";
-
- private static final long GHZ = 1_000_000_000L;
-
- private FlowRuleService flowRuleService;
private RoadmService roadmService;
+ private DeviceService deviceService;
+ private FlowRuleService flowRuleService;
private final Logger log = LoggerFactory.getLogger(getClass());
@Override
public void init(UiConnection connection, ServiceDirectory directory) {
super.init(connection, directory);
- flowRuleService = get(FlowRuleService.class);
roadmService = get(RoadmService.class);
+ deviceService = get(DeviceService.class);
+ flowRuleService = get(FlowRuleService.class);
}
@Override
@@ -110,7 +111,8 @@
new FlowTableDataRequestHandler(),
new SetAttenuationRequestHandler(),
new DeleteConnectionRequestHandler(),
- new CreateConnectionRequestHandler()
+ new CreateConnectionRequestHandler(),
+ new CreateShowItemsRequestHandler()
);
}
@@ -128,7 +130,7 @@
@Override
protected String noRowsMessage(ObjectNode payload) {
- return NO_ROWS_MESSAGE;
+ return RoadmUtil.NO_ROWS_MESSAGE;
}
@Override
@@ -140,8 +142,8 @@
@Override
protected void populateTable(TableModel tm, ObjectNode payload) {
- DeviceId deviceId = DeviceId.deviceId(string(payload, DEV_ID, "(none)"));
-
+ DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
+ // Update flows
Iterable<FlowEntry> flowEntries = flowRuleService.getFlowEntries(deviceId);
for (FlowEntry flowEntry : flowEntries) {
populateRow(tm.addRow(), flowEntry, deviceId);
@@ -150,6 +152,17 @@
private void populateRow(TableModel.Row row, FlowEntry entry, DeviceId deviceId) {
ChannelData cd = ChannelData.fromFlow(entry);
+ String spacing = RoadmUtil.NA, multiplier = RoadmUtil.NA, channelFrequency = "";
+ OchSignal ochSignal = cd.ochSignal();
+ if (ochSignal != null) {
+ Frequency spacingFreq = ochSignal.channelSpacing().frequency();
+ spacing = RoadmUtil.asGHz(spacingFreq);
+ int spacingMult = ochSignal.spacingMultiplier();
+ multiplier = String.valueOf(spacingMult);
+ channelFrequency = String.format(" (%sGHz)",
+ RoadmUtil.asGHz(Spectrum.CENTER_FREQUENCY.add(spacingFreq.multiply(spacingMult))));
+ }
+
row.cell(ID, entry.id().value())
.cell(FLOW_ID, entry.id().value())
.cell(APP_ID, entry.appId())
@@ -159,52 +172,52 @@
.cell(STATE, entry.state().toString())
.cell(IN_PORT, cd.inPort().toLong())
.cell(OUT_PORT, cd.outPort().toLong())
- .cell(CHANNEL_SPACING, cd.ochSignal().channelSpacing().frequency().asHz() / GHZ)
- .cell(CHANNEL_MULTIPLIER, cd.ochSignal().spacingMultiplier())
+ .cell(CHANNEL_SPACING, spacing)
+ .cell(CHANNEL_MULTIPLIER, multiplier)
+ .cell(CHANNEL_FREQUENCY, channelFrequency)
.cell(CURRENT_POWER, getCurrentPower(deviceId, cd))
+ .cell(HAS_ATTENUATION, hasAttenuation(deviceId, cd))
.cell(ATTENUATION, getAttenuation(deviceId, cd));
}
private String getCurrentPower(DeviceId deviceId, ChannelData channelData) {
- Range<Long> range =
- roadmService.attenuationRange(deviceId,
- channelData.outPort(),
- channelData.ochSignal());
- if (range != null) {
- Long currentPower =
- roadmService.getCurrentChannelPower(deviceId,
- channelData.outPort(),
- channelData.ochSignal());
- if (currentPower != null) {
- return String.valueOf(currentPower);
- }
+ if (hasAttenuation(deviceId, channelData)) {
+ // report channel power if channel exists
+ Long currentPower = roadmService.getCurrentChannelPower(deviceId,
+ channelData.outPort(), channelData.ochSignal());
+ return RoadmUtil.objectToString(currentPower, RoadmUtil.UNKNOWN);
}
- return NA;
+ // otherwise, report port power
+ Type devType = deviceService.getDevice(deviceId).type();
+ PortNumber port = devType == Type.FIBER_SWITCH ? channelData.inPort() : channelData.outPort();
+ Long currentPower = roadmService.getCurrentPortPower(deviceId, port);
+ return RoadmUtil.objectToString(currentPower, RoadmUtil.UNKNOWN);
}
private String getAttenuation(DeviceId deviceId, ChannelData channelData) {
- Long attenuation =
- roadmService.getAttenuation(deviceId, channelData.outPort(),
- channelData.ochSignal());
- if (attenuation != null) {
- return String.valueOf(attenuation);
+ OchSignal signal = channelData.ochSignal();
+ if (signal == null) {
+ return RoadmUtil.NA;
}
- return UNKNOWN;
+ Long attenuation = roadmService.getAttenuation(deviceId, channelData.outPort(), signal);
+ return RoadmUtil.objectToString(attenuation, RoadmUtil.UNKNOWN);
+ }
+
+ private boolean hasAttenuation(DeviceId deviceId, ChannelData channelData) {
+ OchSignal signal = channelData.ochSignal();
+ if (signal == null) {
+ return false;
+ }
+ return roadmService.attenuationRange(deviceId, channelData.outPort(), signal) != null;
}
}
// Handler for setting attenuation
private final class SetAttenuationRequestHandler extends RequestHandler {
- // Keys for response message
- private static final String VALID = "valid";
- private static final String MESSAGE = "message";
-
// Error messages to display to user
- private static final String ATTENUATION_RANGE_MSG =
- "Attenuation must be in range %s.";
- private static final String NO_ATTENUATION_MSG =
- "Cannot set attenuation for this connection";
+ private static final String ATTENUATION_RANGE_MSG = "Attenuation must be in range %s.";
+ private static final String NO_ATTENUATION_MSG = "Cannot set attenuation for this connection";
private SetAttenuationRequestHandler() {
super(ROADM_SET_ATTENUATION_REQ);
@@ -212,36 +225,31 @@
@Override
public void process(ObjectNode payload) {
- DeviceId deviceId = DeviceId.deviceId(string(payload, DEV_ID, "(none)"));
+ DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
FlowId flowId = FlowId.valueOf(number(payload, FLOW_ID));
- long attenuation = payload.get(ATTENUATION).asLong();
-
// Get connection information from the flow
FlowEntry entry = findFlow(deviceId, flowId);
if (entry == null) {
- log.error("Unable to find flow rule to set attenuation");
+ log.error("Unable to find flow rule to set attenuation for device {}", deviceId);
return;
}
- ChannelData cd = ChannelData.fromFlow(entry);
- Range<Long> range =
- roadmService.attenuationRange(deviceId, cd.outPort(),
- cd.ochSignal());
-
- boolean validAttenuation = (range != null && range.contains(attenuation));
+ ChannelData channelData = ChannelData.fromFlow(entry);
+ PortNumber port = channelData.outPort();
+ OchSignal signal = channelData.ochSignal();
+ Range<Long> range = roadmService.attenuationRange(deviceId, port, signal);
+ Long attenuation = payload.get(ATTENUATION).asLong();
+ boolean validAttenuation = range != null && range.contains(attenuation);
if (validAttenuation) {
- roadmService.setAttenuation(deviceId, cd.outPort(),
- cd.ochSignal(), attenuation);
+ roadmService.setAttenuation(deviceId, port, signal, attenuation);
}
-
ObjectNode rootNode = objectNode();
// Send back flowId so view can identify which callback function to use
rootNode.put(FLOW_ID, payload.get(FLOW_ID).asText());
- rootNode.put(VALID, validAttenuation);
- if (range != null) {
- rootNode.put(MESSAGE, String.format(ATTENUATION_RANGE_MSG,
- range.toString()));
+ rootNode.put(RoadmUtil.VALID, validAttenuation);
+ if (range == null) {
+ rootNode.put(RoadmUtil.MESSAGE, NO_ATTENUATION_MSG);
} else {
- rootNode.put(MESSAGE, NO_ATTENUATION_MSG);
+ rootNode.put(RoadmUtil.MESSAGE, String.format(ATTENUATION_RANGE_MSG, range.toString()));
}
sendMessage(ROADM_SET_ATTENUATION_RESP, rootNode);
}
@@ -264,7 +272,7 @@
@Override
public void process(ObjectNode payload) {
- DeviceId deviceId = DeviceId.deviceId(string(payload, DEV_ID, "(none)"));
+ DeviceId deviceId = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
FlowId flowId = FlowId.valueOf(payload.get(ID).asLong());
roadmService.removeConnection(deviceId, flowId);
}
@@ -276,7 +284,6 @@
// Keys to load from JSON
private static final String FORM_DATA = "formData";
private static final String CHANNEL_SPACING_INDEX = "index";
- private static final String INCLUDE_ATTENUATION = "includeAttenuation";
// Keys for validation results
private static final String CONNECTION = "connection";
@@ -285,20 +292,11 @@
// Error messages to display to user
private static final String IN_PORT_ERR_MSG = "Invalid input port.";
private static final String OUT_PORT_ERR_MSG = "Invalid output port.";
- private static final String CONNECTION_ERR_MSG =
- "Invalid connection from input port to output port.";
- private static final String CHANNEL_SPACING_ERR_MSG =
- "Channel spacing not supported.";
- private static final String CHANNEL_ERR_MSG =
- "Channel index must be in range %s.";
- private static final String CHANNEL_AVAILABLE_ERR_MSG =
- "Channel is already being used.";
- private static final String ATTENUATION_ERR_MSG =
- "Attenuation must be in range %s.";
-
- // Keys for validation object
- private static final String VALID = "valid";
- private static final String MESSAGE = "message";
+ private static final String CONNECTION_ERR_MSG = "Invalid connection from input port to output port.";
+ private static final String CHANNEL_SPACING_ERR_MSG = "Channel spacing not supported.";
+ private static final String CHANNEL_ERR_MSG = "Channel index must be in range %s.";
+ private static final String CHANNEL_AVAILABLE_ERR_MSG = "Channel is already being used.";
+ private static final String ATTENUATION_ERR_MSG = "Attenuation must be in range %s.";
private CreateConnectionRequestHandler() {
super(ROADM_CREATE_FLOW_REQ);
@@ -306,7 +304,7 @@
@Override
public void process(ObjectNode payload) {
- DeviceId did = DeviceId.deviceId(string(payload, DEV_ID, "(none)"));
+ DeviceId did = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
ObjectNode flowNode = node(payload, FORM_DATA);
int priority = (int) number(flowNode, PRIORITY);
boolean permanent = bool(flowNode, PERMANENT);
@@ -314,13 +312,12 @@
PortNumber inPort = PortNumber.portNumber(number(flowNode, IN_PORT));
PortNumber outPort = PortNumber.portNumber(number(flowNode, OUT_PORT));
ObjectNode chNode = node(flowNode, CHANNEL_SPACING);
- ChannelSpacing spacing =
- channelSpacing((int) number(chNode, CHANNEL_SPACING_INDEX));
+ ChannelSpacing spacing = channelSpacing((int) number(chNode, CHANNEL_SPACING_INDEX));
int multiplier = (int) number(flowNode, CHANNEL_MULTIPLIER);
OchSignal och = OchSignal.newDwdmSlot(spacing, multiplier);
- boolean includeAttenuation = bool(flowNode, INCLUDE_ATTENUATION);
long att = number(flowNode, ATTENUATION);
+ boolean showItems = deviceService.getDevice(did).type() != Type.FIBER_SWITCH;
boolean validInPort = roadmService.validInputPort(did, inPort);
boolean validOutPort = roadmService.validOutputPort(did, outPort);
boolean validConnect = roadmService.validConnection(did, inPort, outPort);
@@ -329,59 +326,51 @@
boolean channelAvailable = roadmService.channelAvailable(did, och);
boolean validAttenuation = roadmService.attenuationInRange(did, outPort, att);
- if (validConnect && validChannel && channelAvailable) {
- if (includeAttenuation && validAttenuation) {
- roadmService.createConnection(did, priority, permanent,
- timeout, inPort, outPort,
- och, att);
- } else if (!includeAttenuation) {
- roadmService.createConnection(did, priority, permanent,
- timeout, inPort, outPort,
- och);
- }
- }
-
- // Construct error for channel
- String channelMessage = "Invalid channel";
- if (!validChannel) {
- Set<OchSignal> lambdas = roadmService.queryLambdas(did, outPort);
- if (lambdas != null) {
- Range<Integer> range = channelRange(lambdas);
- if (range.contains(och.spacingMultiplier())) {
- // Channel spacing error
- validSpacing = false;
+ if (validConnect) {
+ if (validChannel && channelAvailable) {
+ if (validAttenuation) {
+ roadmService.createConnection(did, priority, permanent, timeout, inPort, outPort, och, att);
} else {
- channelMessage = String.format(CHANNEL_ERR_MSG, range.toString());
+ roadmService.createConnection(did, priority, permanent, timeout, inPort, outPort, och);
}
}
}
- // Construct error for attenuation
+ String channelMessage = "Invalid channel";
String attenuationMessage = "Invalid attenuation";
- if (!validAttenuation) {
- Range<Long> range =
- roadmService.attenuationRange(did, outPort, och);
- if (range != null) {
- attenuationMessage =
- String.format(ATTENUATION_ERR_MSG, range.toString());
+ if (showItems) {
+ // Construct error for channel
+ if (!validChannel) {
+ Set<OchSignal> lambdas = roadmService.queryLambdas(did, outPort);
+ if (lambdas != null) {
+ Range<Integer> range = channelRange(lambdas);
+ if (range.contains(och.spacingMultiplier())) {
+ // Channel spacing error
+ validSpacing = false;
+ } else {
+ channelMessage = String.format(CHANNEL_ERR_MSG, range.toString());
+ }
+ }
+ }
+
+ // Construct error for attenuation
+ if (!validAttenuation) {
+ Range<Long> range = roadmService.attenuationRange(did, outPort, och);
+ if (range != null) {
+ attenuationMessage = String.format(ATTENUATION_ERR_MSG, range.toString());
+ }
}
}
// Build response
ObjectNode node = objectNode();
-
node.set(IN_PORT, validationObject(validInPort, IN_PORT_ERR_MSG));
node.set(OUT_PORT, validationObject(validOutPort, OUT_PORT_ERR_MSG));
node.set(CONNECTION, validationObject(validConnect, CONNECTION_ERR_MSG));
- node.set(CHANNEL_SPACING, validationObject(validChannel || validSpacing,
- CHANNEL_SPACING_ERR_MSG));
- node.set(CHANNEL_MULTIPLIER, validationObject(validChannel || !validSpacing,
- channelMessage));
- node.set(CHANNEL_AVAILABLE, validationObject(!validChannel || channelAvailable,
- CHANNEL_AVAILABLE_ERR_MSG));
+ node.set(CHANNEL_SPACING, validationObject(validChannel || validSpacing, CHANNEL_SPACING_ERR_MSG));
+ node.set(CHANNEL_MULTIPLIER, validationObject(validChannel || !validSpacing, channelMessage));
+ node.set(CHANNEL_AVAILABLE, validationObject(!validChannel || channelAvailable, CHANNEL_AVAILABLE_ERR_MSG));
node.set(ATTENUATION, validationObject(validAttenuation, attenuationMessage));
- node.put(INCLUDE_ATTENUATION, includeAttenuation);
-
sendMessage(ROADM_CREATE_FLOW_RESP, node);
}
@@ -401,10 +390,10 @@
// Construct validation object to return to the view
private ObjectNode validationObject(boolean result, String message) {
ObjectNode node = objectNode();
- node.put(VALID, result);
+ node.put(RoadmUtil.VALID, result);
if (!result) {
// return error message to display if validation failed
- node.put(MESSAGE, message);
+ node.put(RoadmUtil.MESSAGE, message);
}
return node;
}
@@ -418,4 +407,23 @@
return Range.closed(minOch.spacingMultiplier(), maxOch.spacingMultiplier());
}
}
+
+ private final class CreateShowItemsRequestHandler extends RequestHandler {
+ private static final String SHOW_CHANNEL = "showChannel";
+ private static final String SHOW_ATTENUATION = "showAttenuation";
+ private CreateShowItemsRequestHandler() {
+ super(ROADM_SHOW_ITEMS_REQ);
+ }
+
+ @Override
+ public void process(ObjectNode payload) {
+ DeviceId did = DeviceId.deviceId(string(payload, RoadmUtil.DEV_ID));
+ Type devType = deviceService.getDevice(did).type();
+ // Build response
+ ObjectNode node = objectNode();
+ node.put(SHOW_CHANNEL, devType != Type.FIBER_SWITCH);
+ node.put(SHOW_ATTENUATION, devType == Type.ROADM);
+ sendMessage(ROADM_SHOW_ITEMS_RESP, node);
+ }
+ }
}