ONOS-1281, ONOS-1747 - GUI -- Flows table created; version updated.
Change-Id: I06477793d6a1943ed90825f5103c8f6f4e962b70
Showing
12 changed files
with
333 additions
and
20 deletions
... | @@ -92,7 +92,8 @@ | ... | @@ -92,7 +92,8 @@ |
92 | org.onlab.packet.*, | 92 | org.onlab.packet.*, |
93 | org.onlab.rest.*, | 93 | org.onlab.rest.*, |
94 | org.onosproject.*, | 94 | org.onosproject.*, |
95 | - org.joda.time.* | 95 | + org.joda.time.*, |
96 | + org.apache.commons.* | ||
96 | </Import-Package> | 97 | </Import-Package> |
97 | <Web-ContextPath>${web.context}</Web-ContextPath> | 98 | <Web-ContextPath>${web.context}</Web-ContextPath> |
98 | </instructions> | 99 | </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.apache.commons.lang.WordUtils; | ||
23 | +import org.onosproject.net.DeviceId; | ||
24 | +import org.onosproject.net.flow.FlowEntry; | ||
25 | +import org.onosproject.net.flow.FlowRuleService; | ||
26 | +import org.onosproject.net.flow.TrafficSelector; | ||
27 | +import org.onosproject.net.flow.TrafficTreatment; | ||
28 | +import org.onosproject.net.flow.criteria.Criterion; | ||
29 | +import org.onosproject.net.flow.instructions.Instruction; | ||
30 | + | ||
31 | +import java.util.ArrayList; | ||
32 | +import java.util.Arrays; | ||
33 | +import java.util.List; | ||
34 | +import java.util.Set; | ||
35 | + | ||
36 | + | ||
37 | +/** | ||
38 | + * Message handler for flow view related messages. | ||
39 | + */ | ||
40 | +public class FlowViewMessageHandler extends AbstractTabularViewMessageHandler { | ||
41 | + | ||
42 | + private static final String NO_DEV = "none"; | ||
43 | + | ||
44 | + /** | ||
45 | + * Creates a new message handler for the flow messages. | ||
46 | + */ | ||
47 | + protected FlowViewMessageHandler() { | ||
48 | + super(ImmutableSet.of("flowDataRequest")); | ||
49 | + } | ||
50 | + | ||
51 | + @Override | ||
52 | + public void process(ObjectNode message) { | ||
53 | + ObjectNode payload = payload(message); | ||
54 | + String uri = string(payload, "devId", NO_DEV); | ||
55 | + String sortCol = string(payload, "sortCol", "id"); | ||
56 | + String sortDir = string(payload, "sortDir", "asc"); | ||
57 | + | ||
58 | + ObjectNode rootNode; | ||
59 | + if (uri.equals(NO_DEV)) { | ||
60 | + rootNode = mapper.createObjectNode(); | ||
61 | + rootNode.set("flows", mapper.createArrayNode()); | ||
62 | + } else { | ||
63 | + DeviceId deviceId = DeviceId.deviceId(uri); | ||
64 | + | ||
65 | + FlowRuleService service = get(FlowRuleService.class); | ||
66 | + TableRow[] rows = generateTableRows(service, deviceId); | ||
67 | + RowComparator rc = | ||
68 | + new RowComparator(sortCol, RowComparator.direction(sortDir)); | ||
69 | + Arrays.sort(rows, rc); | ||
70 | + ArrayNode flows = generateArrayNode(rows); | ||
71 | + | ||
72 | + rootNode = mapper.createObjectNode(); | ||
73 | + rootNode.set("flows", flows); | ||
74 | + } | ||
75 | + | ||
76 | + connection().sendMessage("flowDataResponse", 0, rootNode); | ||
77 | + } | ||
78 | + | ||
79 | + private TableRow[] generateTableRows(FlowRuleService service, | ||
80 | + DeviceId deviceId) { | ||
81 | + List<TableRow> list = new ArrayList<>(); | ||
82 | + for (FlowEntry flow : service.getFlowEntries(deviceId)) { | ||
83 | + list.add(new FlowTableRow(flow)); | ||
84 | + } | ||
85 | + return list.toArray(new TableRow[list.size()]); | ||
86 | + } | ||
87 | + | ||
88 | + /** | ||
89 | + * TableRow implementation for {@link org.onosproject.net.flow.FlowRule flows}. | ||
90 | + */ | ||
91 | + private static class FlowTableRow extends AbstractTableRow { | ||
92 | + | ||
93 | + private static final String ID = "id"; | ||
94 | + private static final String APP_ID = "appId"; | ||
95 | + private static final String GROUP_ID = "groupId"; | ||
96 | + private static final String TABLE_ID = "tableId"; | ||
97 | + private static final String PRIORITY = "priority"; | ||
98 | + private static final String SELECTOR = "selector"; | ||
99 | + private static final String TREATMENT = "treatment"; | ||
100 | + private static final String TIMEOUT = "timeout"; | ||
101 | + private static final String PERMANENT = "permanent"; | ||
102 | + private static final String STATE = "state"; | ||
103 | + | ||
104 | + private static final String COMMA = ", "; | ||
105 | + | ||
106 | + private static final String[] COL_IDS = { | ||
107 | + ID, APP_ID, GROUP_ID, TABLE_ID, PRIORITY, SELECTOR, | ||
108 | + TREATMENT, TIMEOUT, PERMANENT, STATE | ||
109 | + }; | ||
110 | + | ||
111 | + public FlowTableRow(FlowEntry f) { | ||
112 | + add(ID, Long.toString(f.id().value())); | ||
113 | + add(APP_ID, Short.toString(f.appId())); | ||
114 | + add(GROUP_ID, Integer.toString(f.groupId().id())); | ||
115 | + add(TABLE_ID, Integer.toString(f.tableId())); | ||
116 | + add(PRIORITY, Integer.toString(f.priority())); | ||
117 | + add(SELECTOR, getSelectorString(f)); | ||
118 | + add(TREATMENT, getTreatmentString(f)); | ||
119 | + add(TIMEOUT, Integer.toString(f.timeout())); | ||
120 | + add(PERMANENT, Boolean.toString(f.isPermanent())); | ||
121 | + add(STATE, WordUtils.capitalizeFully(f.state().toString())); | ||
122 | + } | ||
123 | + | ||
124 | + private String getSelectorString(FlowEntry f) { | ||
125 | + String result; | ||
126 | + TrafficSelector selector = f.selector(); | ||
127 | + Set<Criterion> criteria = selector.criteria(); | ||
128 | + | ||
129 | + if (criteria.isEmpty()) { | ||
130 | + result = "(No traffic selectors for this flow)"; | ||
131 | + } else { | ||
132 | + StringBuilder sb = new StringBuilder("Criteria = "); | ||
133 | + for (Criterion c : criteria) { | ||
134 | + sb.append(WordUtils.capitalizeFully(c.type().toString())) | ||
135 | + .append(COMMA); | ||
136 | + } | ||
137 | + result = removeTrailingComma(sb).toString(); | ||
138 | + } | ||
139 | + return result; | ||
140 | + } | ||
141 | + | ||
142 | + private String getTreatmentString(FlowEntry f) { | ||
143 | + TrafficTreatment treatment = f.treatment(); | ||
144 | + List<Instruction> deferred = treatment.deferred(); | ||
145 | + List<Instruction> immediate = treatment.immediate(); | ||
146 | + boolean haveDef = !deferred.isEmpty(); | ||
147 | + boolean haveImm = !immediate.isEmpty(); | ||
148 | + boolean both = haveDef && haveImm; | ||
149 | + boolean neither = !haveDef && !haveImm; | ||
150 | + String result; | ||
151 | + | ||
152 | + if (neither) { | ||
153 | + result = "(No traffic treatment instructions for this flow)"; | ||
154 | + } else { | ||
155 | + StringBuilder sb = new StringBuilder(); | ||
156 | + addDeferred(sb, deferred); | ||
157 | + if (both) { | ||
158 | + sb.append(COMMA); | ||
159 | + } | ||
160 | + addImmediate(sb, immediate); | ||
161 | + result = sb.toString(); | ||
162 | + } | ||
163 | + return result; | ||
164 | + } | ||
165 | + | ||
166 | + private void addDeferred(StringBuilder sb, List<Instruction> deferred) { | ||
167 | + if (!deferred.isEmpty()) { | ||
168 | + sb.append("Deferred instructions = "); | ||
169 | + for (Instruction i : deferred) { | ||
170 | + sb.append(WordUtils.capitalizeFully(i.type().toString())) | ||
171 | + .append(COMMA); | ||
172 | + } | ||
173 | + removeTrailingComma(sb); | ||
174 | + } | ||
175 | + } | ||
176 | + | ||
177 | + private void addImmediate(StringBuilder sb, List<Instruction> immediate) { | ||
178 | + if (!immediate.isEmpty()) { | ||
179 | + sb.append("Immediate instructions = "); | ||
180 | + for (Instruction i : immediate) { | ||
181 | + sb.append(WordUtils.capitalizeFully(i.type().toString())) | ||
182 | + .append(COMMA); | ||
183 | + } | ||
184 | + removeTrailingComma(sb); | ||
185 | + } | ||
186 | + } | ||
187 | + | ||
188 | + private StringBuilder removeTrailingComma(StringBuilder sb) { | ||
189 | + int pos = sb.lastIndexOf(COMMA); | ||
190 | + sb.delete(pos, sb.length()); | ||
191 | + return sb; | ||
192 | + } | ||
193 | + | ||
194 | + | ||
195 | + @Override | ||
196 | + protected String[] columnIds() { | ||
197 | + return COL_IDS; | ||
198 | + } | ||
199 | + } | ||
200 | + | ||
201 | +} |
... | @@ -79,6 +79,7 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { | ... | @@ -79,6 +79,7 @@ public class UiExtensionManager implements UiExtensionService, SpriteService { |
79 | new DeviceViewMessageHandler(), | 79 | new DeviceViewMessageHandler(), |
80 | new LinkViewMessageHandler(), | 80 | new LinkViewMessageHandler(), |
81 | new HostViewMessageHandler(), | 81 | new HostViewMessageHandler(), |
82 | + new FlowViewMessageHandler(), | ||
82 | new IntentViewMessageHandler(), | 83 | new IntentViewMessageHandler(), |
83 | new ApplicationViewMessageHandler(), | 84 | new ApplicationViewMessageHandler(), |
84 | new ClusterViewMessageHandler() | 85 | new ClusterViewMessageHandler() | ... | ... |
... | @@ -114,6 +114,24 @@ | ... | @@ -114,6 +114,24 @@ |
114 | "-2,4.1-2.9,7-2.9c2.9,0,5.1,0.9,6.9,2.9c5,5.4,5.6,17.1,5.4,22.6" + | 114 | "-2,4.1-2.9,7-2.9c2.9,0,5.1,0.9,6.9,2.9c5,5.4,5.6,17.1,5.4,22.6" + |
115 | "h-25C42.3,43.1,43.1,31.5,48.1,26.1z", | 115 | "h-25C42.3,43.1,43.1,31.5,48.1,26.1z", |
116 | 116 | ||
117 | + flowTable: 'M15.9,19.1h-8v-13h8V19.1z M90.5,6.1H75.6v13h14.9V6.1z' + | ||
118 | + ' M71.9,6.1H56.9v13h14.9V6.1z M53.2,6.1H38.3v13h14.9V6.1z M34.5,' + | ||
119 | + '6.1H19.6v13h14.9V6.1z M102.2,6.1h-8v13h8V6.1z M102.2,23.6H7.9v' + | ||
120 | + '78.5h94.4V23.6z M86,63.2c0,3.3-2.7,6-6,6c-2.8,0-5.1-1.9-5.8-' + | ||
121 | + '4.5H63.3v5.1c0,0.9-0.7,1.5-1.5,1.5h-5.2v10.6c2.6,0.7,4.5,3,4.5,' + | ||
122 | + '5.8c0,3.3-2.7,6-6,6c-3.3,0-6-2.7-6-6c0-2.8,1.9-5.1,4.4-5.8V71.3' + | ||
123 | + 'H48c-0.9,0-1.5-0.7-1.5-1.5v-5.1H36c-0.7,2.6-3,4.4-5.8,4.4c-3.3,' + | ||
124 | + '0-6-2.7-6-6s2.7-6,6-6c2.8,0,5.2,1.9,5.8,4.5h10.5V56c0-0.9,0.7-' + | ||
125 | + '1.5,1.5-1.5h5.5V43.8c-2.6-0.7-4.5-3-4.5-5.8c0-3.3,2.7-6,6-6s6,' + | ||
126 | + '2.7,6,6c0,2.8-1.9,5.1-4.5,5.8v10.6h5.2c0.9,0,1.5,0.7,1.5,1.5v' + | ||
127 | + '5.6h10.8c0.7-2.6,3-4.5,5.8-4.5C83.3,57.1,86,59.8,86,63.2z M55.1,' + | ||
128 | + '42.3c2.3,0,4.3-1.9,4.3-4.3c0-2.3-1.9-4.3-4.3-4.3s-4.3,1.9-4.3,' + | ||
129 | + '4.3C50.8,40.4,52.7,42.3,55.1,42.3z M34.4,63.1c0-2.3-1.9-4.3-4.3' + | ||
130 | + '-4.3s-4.3,1.9-4.3,4.3s1.9,4.3,4.3,4.3S34.4,65.5,34.4,63.1z ' + | ||
131 | + 'M55.1,83.5c-2.3,0-4.3,1.9-4.3,4.3s1.9,4.3,4.3,4.3s4.3-1.9,4.3-' + | ||
132 | + '4.3S57.5,83.5,55.1,83.5zM84.2,63.2c0-2.3-1.9-4.3-4.3-4.3s-4.3,' + | ||
133 | + '1.9-4.3,4.3s1.9,4.3,4.3,4.3S84.2,65.5,84.2,63.2z', | ||
134 | + | ||
117 | // --- Topology toolbar specific glyphs ---------------------- | 135 | // --- Topology toolbar specific glyphs ---------------------- |
118 | 136 | ||
119 | summary: "M95.8,9.2H14.2c-2.8,0-5,2.2-5,5v81.5c0,2.8,2.2,5,5," + | 137 | summary: "M95.8,9.2H14.2c-2.8,0-5,2.2-5,5v81.5c0,2.8,2.2,5,5," + | ... | ... |
... | @@ -29,9 +29,12 @@ | ... | @@ -29,9 +29,12 @@ |
29 | // scope: $scope, <- controller scope | 29 | // scope: $scope, <- controller scope |
30 | // tag: 'device', <- table identifier | 30 | // tag: 'device', <- table identifier |
31 | // selCb: selCb <- row selection callback (optional) | 31 | // selCb: selCb <- row selection callback (optional) |
32 | + // query: params <- query parameters in URL (optional) | ||
32 | // } | 33 | // } |
33 | // Note: selCb() is passed the row data model of the selected row, | 34 | // Note: selCb() is passed the row data model of the selected row, |
34 | // or null when no row is selected. | 35 | // or null when no row is selected. |
36 | + // Note: query is always an object (empty or containing properties) | ||
37 | + // it comes from $location.search() | ||
35 | 38 | ||
36 | function buildTable(o) { | 39 | function buildTable(o) { |
37 | var handlers = {}, | 40 | var handlers = {}, |
... | @@ -48,7 +51,8 @@ | ... | @@ -48,7 +51,8 @@ |
48 | } | 51 | } |
49 | 52 | ||
50 | function sortCb(params) { | 53 | function sortCb(params) { |
51 | - wss.sendEvent(req, params); | 54 | + var p = angular.extend({}, params, o.query); |
55 | + wss.sendEvent(req, p); | ||
52 | } | 56 | } |
53 | o.scope.sortCallback = sortCb; | 57 | o.scope.sortCallback = sortCb; |
54 | 58 | ... | ... |
... | @@ -119,11 +119,11 @@ | ... | @@ -119,11 +119,11 @@ |
119 | 119 | ||
120 | bns.button(btnsDiv, | 120 | bns.button(btnsDiv, |
121 | 'dev-dets-p-flows', | 121 | 'dev-dets-p-flows', |
122 | - 'flowsTable', | 122 | + 'flowTable', |
123 | function () { | 123 | function () { |
124 | ns.navTo(flowPath, { devId: details.id }); | 124 | ns.navTo(flowPath, { devId: details.id }); |
125 | }, | 125 | }, |
126 | - 'Show flows for this device'); | 126 | + 'Show flows table for this device'); |
127 | } | 127 | } |
128 | 128 | ||
129 | function addPortRow(tbody, port) { | 129 | function addPortRow(tbody, port) { | ... | ... |
... | @@ -18,5 +18,28 @@ | ... | @@ -18,5 +18,28 @@ |
18 | ONOS GUI -- Flow View -- CSS file | 18 | ONOS GUI -- Flow View -- CSS file |
19 | */ | 19 | */ |
20 | 20 | ||
21 | -#ov-flow td { | 21 | +.light #ov-flow tr:nth-child(6n + 2), |
22 | +.light #ov-flow tr:nth-child(6n + 3), | ||
23 | +.light #ov-flow tr:nth-child(6n + 4) { | ||
24 | + background-color: #eee; | ||
25 | +} | ||
26 | +.light #ov-flow tr:nth-child(6n + 5), | ||
27 | +.light #ov-flow tr:nth-child(6n + 6), | ||
28 | +.light #ov-flow tr:nth-child(6n + 1) { | ||
29 | + background-color: #ddd; | ||
30 | +} | ||
31 | +.dark #ov-flow tr:nth-child(6n + 2), | ||
32 | +.dark #ov-flow tr:nth-child(6n + 3), | ||
33 | +.dark #ov-flow tr:nth-child(6n + 4) { | ||
34 | + background-color: #444; | ||
35 | +} | ||
36 | +.dark #ov-flow tr:nth-child(6n + 5), | ||
37 | +.dark #ov-flow tr:nth-child(6n + 6), | ||
38 | +.dark #ov-flow tr:nth-child(6n + 1) { | ||
39 | + background-color: #333; | ||
40 | +} | ||
41 | + | ||
42 | +#ov-flow td.selector, | ||
43 | +#ov-flow td.treatment { | ||
44 | + padding-left: 36px; | ||
22 | } | 45 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | -<!-- Host partial HTML --> | 1 | +<!-- Flow partial HTML --> |
2 | <div id="ov-flow"> | 2 | <div id="ov-flow"> |
3 | - <h1> Flows are here </h1> | 3 | + <div class="tabular-header"> |
4 | + <h2> | ||
5 | + Flows for Device {{ctrl.devId || "none"}} | ||
6 | + ({{ctrl.tableData.length}} total) | ||
7 | + </h2> | ||
8 | + </div> | ||
9 | + | ||
10 | + <table class="summary-list" | ||
11 | + onos-fixed-header | ||
12 | + onos-sortable-header | ||
13 | + sort-callback="sortCallback(requestParams)"> | ||
14 | + <thead> | ||
15 | + <tr> | ||
16 | + <th colId="id" sortable>Flow ID </th> | ||
17 | + <th colId="appId" sortable>App ID </th> | ||
18 | + <th colId="groupId" sortable>Group ID </th> | ||
19 | + <th colId="tableId" sortable>Table ID </th> | ||
20 | + <th colId="priority" sortable>Priority </th> | ||
21 | + <th colId="timeout" sortable>Timeout </th> | ||
22 | + <th colId="permanent" sortable>Permanent </th> | ||
23 | + <th colId="state" sortable>State </th> | ||
24 | + </tr> | ||
25 | + </thead> | ||
26 | + | ||
27 | + <tbody> | ||
28 | + <tr ng-hide="ctrl.tableData.length"> | ||
29 | + <td class="nodata" colspan="8"> | ||
30 | + No Flows found | ||
31 | + </td> | ||
32 | + </tr> | ||
33 | + | ||
34 | + <tr ng-repeat-start="flow in ctrl.tableData"> | ||
35 | + <td>{{flow.id}}</td> | ||
36 | + <td>{{flow.appId}}</td> | ||
37 | + <td>{{flow.groupId}}</td> | ||
38 | + <td>{{flow.tableId}}</td> | ||
39 | + <td>{{flow.priority}}</td> | ||
40 | + <td>{{flow.timeout}}</td> | ||
41 | + <td>{{flow.permanent}}</td> | ||
42 | + <td>{{flow.state}}</td> | ||
43 | + </tr> | ||
44 | + <tr> | ||
45 | + <td class="selector" colspan="8">{{flow.selector}}</td> | ||
46 | + </tr> | ||
47 | + <tr ng-repeat-end ng-repeat-done> | ||
48 | + <td class="treatment" colspan="8">{{flow.treatment}}</td> | ||
49 | + </tr> | ||
50 | + </tbody> | ||
51 | + </table> | ||
4 | </div> | 52 | </div> | ... | ... |
... | @@ -21,16 +21,33 @@ | ... | @@ -21,16 +21,33 @@ |
21 | (function () { | 21 | (function () { |
22 | 'use strict'; | 22 | 'use strict'; |
23 | 23 | ||
24 | + // injected references | ||
25 | + var $log, $scope, $location, fs, tbs; | ||
26 | + | ||
24 | angular.module('ovFlow', []) | 27 | angular.module('ovFlow', []) |
25 | .controller('OvFlowCtrl', | 28 | .controller('OvFlowCtrl', |
26 | - ['$log', '$scope', 'TableBuilderService', | 29 | + ['$log', '$scope', '$location', 'FnService', 'TableBuilderService', |
27 | - | 30 | + |
28 | - function ($log, $scope, tbs) { | 31 | + function (_$log_, _$scope_, _$location_, _fs_, _tbs_) { |
29 | - //tbs.buildTable({ | 32 | + var self = this, |
30 | - // self: this, | 33 | + params; |
31 | - // scope: $scope, | 34 | + $log = _$log_; |
32 | - // tag: 'flow' | 35 | + $scope = _$scope_; |
33 | - //}); | 36 | + $location = _$location_; |
37 | + fs = _fs_; | ||
38 | + tbs = _tbs_; | ||
39 | + | ||
40 | + params = $location.search(); | ||
41 | + if (params.hasOwnProperty('devId')) { | ||
42 | + self.devId = params['devId']; | ||
43 | + } | ||
44 | + | ||
45 | + tbs.buildTable({ | ||
46 | + self: self, | ||
47 | + scope: $scope, | ||
48 | + tag: 'flow', | ||
49 | + query: params | ||
50 | + }); | ||
34 | 51 | ||
35 | $log.log('OvFlowCtrl has been created'); | 52 | $log.log('OvFlowCtrl has been created'); |
36 | }]); | 53 | }]); | ... | ... |
... | @@ -248,9 +248,9 @@ | ... | @@ -248,9 +248,9 @@ |
248 | if ((data.props).hasOwnProperty('URI')) { | 248 | if ((data.props).hasOwnProperty('URI')) { |
249 | tps.addAction({ | 249 | tps.addAction({ |
250 | id: 'flows-table-btn', | 250 | id: 'flows-table-btn', |
251 | - gid: 'flowsTable', | 251 | + gid: 'flowTable', |
252 | cb: function () { | 252 | cb: function () { |
253 | - ns.navTo(flowPath, { devId: data.id }); | 253 | + ns.navTo(flowPath, { devId: data.props['URI'] }); |
254 | }, | 254 | }, |
255 | tt: 'Show flows for this device' | 255 | tt: 'Show flows for this device' |
256 | }); | 256 | }); | ... | ... |
... | @@ -78,7 +78,7 @@ | ... | @@ -78,7 +78,7 @@ |
78 | self.$route = $route; | 78 | self.$route = $route; |
79 | self.$routeParams = $routeParams; | 79 | self.$routeParams = $routeParams; |
80 | self.$location = $location; | 80 | self.$location = $location; |
81 | - self.version = '1.1.0'; | 81 | + self.version = '1.3.0'; |
82 | 82 | ||
83 | // initialize services... | 83 | // initialize services... |
84 | ts.init(); | 84 | ts.init(); | ... | ... |
... | @@ -29,7 +29,7 @@ describe('Controller: OnosCtrl', function () { | ... | @@ -29,7 +29,7 @@ describe('Controller: OnosCtrl', function () { |
29 | ctrl = $controller('OnosCtrl'); | 29 | ctrl = $controller('OnosCtrl'); |
30 | })); | 30 | })); |
31 | 31 | ||
32 | - it('should report version 1.1.0', function () { | 32 | + it('should report version 1.3.0', function () { |
33 | - expect(ctrl.version).toEqual('1.1.0'); | 33 | + expect(ctrl.version).toEqual('1.3.0'); |
34 | }); | 34 | }); |
35 | }); | 35 | }); |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or login to post a comment