diff --git a/apps/roadm/src/main/java/org/onosproject/roadm/RoadmFlowViewMessageHandler.java b/apps/roadm/src/main/java/org/onosproject/roadm/RoadmFlowViewMessageHandler.java
new file mode 100644
index 0000000..08e74f0
--- /dev/null
+++ b/apps/roadm/src/main/java/org/onosproject/roadm/RoadmFlowViewMessageHandler.java
@@ -0,0 +1,421 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.roadm;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Range;
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowId;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.ui.RequestHandler;
+import org.onosproject.ui.UiConnection;
+import org.onosproject.ui.UiMessageHandler;
+import org.onosproject.ui.table.TableModel;
+import org.onosproject.ui.table.TableRequestHandler;
+import org.onosproject.ui.table.cell.HexLongFormatter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Set;
+
+import static org.onosproject.ui.JsonUtils.node;
+import static org.onosproject.ui.JsonUtils.number;
+
+/**
+ * Table-View message handler for ROADM flow view.
+ */
+public class RoadmFlowViewMessageHandler extends UiMessageHandler {
+
+    private static final String ROADM_FLOW_DATA_REQ = "roadmFlowDataRequest";
+    private static final String ROADM_FLOW_DATA_RESP = "roadmFlowDataResponse";
+    private static final String ROADM_FLOWS = "roadmFlows";
+
+    private static final String ROADM_SET_ATTENUATION_REQ = "roadmSetAttenuationRequest";
+    private static final String ROADM_SET_ATTENUATION_RESP = "roadmSetAttenuationResponse";
+
+    private static final String ROADM_DELETE_FLOW_REQ = "roadmDeleteFlowRequest";
+
+    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 ID = "id";
+    private static final String FLOW_ID = "flowId";
+    private static final String APP_ID = "appId";
+    private static final String GROUP_ID = "groupId";
+    private static final String TABLE_ID = "tableId";
+    private static final String PRIORITY = "priority";
+    private static final String PERMANENT = "permanent";
+    private static final String TIMEOUT = "timeout";
+    private static final String STATE = "state";
+    private static final String IN_PORT = "inPort";
+    private static final String OUT_PORT = "outPort";
+    private static final String CHANNEL_SPACING = "spacing";
+    private static final String CHANNEL_MULTIPLIER = "multiplier";
+    private static final String CURRENT_POWER = "currentPower";
+    private static final String ATTENUATION = "attenuation";
+    private static final String HAS_ATTENUATION = "hasAttenuation";
+
+    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
+    };
+
+    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 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);
+    }
+
+    @Override
+    protected Collection<RequestHandler> createRequestHandlers() {
+        return ImmutableSet.of(
+                new FlowTableDataRequestHandler(),
+                new SetAttenuationRequestHandler(),
+                new DeleteConnectionRequestHandler(),
+                new CreateConnectionRequestHandler()
+        );
+    }
+
+    // Handler for sample table requests
+    private final class FlowTableDataRequestHandler extends TableRequestHandler {
+
+        private FlowTableDataRequestHandler() {
+            super(ROADM_FLOW_DATA_REQ, ROADM_FLOW_DATA_RESP, ROADM_FLOWS);
+        }
+
+        @Override
+        protected String[] getColumnIds() {
+            return COLUMN_IDS;
+        }
+
+        @Override
+        protected String noRowsMessage(ObjectNode payload) {
+            return NO_ROWS_MESSAGE;
+        }
+
+        @Override
+        protected TableModel createTableModel() {
+            TableModel tm = super.createTableModel();
+            tm.setFormatter(FLOW_ID, HexLongFormatter.INSTANCE);
+            return tm;
+        }
+
+        @Override
+        protected void populateTable(TableModel tm, ObjectNode payload) {
+            DeviceId deviceId = DeviceId.deviceId(string(payload, DEV_ID, "(none)"));
+
+            Iterable<FlowEntry> flowEntries = flowRuleService.getFlowEntries(deviceId);
+            for (FlowEntry flowEntry : flowEntries) {
+                populateRow(tm.addRow(), flowEntry, deviceId);
+            }
+        }
+
+        private void populateRow(TableModel.Row row, FlowEntry entry, DeviceId deviceId) {
+            ChannelData cd = ChannelData.fromFlow(entry);
+            row.cell(ID, entry.id().value())
+                    .cell(FLOW_ID, entry.id().value())
+                    .cell(APP_ID, entry.appId())
+                    .cell(PRIORITY, entry.priority())
+                    .cell(TIMEOUT, entry.timeout())
+                    .cell(PERMANENT, entry.isPermanent())
+                    .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(CURRENT_POWER, getCurrentPower(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);
+                }
+            }
+            return NA;
+        }
+
+        private String getAttenuation(DeviceId deviceId, ChannelData channelData) {
+            Long attenuation =
+                    roadmService.getAttenuation(deviceId, channelData.outPort(),
+                                                channelData.ochSignal());
+            if (attenuation != null) {
+                return String.valueOf(attenuation);
+            }
+            return UNKNOWN;
+        }
+    }
+
+    // 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 SetAttenuationRequestHandler() {
+            super(ROADM_SET_ATTENUATION_REQ);
+        }
+
+        @Override
+        public void process(ObjectNode payload) {
+            DeviceId deviceId = DeviceId.deviceId(string(payload, DEV_ID, "(none)"));
+            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");
+                return;
+            }
+            ChannelData cd = ChannelData.fromFlow(entry);
+            Range<Long> range =
+                    roadmService.attenuationRange(deviceId, cd.outPort(),
+                                                  cd.ochSignal());
+
+            boolean validAttenuation = (range != null && range.contains(attenuation));
+            if (validAttenuation) {
+                roadmService.setAttenuation(deviceId, cd.outPort(),
+                                            cd.ochSignal(), 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()));
+            } else {
+                rootNode.put(MESSAGE, NO_ATTENUATION_MSG);
+            }
+            sendMessage(ROADM_SET_ATTENUATION_RESP, rootNode);
+        }
+
+        private FlowEntry findFlow(DeviceId deviceId, FlowId flowId) {
+            for (FlowEntry entry : flowRuleService.getFlowEntries(deviceId)) {
+                if (entry.id().equals(flowId)) {
+                    return entry;
+                }
+            }
+            return null;
+        }
+    }
+
+    // Handler for deleting a connection
+    private final class DeleteConnectionRequestHandler extends RequestHandler {
+        private DeleteConnectionRequestHandler() {
+            super(ROADM_DELETE_FLOW_REQ);
+        }
+
+        @Override
+        public void process(ObjectNode payload) {
+            DeviceId deviceId = DeviceId.deviceId(string(payload, DEV_ID, "(none)"));
+            FlowId flowId = FlowId.valueOf(payload.get(ID).asLong());
+            roadmService.removeConnection(deviceId, flowId);
+        }
+    }
+
+    // Handler for creating a creating a connection from form data
+    private final class CreateConnectionRequestHandler extends RequestHandler {
+
+        // 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";
+        private static final String CHANNEL_AVAILABLE = "channelAvailable";
+
+        // 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 CreateConnectionRequestHandler() {
+            super(ROADM_CREATE_FLOW_REQ);
+        }
+
+        @Override
+        public void process(ObjectNode payload) {
+            DeviceId did = DeviceId.deviceId(string(payload, DEV_ID, "(none)"));
+            ObjectNode flowNode = node(payload, FORM_DATA);
+            int priority = (int) number(flowNode, PRIORITY);
+            boolean permanent = bool(flowNode, PERMANENT);
+            int timeout = (int) number(flowNode, TIMEOUT);
+            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));
+            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 validInPort = roadmService.validInputPort(did, inPort);
+            boolean validOutPort = roadmService.validOutputPort(did, outPort);
+            boolean validConnect = roadmService.validConnection(did, inPort, outPort);
+            boolean validSpacing = true;
+            boolean validChannel = roadmService.validChannel(did, inPort, och);
+            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;
+                    } else {
+                        channelMessage = String.format(CHANNEL_ERR_MSG, range.toString());
+                    }
+                }
+            }
+
+            // Construct error for attenuation
+            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());
+                }
+            }
+
+            // 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(ATTENUATION, validationObject(validAttenuation, attenuationMessage));
+            node.put(INCLUDE_ATTENUATION, includeAttenuation);
+
+            sendMessage(ROADM_CREATE_FLOW_RESP, node);
+        }
+
+        // Returns the ChannelSpacing based on the selection made
+        private ChannelSpacing channelSpacing(int selectionIndex) {
+            switch (selectionIndex) {
+                case 0: return ChannelSpacing.CHL_100GHZ;
+                case 1: return ChannelSpacing.CHL_50GHZ;
+                case 2: return ChannelSpacing.CHL_25GHZ;
+                case 3: return ChannelSpacing.CHL_12P5GHZ;
+                // 6.25GHz cannot be used with ChannelSpacing.newDwdmSlot
+                // case 4: return ChannelSpacing.CHL_6P25GHZ;
+                default: return ChannelSpacing.CHL_50GHZ;
+            }
+        }
+
+        // Construct validation object to return to the view
+        private ObjectNode validationObject(boolean result, String message) {
+            ObjectNode node = objectNode();
+            node.put(VALID, result);
+            if (!result) {
+                // return error message to display if validation failed
+                node.put(MESSAGE, message);
+            }
+            return node;
+        }
+
+        // Returns the minimum and maximum channel spacing
+        private Range<Integer> channelRange(Set<OchSignal> signals) {
+            Comparator<OchSignal> compare =
+                    (OchSignal a, OchSignal b) -> a.spacingMultiplier() - b.spacingMultiplier();
+            OchSignal minOch = Collections.min(signals, compare);
+            OchSignal maxOch = Collections.max(signals, compare);
+            return Range.closed(minOch.spacingMultiplier(), maxOch.spacingMultiplier());
+        }
+    }
+}
