Matteo Scandolo
Committed by Gerrit Code Review

Enabling UI live-reload for apps not in the ONOS source code

Change-Id: Ib88929a8825b7adf136d2b6b90d66db10549c165
1 +namespace java org.p4.bmv2.thrift
2 +namespace cpp cpservice
3 +
4 +service ControlPlaneService {
5 +
6 + bool ping(),
7 +
8 + oneway void packetIn(1: i32 port, 2: i64 reason, 3: i32 tableId, 4: i32 contextId, 5: binary packet),
9 +
10 + oneway void hello(1: i32 thriftServerPort, 2: i32 deviceId)
11 +
12 +}
...\ No newline at end of file ...\ No newline at end of file
1 +namespace java org.p4.bmv2.thrift
2 +/* Copyright 2013-present Barefoot Networks, Inc.
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 + * Antonin Bas (antonin@barefootnetworks.com)
19 + *
20 + */
21 +
22 +namespace cpp bm_runtime.simple_pre
23 +namespace py bm_runtime.simple_pre
24 +
25 +typedef i32 BmMcMgrp
26 +typedef i32 BmMcRid
27 +typedef i32 BmMcMgrpHandle
28 +typedef i32 BmMcL1Handle
29 +typedef string BmMcPortMap // string of 0s and 1s
30 +
31 +enum McOperationErrorCode {
32 + TABLE_FULL = 1,
33 + INVALID_HANDLE = 2,
34 + INVALID_MGID = 3,
35 + INVALID_L1_HANDLE = 4,
36 + INVALID_L2_HANLDE = 5,
37 + ERROR = 6
38 +}
39 +
40 +exception InvalidMcOperation {
41 + 1:McOperationErrorCode code
42 +}
43 +
44 +service SimplePre {
45 +
46 + BmMcMgrpHandle bm_mc_mgrp_create(
47 + 1:i32 cxt_id,
48 + 2:BmMcMgrp mgrp
49 + ) throws (1:InvalidMcOperation ouch),
50 +
51 + void bm_mc_mgrp_destroy(
52 + 1:i32 cxt_id,
53 + 2:BmMcMgrpHandle mgrp_handle
54 + ) throws (1:InvalidMcOperation ouch),
55 +
56 + BmMcL1Handle bm_mc_node_create(
57 + 1:i32 cxt_id,
58 + 2:BmMcRid rid
59 + 3:BmMcPortMap port_map
60 + ) throws (1:InvalidMcOperation ouch),
61 +
62 + void bm_mc_node_associate(
63 + 1:i32 cxt_id,
64 + 2:BmMcMgrpHandle mgrp_handle,
65 + 3:BmMcL1Handle l1_handle
66 + ) throws (1:InvalidMcOperation ouch),
67 +
68 + void bm_mc_node_dissociate(
69 + 1:i32 cxt_id,
70 + 2:BmMcMgrpHandle mgrp_handle,
71 + 3:BmMcL1Handle l1_handle
72 + ) throws (1:InvalidMcOperation ouch),
73 +
74 + void bm_mc_node_destroy(
75 + 1:i32 cxt_id,
76 + 2:BmMcL1Handle l1_handle
77 + ) throws (1:InvalidMcOperation ouch),
78 +
79 + void bm_mc_node_update(
80 + 1:i32 cxt_id,
81 + 2:BmMcL1Handle l1_handle,
82 + 3:BmMcPortMap port_map
83 + ) throws (1:InvalidMcOperation ouch),
84 +}
1 +namespace java org.p4.bmv2.thrift
2 +/* Copyright 2013-present Barefoot Networks, Inc.
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 + * Srikrishna Gopu (krishna@barefootnetworks.com)
19 + * Antonin Bas (antonin@barefootnetworks.com)
20 + *
21 + */
22 +
23 +namespace cpp bm_runtime.simple_pre_lag
24 +namespace py bm_runtime.simple_pre_lag
25 +
26 +typedef i32 BmMcMgrp
27 +typedef i32 BmMcRid
28 +typedef i32 BmMcMgrpHandle
29 +typedef i32 BmMcL1Handle
30 +typedef i16 BmMcLagIndex
31 +typedef string BmMcPortMap // string of 0s and 1s
32 +typedef string BmMcLagMap // string of 0s and 1s
33 +
34 +enum McOperationErrorCode {
35 + TABLE_FULL = 1,
36 + INVALID_HANDLE = 2,
37 + INVALID_MGID = 3,
38 + INVALID_L1_HANDLE = 4,
39 + INVALID_L2_HANLDE = 5,
40 + ERROR = 6
41 +}
42 +
43 +exception InvalidMcOperation {
44 + 1:McOperationErrorCode code
45 +}
46 +
47 +service SimplePreLAG {
48 +
49 + BmMcMgrpHandle bm_mc_mgrp_create(
50 + 1:i32 cxt_id,
51 + 2:BmMcMgrp mgrp
52 + ) throws (1:InvalidMcOperation ouch),
53 +
54 + void bm_mc_mgrp_destroy(
55 + 1:i32 cxt_id,
56 + 2:BmMcMgrpHandle mgrp_handle
57 + ) throws (1:InvalidMcOperation ouch),
58 +
59 + BmMcL1Handle bm_mc_node_create(
60 + 1:i32 cxt_id,
61 + 2:BmMcRid rid,
62 + 3:BmMcPortMap port_map,
63 + 4:BmMcLagMap lag_map
64 + ) throws (1:InvalidMcOperation ouch),
65 +
66 + void bm_mc_node_associate(
67 + 1:i32 cxt_id,
68 + 2:BmMcMgrpHandle mgrp_handle,
69 + 3:BmMcL1Handle l1_handle
70 + ) throws (1:InvalidMcOperation ouch),
71 +
72 + void bm_mc_node_dissociate(
73 + 1:i32 cxt_id,
74 + 2:BmMcMgrpHandle mgrp_handle,
75 + 3:BmMcL1Handle l1_handle
76 + ) throws (1:InvalidMcOperation ouch),
77 +
78 + void bm_mc_node_destroy(
79 + 1:i32 cxt_id,
80 + 2:BmMcL1Handle l1_handle
81 + ) throws (1:InvalidMcOperation ouch),
82 +
83 + void bm_mc_node_update(
84 + 1:i32 cxt_id,
85 + 2:BmMcL1Handle l1_handle,
86 + 3:BmMcPortMap port_map,
87 + 4:BmMcLagMap lag_map
88 + ) throws (1:InvalidMcOperation ouch),
89 +
90 + void bm_mc_set_lag_membership(
91 + 1:i32 cxt_id,
92 + 2:BmMcLagIndex lag_index,
93 + 3:BmMcPortMap port_map
94 + ) throws (1:InvalidMcOperation ouch),
95 +}
1 +namespace java org.p4.bmv2.thrift
2 +/* Copyright 2013-present Barefoot Networks, Inc.
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 + * Antonin Bas (antonin@barefootnetworks.com)
19 + *
20 + */
21 +
22 +namespace cpp sswitch_runtime
23 +namespace py sswitch_runtime
24 +
25 +service SimpleSwitch {
26 +
27 + i32 mirroring_mapping_add(1:i32 mirror_id, 2:i32 egress_port);
28 + i32 mirroring_mapping_delete(1:i32 mirror_id);
29 + i32 mirroring_mapping_get_egress_port(1:i32 mirror_id);
30 +
31 + i32 set_egress_queue_depth(1:i32 depth_pkts);
32 + i32 set_egress_queue_rate(1:i64 rate_pps);
33 +
34 + oneway void push_packet(1:i32 port, 2:binary packet);
35 +
36 + bool ping();
37 +
38 +}
This diff is collapsed. Click to expand it.
...@@ -26,4 +26,17 @@ Dev server is up and listening on http://localhost: 8182 ...@@ -26,4 +26,17 @@ Dev server is up and listening on http://localhost: 8182
26 [BS] Watching files... 26 [BS] Watching files...
27 ``` 27 ```
28 28
29 -To open ONOS visit the local URL (eg: `http://localhost:3000`) plus `/onos/ui` (eg: `http://localhost:3000/onos/ui`)
...\ No newline at end of file ...\ No newline at end of file
29 +To open ONOS visit the local URL (eg: `http://localhost:3000`) plus `/onos/ui`
30 +(eg: `http://localhost:3000/onos/ui`)
31 +
32 +## Loading files from external applications
33 +
34 +The UI development environment provide the ability to serve UI files
35 +from an external forlder that can be specified with:
36 +`ONOS_EXTERNAL_APP_DIRS="appName:path-to-the-first-folder" npm start`
37 +
38 +Eg:
39 +`ONOS_EXTERNAL_APP_DIRS="sampleCustom:../../meow/sample/meowster-sample/" npm start`
40 +
41 +_Note that `ONOS_EXTERNAL_APP_DIRS` is an environment variable,so it can be set with_
42 +_`export ONOS_EXTERNAL_APP_DIRS="sampleCustom:../../meow/sample/meowster-sample/"`_
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -19,15 +19,38 @@ var proxy = httpProxy.createProxyServer({ ...@@ -19,15 +19,38 @@ var proxy = httpProxy.createProxyServer({
19 target: 'http://localhost:8182', 19 target: 'http://localhost:8182',
20 }); 20 });
21 21
22 +if (process.env.ONOS_EXTERNAL_APP_DIRS) {
23 + var external_apps = process.env.ONOS_EXTERNAL_APP_DIRS.replace(/\s/,'').split(',');
24 + external_apps = external_apps.reduce(function(dict, app){
25 + var pieces = app.split(':');
26 + var appName = pieces[0];
27 + var appPath = pieces[1];
28 + dict[appName] = appPath;
29 + return dict;
30 + }, {});
31 +}
32 +
22 var defaultViews = fs.readdirSync('./app/view/'); 33 var defaultViews = fs.readdirSync('./app/view/');
23 var viewNameMatcher = new RegExp(/\/onos\/ui\/app\/view\/(.+)\/.+\.(?:js|css|html)/); 34 var viewNameMatcher = new RegExp(/\/onos\/ui\/app\/view\/(.+)\/.+\.(?:js|css|html)/);
24 35
36 +var checkExternalApp = function (url) {
37 + if(external_apps){
38 + for(var i = 0; i < Object.keys(external_apps).length; i++){
39 + var key = Object.keys(external_apps)[i];
40 + if(url.indexOf(key) !== -1){
41 + return key;
42 + };
43 + }
44 + }
45 + return false;
46 +};
47 +
25 proxy.on('upgrade', function (req, socket, head) { 48 proxy.on('upgrade', function (req, socket, head) {
26 console.log('[WS]: ', head); 49 console.log('[WS]: ', head);
27 proxy.ws(req, socket, head); 50 proxy.ws(req, socket, head);
28 }); 51 });
29 52
30 -proxy.on('error', function(error, req, res) { 53 +proxy.on('error', function (error, req, res) {
31 res.writeHead(500, { 54 res.writeHead(500, {
32 'Content-Type': 'text/plain' 55 'Content-Type': 'text/plain'
33 }); 56 });
...@@ -50,21 +73,29 @@ module.exports = { ...@@ -50,21 +73,29 @@ module.exports = {
50 proxy: { 73 proxy: {
51 target: "http://localhost:8181", 74 target: "http://localhost:8181",
52 ws: true, 75 ws: true,
53 - middleware: function(req, res, next){ 76 + middleware: function (req, res, next) {
54 -
55 77
56 var viewName = viewNameMatcher.exec(req.url); 78 var viewName = viewNameMatcher.exec(req.url);
57 - if(!!viewName && defaultViews.indexOf(viewName[1]) === -1){ 79 + var isExternalApp = checkExternalApp(req.url);
58 - // in this case it is an external application that extend the view 80 +
81 + if (!!viewName && !isExternalApp && defaultViews.indexOf(viewName[1]) === -1) {
82 + // in this case it is an application that extend the view
59 // so we redirect the request to the app folder in case of .js, .css, .html 83 // so we redirect the request to the app folder in case of .js, .css, .html
60 req.url = req.url.replace('/onos/ui/', '/apps/' + viewName[1] + '/app/src/main/resources/'); 84 req.url = req.url.replace('/onos/ui/', '/apps/' + viewName[1] + '/app/src/main/resources/');
61 proxy.web(req, res); 85 proxy.web(req, res);
62 } 86 }
87 + else if (isExternalApp) {
88 + // in this case it is an external application (not in ONOS source code) that extend the view
89 + // so we redirect the request to the app folder in case of .js, .css, .html
90 + req.url = req.url.replace('/onos/ui/', '/src/main/resources/');
91 + proxy.web(req, res);
92 + }
63 // NOTE onos.js and index.html should not be proxied (require server side injection) 93 // NOTE onos.js and index.html should not be proxied (require server side injection)
64 - else if(req.url.match(/(?:js|css|html)/) && req.url !== '/onos/ui/onos.js' && req.url !== '/onos/ui/index.html' && req.url !== '/onos/ui/nav.html'){ 94 + else if (req.url.match(/(?:js|css|html)/) && req.url !== '/onos/ui/onos.js' &&
95 + req.url !== '/onos/ui/index.html' && req.url !== '/onos/ui/nav.html') {
65 // redirect onos base js files to the source folder 96 // redirect onos base js files to the source folder
66 req.url = req.url.replace('/onos/ui/', '/web/gui/src/main/webapp/'); 97 req.url = req.url.replace('/onos/ui/', '/web/gui/src/main/webapp/');
67 - proxy.web(req, res); 98 + proxy.web(req, res);
68 } 99 }
69 else { 100 else {
70 return next(); 101 return next();
......
1 'use strict'; 1 'use strict';
2 2
3 -var http = require('http');
4 -// var httpProxy = require('http-proxy');
5 -var connect = require('connect');
6 -var serveStatic = require('serve-static');
7 var path = require('path'); 3 var path = require('path');
4 +var express = require('express');
5 +var app = express();
8 6
9 var conf = { 7 var conf = {
10 paths: { 8 paths: {
...@@ -13,17 +11,31 @@ var conf = { ...@@ -13,17 +11,31 @@ var conf = {
13 port: '8182' 11 port: '8182'
14 } 12 }
15 13
16 -var httpProxyInit = function (baseDir) { 14 +if (process.env.ONOS_EXTERNAL_APP_DIRS) {
15 + var external_apps = process.env.ONOS_EXTERNAL_APP_DIRS.replace(/\s/,'').split(',');
16 + external_apps.forEach(function(a, i){
17 + let [appName, appPath] = a.split(':');
18 + conf.paths[appName] = appPath;
19 + });
20 +}
17 21
18 - var app = connect(); 22 +var httpProxyInit = function (baseDirs) {
19 23
20 - app.use(serveStatic(path.join(__dirname, baseDir))); 24 + Object.keys(baseDirs).forEach(dir => {
25 + var d = path.isAbsolute(baseDirs[dir]) ? baseDirs[dir] : path.join(__dirname, baseDirs[dir]);
26 + app.use(express.static(d));
27 + });
21 28
22 - var server = http.createServer(app); 29 + app.get('/', function (req, res) {
30 + res.send('Hello World!');
31 + });
23 32
24 - server.listen(conf.port, function(){ 33 + app.listen(conf.port, function () {
25 - console.log('Dev server is up and listening on http://localhost:', conf.port); 34 + console.log(`Dev server is up and listening on http://localhost:${conf.port}!`);
26 }); 35 });
27 }; 36 };
28 37
29 -httpProxyInit(conf.paths.root);
...\ No newline at end of file ...\ No newline at end of file
38 +httpProxyInit(conf.paths);
39 +
40 +
41 +
......
...@@ -7,17 +7,16 @@ ...@@ -7,17 +7,16 @@
7 "test": "tests" 7 "test": "tests"
8 }, 8 },
9 "scripts": { 9 "scripts": {
10 - "bs": "browser-sync start --config bs-config.js", 10 + "bs": "browser-sync start --config bs-config.js",
11 - "dev-server": "node dev_server.js", 11 + "dev-server": "node --harmony_destructuring dev_server.js",
12 "start": "parallelshell \"npm run dev-server\" \"npm run bs\"" 12 "start": "parallelshell \"npm run dev-server\" \"npm run bs\""
13 }, 13 },
14 "author": "ON.Lab", 14 "author": "ON.Lab",
15 "license": "Apache 2.0", 15 "license": "Apache 2.0",
16 "devDependencies": { 16 "devDependencies": {
17 "browser-sync": "^2.12.8", 17 "browser-sync": "^2.12.8",
18 - "connect": "^3.4.1",
19 - "http-proxy": "^1.13.2",
20 "parallelshell": "^2.0.0", 18 "parallelshell": "^2.0.0",
21 - "serve-static": "^1.10.2" 19 + "serve-static": "^1.10.2",
20 + "express": "^4.14.0"
22 } 21 }
23 } 22 }
......