Bri Prebilic Cole

GUI -- Base Cluster View implemented. Bug fixed of table bodies not being wide enough.

Change-Id: Iebf43c87c91404eb443ae1a098b56575ca9959fe
...@@ -90,7 +90,8 @@ ...@@ -90,7 +90,8 @@
90 org.onlab.osgi.*, 90 org.onlab.osgi.*,
91 org.onlab.packet.*, 91 org.onlab.packet.*,
92 org.onlab.rest.*, 92 org.onlab.rest.*,
93 - org.onosproject.* 93 + org.onosproject.*,
94 + org.joda.time.*
94 </Import-Package> 95 </Import-Package>
95 <Web-ContextPath>${web.context}</Web-ContextPath> 96 <Web-ContextPath>${web.context}</Web-ContextPath>
96 </instructions> 97 </instructions>
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
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 +
17 +package org.onosproject.ui.impl;
18 +
19 +import com.fasterxml.jackson.databind.node.ArrayNode;
20 +import com.fasterxml.jackson.databind.node.ObjectNode;
21 +import com.google.common.collect.ImmutableSet;
22 +import org.joda.time.DateTime;
23 +import org.joda.time.format.DateTimeFormat;
24 +import org.onosproject.cluster.ClusterService;
25 +import org.onosproject.cluster.ControllerNode;
26 +import org.onosproject.cluster.NodeId;
27 +
28 +import java.util.ArrayList;
29 +import java.util.Arrays;
30 +import java.util.List;
31 +
32 +
33 +/**
34 + * Message handler for cluster view related messages.
35 + */
36 +public class ClusterViewMessageHandler extends AbstractTabularViewMessageHandler {
37 +
38 + /**
39 + * Creates a new message handler for the cluster messages.
40 + */
41 + protected ClusterViewMessageHandler() {
42 + super(ImmutableSet.of("clusterDataRequest"));
43 + }
44 +
45 + @Override
46 + public void process(ObjectNode message) {
47 + ObjectNode payload = payload(message);
48 + String sortCol = string(payload, "sortCol", "id");
49 + String sortDir = string(payload, "sortDir", "asc");
50 +
51 + ClusterService service = get(ClusterService.class);
52 + TableRow[] rows = generateTableRows(service);
53 + RowComparator rc =
54 + new RowComparator(sortCol, RowComparator.direction(sortDir));
55 + Arrays.sort(rows, rc);
56 + ArrayNode clusterNodes = generateArrayNode(rows);
57 + ObjectNode rootNode = mapper.createObjectNode();
58 + rootNode.set("clusters", clusterNodes);
59 +
60 + connection().sendMessage("clusterDataResponse", 0, rootNode);
61 + }
62 +
63 + private TableRow[] generateTableRows(ClusterService service) {
64 + List<TableRow> list = new ArrayList<>();
65 + for (ControllerNode node : service.getNodes()) {
66 + list.add(new ControllerNodeTableRow(service, node));
67 + }
68 + return list.toArray(new TableRow[list.size()]);
69 + }
70 +
71 + /**
72 + * TableRow implementation for {@link ControllerNode controller nodes}.
73 + */
74 + private static class ControllerNodeTableRow extends AbstractTableRow {
75 +
76 + private static final String ID = "id";
77 + private static final String IP = "ip";
78 + private static final String TCP_PORT = "tcp";
79 + private static final String STATE = "state";
80 + private static final String UPDATED = "updated";
81 +
82 + private static final String[] COL_IDS = {
83 + ID, IP, TCP_PORT, STATE, UPDATED
84 + };
85 +
86 + public ControllerNodeTableRow(ClusterService service, ControllerNode n) {
87 + NodeId id = n.id();
88 + DateTime lastUpdated = service.getLastUpdated(id);
89 + org.joda.time.format.DateTimeFormatter format = DateTimeFormat.longTime();
90 +
91 + add(ID, id.toString());
92 + add(IP, n.ip().toString());
93 + add(TCP_PORT, Integer.toString(n.tcpPort()));
94 + add(STATE, service.getState(id).toString());
95 + add(UPDATED, format.print(lastUpdated));
96 + }
97 +
98 + @Override
99 + protected String[] columnIds() {
100 + return COL_IDS;
101 + }
102 + }
103 +
104 +}
...@@ -61,6 +61,7 @@ public class UiExtensionManager implements UiExtensionService { ...@@ -61,6 +61,7 @@ public class UiExtensionManager implements UiExtensionService {
61 new UiView("host", "Hosts"), 61 new UiView("host", "Hosts"),
62 new UiView("app", "Applications"), 62 new UiView("app", "Applications"),
63 new UiView("intent", "Intents"), 63 new UiView("intent", "Intents"),
64 + new UiView("cluster", "Cluster Nodes"),
64 new UiView("sample", "Sample")); 65 new UiView("sample", "Sample"));
65 UiMessageHandlerFactory messageHandlerFactory = 66 UiMessageHandlerFactory messageHandlerFactory =
66 () -> ImmutableList.of( 67 () -> ImmutableList.of(
...@@ -68,7 +69,8 @@ public class UiExtensionManager implements UiExtensionService { ...@@ -68,7 +69,8 @@ public class UiExtensionManager implements UiExtensionService {
68 new DeviceViewMessageHandler(), 69 new DeviceViewMessageHandler(),
69 new HostViewMessageHandler(), 70 new HostViewMessageHandler(),
70 new ApplicationViewMessageHandler(), 71 new ApplicationViewMessageHandler(),
71 - new IntentViewMessageHandler() 72 + new IntentViewMessageHandler(),
73 + new ClusterViewMessageHandler()
72 ); 74 );
73 return new UiExtension(coreViews, messageHandlerFactory, "core", 75 return new UiExtension(coreViews, messageHandlerFactory, "core",
74 UiExtensionManager.class.getClassLoader()); 76 UiExtensionManager.class.getClassLoader());
......
...@@ -4,3 +4,4 @@ ...@@ -4,3 +4,4 @@
4 <link rel="stylesheet" href="app/view/host/host.css"> 4 <link rel="stylesheet" href="app/view/host/host.css">
5 <link rel="stylesheet" href="app/view/app/app.css"> 5 <link rel="stylesheet" href="app/view/app/app.css">
6 <link rel="stylesheet" href="app/view/intent/intent.css"> 6 <link rel="stylesheet" href="app/view/intent/intent.css">
7 +<link rel="stylesheet" href="app/view/cluster/cluster.css">
......
...@@ -15,4 +15,5 @@ ...@@ -15,4 +15,5 @@
15 <script src="app/view/host/host.js"></script> 15 <script src="app/view/host/host.js"></script>
16 <script src="app/view/app/app.js"></script> 16 <script src="app/view/app/app.js"></script>
17 <script src="app/view/intent/intent.js"></script> 17 <script src="app/view/intent/intent.js"></script>
18 +<script src="app/view/cluster/cluster.js"></script>
18 <script src="app/view/sample/sample.js"></script> 19 <script src="app/view/sample/sample.js"></script>
......
...@@ -83,7 +83,8 @@ ...@@ -83,7 +83,8 @@
83 83
84 tHeaders.each(function (d, i) { 84 tHeaders.each(function (d, i) {
85 var thElement = d3.select(this), 85 var thElement = d3.select(this),
86 - tdElement = t.select('td:nth-of-type(' + (i + 1) + ')'), 86 + tr = t.select('tr:nth-of-type(2)'),
87 + tdElement = tr.select('td:nth-of-type(' + (i + 1) + ')'),
87 custWidth = thElement.attr(colWidth); 88 custWidth = thElement.attr(colWidth);
88 89
89 if (custWidth) { 90 if (custWidth) {
...@@ -105,9 +106,10 @@ ...@@ -105,9 +106,10 @@
105 tableHeight = fs.windowSize(mast.mastHeight() + totalHeight).height; 106 tableHeight = fs.windowSize(mast.mastHeight() + totalHeight).height;
106 107
107 thead.style('display', 'block'); 108 thead.style('display', 'block');
108 - tbody.style({'display': 'block', 109 + tbody.style({
109 - 'height': (tableHeight + 'px'), 110 + display: 'block',
110 - 'overflow': 'auto' 111 + height: tableHeight + 'px',
112 + overflow: 'auto'
111 }); 113 });
112 } 114 }
113 115
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
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 +
17 +/*
18 + ONOS GUI -- Cluster View -- CSS file
19 + */
20 +
21 +#ov-cluster td {
22 +}
...\ No newline at end of file ...\ No newline at end of file
1 +<!--
2 + ~ Copyright 2015 Open Networking Laboratory
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 +
17 +<!-- Cluster partial HTML -->
18 +<div id="ov-cluster">
19 + <h2>Cluster Nodes ({{ctrl.tableData.length}} total)</h2>
20 + <table class="summary-list"
21 + onos-fixed-header
22 + onos-sortable-header
23 + sort-callback="sortCallback(requestParams)">
24 + <thead>
25 + <tr>
26 + <th colId="id" sortable>ID </th>
27 + <th colId="ip" sortable>IP Address </th>
28 + <th colId="tcp" sortable>TCP Port </th>
29 + <th colId="state" sortable>State </th>
30 + <th colId="updated" sortable>Last Updated </th>
31 + </tr>
32 + </thead>
33 +
34 + <tbody>
35 + <tr ng-hide="ctrl.tableData.length">
36 + <td class="nodata" colspan="5">
37 + No Cluster Nodes found
38 + </td>
39 + </tr>
40 +
41 + <tr ng-repeat="node in ctrl.tableData"
42 + ng-repeat-done>
43 + <td>{{node.id}}</td>
44 + <td>{{node.ip}}</td>
45 + <td>{{node.tcp}}</td>
46 + <td>{{node.state}}</td>
47 + <td>{{node.updated}}</td>
48 + </tr>
49 + </tbody>
50 + </table>
51 +
52 +</div>
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
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 +
17 +/*
18 + ONOS GUI -- Cluster View Module
19 + */
20 +
21 +(function () {
22 + 'use strict';
23 +
24 + angular.module('ovCluster', [])
25 + .controller('OvClusterCtrl',
26 + ['$log', '$scope', 'TableBuilderService',
27 +
28 + function ($log, $scope, tbs) {
29 + tbs.buildTable({
30 + self: this,
31 + scope: $scope,
32 + tag: 'cluster'
33 + });
34 +
35 + $log.log('OvClusterCtrl has been created');
36 + }]);
37 +}());
...@@ -18,24 +18,24 @@ ...@@ -18,24 +18,24 @@
18 ONOS GUI -- Intent View -- CSS file 18 ONOS GUI -- Intent View -- CSS file
19 */ 19 */
20 20
21 -.light #ov-intent tr:nth-child(6n + 1),
22 .light #ov-intent tr:nth-child(6n + 2), 21 .light #ov-intent tr:nth-child(6n + 2),
23 -.light #ov-intent tr:nth-child(6n + 3) { 22 +.light #ov-intent tr:nth-child(6n + 3),
23 +.light #ov-intent tr:nth-child(6n + 4) {
24 background-color: #eee; 24 background-color: #eee;
25 } 25 }
26 -.light #ov-intent tr:nth-child(6n + 4),
27 .light #ov-intent tr:nth-child(6n + 5), 26 .light #ov-intent tr:nth-child(6n + 5),
28 -.light #ov-intent tr:nth-child(6n) { 27 +.light #ov-intent tr:nth-child(6n + 6),
28 +.light #ov-intent tr:nth-child(6n + 1) {
29 background-color: #ddd; 29 background-color: #ddd;
30 } 30 }
31 -.dark #ov-intent tr:nth-child(6n + 1),
32 .dark #ov-intent tr:nth-child(6n + 2), 31 .dark #ov-intent tr:nth-child(6n + 2),
33 -.dark #ov-intent tr:nth-child(6n + 3) { 32 +.dark #ov-intent tr:nth-child(6n + 3),
33 +.dark #ov-intent tr:nth-child(6n + 4) {
34 background-color: #444; 34 background-color: #444;
35 } 35 }
36 -.dark #ov-intent tr:nth-child(6n + 4),
37 .dark #ov-intent tr:nth-child(6n + 5), 36 .dark #ov-intent tr:nth-child(6n + 5),
38 -.dark #ov-intent tr:nth-child(6n) { 37 +.dark #ov-intent tr:nth-child(6n + 6),
38 +.dark #ov-intent tr:nth-child(6n + 1) {
39 background-color: #333; 39 background-color: #333;
40 } 40 }
41 41
......
...@@ -113,6 +113,7 @@ ...@@ -113,6 +113,7 @@
113 <script src="app/view/host/host.js"></script> 113 <script src="app/view/host/host.js"></script>
114 <script src="app/view/app/app.js"></script> 114 <script src="app/view/app/app.js"></script>
115 <script src="app/view/intent/intent.js"></script> 115 <script src="app/view/intent/intent.js"></script>
116 + <script src="app/view/cluster/cluster.js"></script>
116 <script src="app/view/sample/sample.js"></script> 117 <script src="app/view/sample/sample.js"></script>
117 <!-- {INJECTED-JAVASCRIPT-END} --> 118 <!-- {INJECTED-JAVASCRIPT-END} -->
118 119
...@@ -124,6 +125,7 @@ ...@@ -124,6 +125,7 @@
124 <link rel="stylesheet" href="app/view/host/host.css"> 125 <link rel="stylesheet" href="app/view/host/host.css">
125 <link rel="stylesheet" href="app/view/app/app.css"> 126 <link rel="stylesheet" href="app/view/app/app.css">
126 <link rel="stylesheet" href="app/view/intent/intent.css"> 127 <link rel="stylesheet" href="app/view/intent/intent.css">
128 + <link rel="stylesheet" href="app/view/cluster/cluster.css">
127 <link rel="stylesheet" href="app/view/sample/sample.css"> 129 <link rel="stylesheet" href="app/view/sample/sample.css">
128 <!-- {INJECTED-STYLESHEETS-END} --> 130 <!-- {INJECTED-STYLESHEETS-END} -->
129 131
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
41 'host', 41 'host',
42 'app', 42 'app',
43 'intent', 43 'intent',
44 + 'cluster',
44 'sample', 45 'sample',
45 // {INJECTED-VIEW-IDS-END} 46 // {INJECTED-VIEW-IDS-END}
46 47
......