Allow upload/update through session manager
[osm/UI.git] / skyquake / skyquake.js
1
2
3 /*
4 *
5 * Copyright 2016 RIFT.IO Inc
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */
20
21 /**
22 * Main skyquake module.
23 * @module skyquake
24 * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
25 */
26
27 // Standard library imports for forking
28 var cluster = require("cluster");
29 var cpu = require('os').cpus().length;
30 var clusteredLaunch = process.env.CLUSTER_SUPPORT || false;
31 var constants = require('./framework/core/api_utils/constants');
32 // Uncomment for Replay support
33 // const Replay = require('replay');
34 var freePorts = [];
35 for (var i = 0; i < constants.SOCKET_POOL_LENGTH; i++) {
36 freePorts[i] = constants.SOCKET_BASE_PORT + i;
37 };
38
39
40 if (cluster.isMaster && clusteredLaunch) {
41 console.log(cpu, 'CPUs found');
42 for (var i = 0; i < cpu; i ++) {
43 var worker = cluster.fork();
44 worker.on('message', function(msg) {
45 if (msg && msg.getPort) {
46 worker.send({
47 port: freePorts.shift()
48 });
49 console.log('freePorts after shift for worker', this.process.pid, ':', freePorts);
50 } else if (msg && msg.freePort) {
51 freePorts.unshift(msg.port);
52 console.log('freePorts after unshift of', msg.port, 'for worker', this.process.pid, ':', freePorts);
53 }
54 });
55 }
56
57 cluster.on('online', function(worker) {
58 console.log("Worker Started pid : " + worker.process.pid);
59 });
60 cluster.on('exit', function(worker, code, signal) {
61 console.log('worker ' + worker.process.pid + ' stopped');
62 });
63 } else {
64 // Standard library imports
65 var argv = require('minimist')(process.argv.slice(2));
66 var pid = process.pid;
67 var fs = require('fs');
68 var https = require('https');
69 var http = require('http');
70 var express = require('express');
71 var session = require('express-session');
72 var cors = require('cors');
73 var bodyParser = require('body-parser');
74 var _ = require('lodash');
75 var reload = require('require-reload')(require);
76 var Sockets = require('./framework/core/api_utils/sockets.js');
77
78 require('require-json');
79
80 // SSL related configuration bootstrap
81 var httpServer = null;
82 var secureHttpServer = null;
83
84 var httpsConfigured = false;
85
86 var sslOptions = null;
87
88 var apiServer = argv['api-server'] ? argv['api-server'] : 'localhost';
89 var uploadServer = argv['upload-server'] ? argv['upload-server'] : null;
90
91 try {
92 if (argv['enable-https']) {
93 var keyFilePath = argv['keyfile-path'];
94 var certFilePath = argv['certfile-path'];
95
96 sslOptions = {
97 key: fs.readFileSync(keyFilePath),
98 cert: fs.readFileSync(certFilePath)
99 };
100
101 httpsConfigured = true;
102 }
103 } catch (e) {
104 console.log('HTTPS enabled but file paths missing/incorrect');
105 process.exit(code = -1);
106 }
107
108 var app = express();
109
110 app.set('views', __dirname + '/framework/core/views');
111 app.engine('html', require('ejs').renderFile);
112
113 app.use(session({
114 secret: 'ritio rocks',
115 resave: false,
116 saveUninitialized: true
117 }));
118 app.use(bodyParser.json());
119 app.use(cors());
120 app.use(bodyParser.urlencoded({
121 extended: true
122 }));
123
124 var socketManager = new Sockets();
125 var socketConfig = {
126 httpsConfigured: httpsConfigured
127 };
128
129 if (httpsConfigured) {
130 socketConfig.sslOptions = sslOptions;
131 }
132
133 // Rift framework imports
134 var constants = require('./framework/core/api_utils/constants');
135 var skyquakeEmitter = require('./framework/core/modules/skyquakeEmitter');
136 var navigation_routes = require('./framework/core/modules/routes/navigation');
137 var socket_routes = require('./framework/core/modules/routes/sockets');
138 var restconf_routes = require('./framework/core/modules/routes/restconf');
139 var inactivity_routes = require('./framework/core/modules/routes/inactivity');
140 var descriptor_routes = require('./framework/core/modules/routes/descriptorModel');
141 var configuration_routes = require('./framework/core/modules/routes/configuration');
142 var configurationAPI = require('./framework/core/modules/api/configuration');
143 var userManagement_routes = require('./framework/core/modules/routes/userManagement');
144 var projectManagement_routes = require('./framework/core/modules/routes/projectManagement');
145 var session_routes = require('./framework/core/modules/routes/sessions');
146 /**
147 * Processing when a plugin is added or modified
148 * @param {string} plugin_name - Name of the plugin
149 */
150 function onPluginAdded(plugin_name) {
151 // Load plugin config
152 var plugin_config = reload('./plugins/' + plugin_name + '/config.json');
153
154 // Load all app's views
155 app.use('/' + plugin_name, express.static('./plugins/' + plugin_name + '/' + plugin_config.root));
156
157 // Load all app's routes
158 app.use('/' + plugin_name, require('./plugins/' + plugin_name + '/routes'));
159
160 // Publish navigation links
161 if (plugin_config.routes && _.isArray(plugin_config.routes)) {
162 skyquakeEmitter.emit('config_discoverer.navigation_discovered', plugin_name, plugin_config);
163 }
164
165 }
166
167 /**
168 * Serve jquery
169 */
170 app.use('/jquery', express.static('./node_modules/jquery/dist/jquery.min.js'));
171 /**
172 * Serve images
173 */
174 app.use('/img', express.static('./framework/style/img'));
175
176 /**
177 * Start listening on a port
178 * @param {string} port - Port to listen on
179 * @param {object} httpServer - httpServer created with http(s).createServer
180 */
181 function startListening(port, httpServer) {
182 var server = httpServer.listen(port, function () {
183 var host = server.address().address;
184
185 var port = server.address().port;
186
187 console.log('Express server listening on port', port);
188 });
189 return server;
190 }
191
192 /**
193 * Initialize skyquake
194 */
195 function init() {
196 skyquakeEmitter.on('plugin_discoverer.plugin_discovered', onPluginAdded);
197 skyquakeEmitter.on('plugin_discoverer.plugin_updated', onPluginAdded);
198 }
199
200 /**
201 * Configure skyquake
202 */
203 function config() {
204 // Conigure any globals
205 process.env.NODE_TLS_REJECT_UNAUTHORIZED=0;
206
207 // Configure navigation router
208 app.use(navigation_routes);
209
210 // Configure restconf router
211 app.use(restconf_routes);
212
213 //Configure inactivity route(s)
214 app.use(inactivity_routes);
215
216 // Configure global config with ssl enabled/disabled
217 var globalConfig = {
218 ssl_enabled: httpsConfigured,
219 api_server: apiServer
220 };
221
222 if (uploadServer) {
223 globalConfig.upload_server = uploadServer;
224 }
225
226 configurationAPI.globalConfiguration.update(globalConfig);
227
228 // Configure configuration route(s)
229 app.use(configuration_routes);
230
231 //Configure descriptor route(s)
232 app.use(descriptor_routes);
233
234 //Configure user management route(s)
235 app.use(userManagement_routes);
236
237 //Configure project management route(s)
238 app.use(projectManagement_routes);
239
240 //Configure session route(s)
241 app.use(session_routes);
242
243 // app.get('/testme', function(req, res) {
244 // res.sendFile(__dirname + '/index.html');
245 // });
246
247 // Configure HTTP/HTTPS server and populate socketConfig.
248 if (httpsConfigured) {
249 console.log('HTTPS configured. Will create 2 servers');
250 secureHttpServer = https.createServer(sslOptions, app);
251 // Add redirection on SERVER_PORT
252 httpServer = http.createServer(function(req, res) {
253 var host = req.headers['host'];
254 host = host.replace(/:\d+$/, ":" + constants.SECURE_SERVER_PORT);
255
256 res.writeHead(301, { "Location": "https://" + host + req.url });
257 res.end();
258 });
259
260 socketConfig.httpServer = secureHttpServer;
261 } else {
262 httpServer = http.createServer(app);
263 socketConfig.httpServer = httpServer;
264 }
265
266 // Configure socket manager
267 socketManager.configure(socketConfig);
268
269 // Configure socket router
270 socket_routes.routes(socketManager);
271 app.use(socket_routes.router);
272
273 // Serve multiplex-client
274 app.get('/multiplex-client', function(req, res) {
275 res.sendFile(__dirname + '/node_modules/websocket-multiplex/multiplex_client.js');
276 });
277
278 // handle requests for gzip'd files
279 app.get('*gzip*', function (req, res, next) {
280 res.set('Content-Encoding', 'gzip');
281 next();
282 });
283
284 }
285
286 /**
287 * Run skyquake functionality
288 */
289 function run() {
290
291 // Start plugin_discoverer
292 var navigation_manager = require('./framework/core/modules/navigation_manager');
293 var plugin_discoverer = require('./framework/core/modules/plugin_discoverer');
294
295 // Initialize asynchronous modules
296 navigation_manager.init();
297 plugin_discoverer.init();
298
299 // Configure asynchronous modules
300 navigation_manager.config()
301 plugin_discoverer.config({
302 plugins_path: './plugins'
303 });
304
305 // Run asynchronous modules
306 navigation_manager.run();
307 plugin_discoverer.run();
308
309
310 // Server start
311 if (httpsConfigured) {
312 console.log('HTTPS configured. Will start 2 servers');
313 // Start listening on SECURE_SERVER_PORT (8443)
314 var secureServer = startListening(constants.SECURE_SERVER_PORT, secureHttpServer);
315 }
316 // Start listening on SERVER_PORT (8000)
317 var server = startListening(constants.SERVER_PORT, httpServer);
318
319 }
320
321 init();
322
323 config();
324
325 run();
326 }