5 * Copyright 2016 RIFT.IO Inc
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * Main skyquake module.
24 * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
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');
35 for (var i
= 0; i
< constants
.SOCKET_POOL_LENGTH
; i
++) {
36 freePorts
[i
] = constants
.SOCKET_BASE_PORT
+ i
;
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
) {
47 port
: freePorts
.shift()
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
);
57 cluster
.on('online', function(worker
) {
58 console
.log("Worker Started pid : " + worker
.process
.pid
);
60 cluster
.on('exit', function(worker
, code
, signal
) {
61 console
.log('worker ' + worker
.process
.pid
+ ' stopped');
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');
78 require('require-json');
80 // SSL related configuration bootstrap
81 var httpServer
= null;
82 var secureHttpServer
= null;
84 var httpsConfigured
= false;
86 var sslOptions
= null;
88 var apiServer
= argv
['api-server'] ? argv
['api-server'] : 'localhost';
89 var uploadServer
= argv
['upload-server'] ? argv
['upload-server'] : null;
92 if (argv
['enable-https']) {
93 var keyFilePath
= argv
['keyfile-path'];
94 var certFilePath
= argv
['certfile-path'];
97 key
: fs
.readFileSync(keyFilePath
),
98 cert
: fs
.readFileSync(certFilePath
)
101 httpsConfigured
= true;
104 console
.log('HTTPS enabled but file paths missing/incorrect');
105 process
.exit(code
= -1);
110 app
.set('views', __dirname
+ '/framework/core/views');
111 app
.engine('html', require('ejs').renderFile
);
114 secret
: 'ritio rocks',
116 saveUninitialized
: true
118 app
.use(bodyParser
.json());
120 app
.use(bodyParser
.urlencoded({
124 var socketManager
= new Sockets();
126 httpsConfigured
: httpsConfigured
129 if (httpsConfigured
) {
130 socketConfig
.sslOptions
= sslOptions
;
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');
147 * Processing when a plugin is added or modified
148 * @param {string} plugin_name - Name of the plugin
150 function onPluginAdded(plugin_name
) {
151 // Load plugin config
152 var plugin_config
= reload('./plugins/' + plugin_name
+ '/config.json');
154 // Load all app's views
155 app
.use('/' + plugin_name
, express
.static('./plugins/' + plugin_name
+ '/' + plugin_config
.root
));
157 // Load all app's routes
158 app
.use('/' + plugin_name
, require('./plugins/' + plugin_name
+ '/routes'));
160 // Publish navigation links
161 if (plugin_config
.routes
&& _
.isArray(plugin_config
.routes
)) {
162 skyquakeEmitter
.emit('config_discoverer.navigation_discovered', plugin_name
, plugin_config
);
170 app
.use('/jquery', express
.static('./node_modules/jquery/dist/jquery.min.js'));
174 app
.use('/img', express
.static('./framework/style/img'));
177 * Start listening on a port
178 * @param {string} port - Port to listen on
179 * @param {object} httpServer - httpServer created with http(s).createServer
181 function startListening(port
, httpServer
) {
182 var server
= httpServer
.listen(port
, function () {
183 var host
= server
.address().address
;
185 var port
= server
.address().port
;
187 console
.log('Express server listening on port', port
);
193 * Initialize skyquake
196 skyquakeEmitter
.on('plugin_discoverer.plugin_discovered', onPluginAdded
);
197 skyquakeEmitter
.on('plugin_discoverer.plugin_updated', onPluginAdded
);
204 // Conigure any globals
205 process
.env
.NODE_TLS_REJECT_UNAUTHORIZED
=0;
207 // Configure navigation router
208 app
.use(navigation_routes
);
210 // Configure restconf router
211 app
.use(restconf_routes
);
213 //Configure inactivity route(s)
214 app
.use(inactivity_routes
);
216 // Configure global config with ssl enabled/disabled
218 ssl_enabled
: httpsConfigured
,
219 api_server
: apiServer
223 globalConfig
.upload_server
= uploadServer
;
226 configurationAPI
.globalConfiguration
.update(globalConfig
);
228 // Configure configuration route(s)
229 app
.use(configuration_routes
);
231 //Configure descriptor route(s)
232 app
.use(descriptor_routes
);
234 //Configure user management route(s)
235 app
.use(userManagement_routes
);
237 //Configure project management route(s)
238 app
.use(projectManagement_routes
);
240 //Configure session route(s)
241 app
.use(session_routes
);
243 // app.get('/testme', function(req, res) {
244 // res.sendFile(__dirname + '/index.html');
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
);
256 res
.writeHead(301, { "Location": "https://" + host
+ req
.url
});
260 socketConfig
.httpServer
= secureHttpServer
;
262 httpServer
= http
.createServer(app
);
263 socketConfig
.httpServer
= httpServer
;
266 // Configure socket manager
267 socketManager
.configure(socketConfig
);
269 // Configure socket router
270 socket_routes
.routes(socketManager
);
271 app
.use(socket_routes
.router
);
273 // Serve multiplex-client
274 app
.get('/multiplex-client', function(req
, res
) {
275 res
.sendFile(__dirname
+ '/node_modules/websocket-multiplex/multiplex_client.js');
278 // handle requests for gzip'd files
279 app
.get('*gzip*', function (req
, res
, next
) {
280 res
.set('Content-Encoding', 'gzip');
287 * Run skyquake functionality
291 // Start plugin_discoverer
292 var navigation_manager
= require('./framework/core/modules/navigation_manager');
293 var plugin_discoverer
= require('./framework/core/modules/plugin_discoverer');
295 // Initialize asynchronous modules
296 navigation_manager
.init();
297 plugin_discoverer
.init();
299 // Configure asynchronous modules
300 navigation_manager
.config()
301 plugin_discoverer
.config({
302 plugins_path
: './plugins'
305 // Run asynchronous modules
306 navigation_manager
.run();
307 plugin_discoverer
.run();
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
);
316 // Start listening on SERVER_PORT (8000)
317 var server
= startListening(constants
.SERVER_PORT
, httpServer
);