3 * Copyright 2016 RIFT.IO Inc
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 * Main skyquake module.
22 * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
25 // Standard library imports for forking
26 var cluster
= require("cluster");
27 var cpu
= require('os').cpus().length
;
28 var clusteredLaunch
= process
.env
.CLUSTER_SUPPORT
|| false;
29 var constants
= require('./framework/core/api_utils/constants');
30 // Uncomment for Replay support
31 // const Replay = require('replay');
33 for (var i
= 0; i
< constants
.SOCKET_POOL_LENGTH
; i
++) {
34 freePorts
[i
] = constants
.SOCKET_BASE_PORT
+ i
;
38 if (cluster
.isMaster
&& clusteredLaunch
) {
39 console
.log(cpu
, 'CPUs found');
40 for (var i
= 0; i
< cpu
; i
++) {
41 var worker
= cluster
.fork();
42 worker
.on('message', function(msg
) {
43 if (msg
&& msg
.getPort
) {
45 port
: freePorts
.shift()
47 console
.log('freePorts after shift for worker', this.process
.pid
, ':', freePorts
);
48 } else if (msg
&& msg
.freePort
) {
49 freePorts
.unshift(msg
.port
);
50 console
.log('freePorts after unshift of', msg
.port
, 'for worker', this.process
.pid
, ':', freePorts
);
55 cluster
.on('online', function(worker
) {
56 console
.log("Worker Started pid : " + worker
.process
.pid
);
58 cluster
.on('exit', function(worker
, code
, signal
) {
59 console
.log('worker ' + worker
.process
.pid
+ ' stopped');
62 // Standard library imports
63 var argv
= require('minimist')(process
.argv
.slice(2));
64 var pid
= process
.pid
;
65 var fs
= require('fs');
66 var https
= require('https');
67 var http
= require('http');
68 var express
= require('express');
69 var session
= require('express-session');
70 var cors
= require('cors');
71 var bodyParser
= require('body-parser');
72 var _
= require('lodash');
73 var reload
= require('require-reload')(require
);
74 var Sockets
= require('./framework/core/api_utils/sockets.js');
76 require('require-json');
78 // SSL related configuration bootstrap
79 var httpServer
= null;
80 var secureHttpServer
= null;
82 var httpsConfigured
= false;
84 var sslOptions
= null;
86 var apiServer
= argv
['api-server'] ? argv
['api-server'] : 'localhost';
87 var uploadServer
= argv
['upload-server'] ? argv
['upload-server'] : null;
90 if (argv
['enable-https']) {
91 var keyFilePath
= argv
['keyfile-path'];
92 var certFilePath
= argv
['certfile-path'];
95 key
: fs
.readFileSync(keyFilePath
),
96 cert
: fs
.readFileSync(certFilePath
)
99 httpsConfigured
= true;
102 console
.log('HTTPS enabled but file paths missing/incorrect');
103 process
.exit(code
= -1);
109 secret
: 'ritio rocks',
111 saveUninitialized
: true
113 app
.use(bodyParser
.json());
115 app
.use(bodyParser
.urlencoded({
119 var socketManager
= new Sockets();
121 httpsConfigured
: httpsConfigured
124 if (httpsConfigured
) {
125 socketConfig
.sslOptions
= sslOptions
;
128 // Rift framework imports
129 var constants
= require('./framework/core/api_utils/constants');
130 var skyquakeEmitter
= require('./framework/core/modules/skyquakeEmitter');
131 var navigation_routes
= require('./framework/core/modules/routes/navigation');
132 var socket_routes
= require('./framework/core/modules/routes/sockets');
133 var restconf_routes
= require('./framework/core/modules/routes/restconf');
134 var inactivity_routes
= require('./framework/core/modules/routes/inactivity');
135 var descriptor_routes
= require('./framework/core/modules/routes/descriptorModel');
136 var configuration_routes
= require('./framework/core/modules/routes/configuration');
137 var configurationAPI
= require('./framework/core/modules/api/configuration');
138 var userManagement_routes
= require('./framework/core/modules/routes/userManagement');
139 var projectManagement_routes
= require('./framework/core/modules/routes/projectManagement');
141 * Processing when a plugin is added or modified
142 * @param {string} plugin_name - Name of the plugin
144 function onPluginAdded(plugin_name
) {
145 // Load plugin config
146 var plugin_config
= reload('./plugins/' + plugin_name
+ '/config.json');
148 // Load all app's views
149 app
.use('/' + plugin_name
, express
.static('./plugins/' + plugin_name
+ '/' + plugin_config
.root
));
151 // Load all app's routes
152 app
.use('/' + plugin_name
, require('./plugins/' + plugin_name
+ '/routes'));
154 // Publish navigation links
155 if (plugin_config
.routes
&& _
.isArray(plugin_config
.routes
)) {
156 skyquakeEmitter
.emit('config_discoverer.navigation_discovered', plugin_name
, plugin_config
);
162 * Start listening on a port
163 * @param {string} port - Port to listen on
164 * @param {object} httpServer - httpServer created with http(s).createServer
166 function startListening(port
, httpServer
) {
167 var server
= httpServer
.listen(port
, function () {
168 var host
= server
.address().address
;
170 var port
= server
.address().port
;
172 console
.log('Express server listening on port', port
);
178 * Initialize skyquake
181 skyquakeEmitter
.on('plugin_discoverer.plugin_discovered', onPluginAdded
);
182 skyquakeEmitter
.on('plugin_discoverer.plugin_updated', onPluginAdded
);
189 // Conigure any globals
190 process
.env
.NODE_TLS_REJECT_UNAUTHORIZED
=0;
192 // Configure navigation router
193 app
.use(navigation_routes
);
195 // Configure restconf router
196 app
.use(restconf_routes
);
198 //Configure inactivity route(s)
199 app
.use(inactivity_routes
);
201 // Configure global config with ssl enabled/disabled
203 ssl_enabled
: httpsConfigured
,
204 api_server
: apiServer
208 globalConfig
.upload_server
= uploadServer
;
211 configurationAPI
.globalConfiguration
.update(globalConfig
);
213 // Configure configuration route(s)
214 app
.use(configuration_routes
);
216 //Configure descriptor route(s)
217 app
.use(descriptor_routes
);
219 //Configure user management route(s)
220 app
.use(userManagement_routes
);
222 //Configure project management route(s)
223 app
.use(projectManagement_routes
);
225 // app.get('/testme', function(req, res) {
226 // res.sendFile(__dirname + '/index.html');
229 // Configure HTTP/HTTPS server and populate socketConfig.
230 if (httpsConfigured
) {
231 console
.log('HTTPS configured. Will create 2 servers');
232 secureHttpServer
= https
.createServer(sslOptions
, app
);
233 // Add redirection on SERVER_PORT
234 httpServer
= http
.createServer(function(req
, res
) {
235 var host
= req
.headers
['host'];
236 host
= host
.replace(/:\d+$/, ":" + constants
.SECURE_SERVER_PORT
);
238 res
.writeHead(301, { "Location": "https://" + host
+ req
.url
});
242 socketConfig
.httpServer
= secureHttpServer
;
244 httpServer
= http
.createServer(app
);
245 socketConfig
.httpServer
= httpServer
;
248 // Configure socket manager
249 socketManager
.configure(socketConfig
);
251 // Configure socket router
252 socket_routes
.routes(socketManager
);
253 app
.use(socket_routes
.router
);
255 // Serve multiplex-client
256 app
.get('/multiplex-client', function(req
, res
) {
257 res
.sendFile(__dirname
+ '/node_modules/websocket-multiplex/multiplex_client.js');
262 * Run skyquake functionality
266 // Start plugin_discoverer
267 var navigation_manager
= require('./framework/core/modules/navigation_manager');
268 var plugin_discoverer
= require('./framework/core/modules/plugin_discoverer');
270 // Initialize asynchronous modules
271 navigation_manager
.init();
272 plugin_discoverer
.init();
274 // Configure asynchronous modules
275 navigation_manager
.config()
276 plugin_discoverer
.config({
277 plugins_path
: './plugins'
280 // Run asynchronous modules
281 navigation_manager
.run();
282 plugin_discoverer
.run();
286 if (httpsConfigured
) {
287 console
.log('HTTPS configured. Will start 2 servers');
288 // Start listening on SECURE_SERVER_PORT (8443)
289 var secureServer
= startListening(constants
.SECURE_SERVER_PORT
, secureHttpServer
);
291 // Start listening on SERVER_PORT (8000)
292 var server
= startListening(constants
.SERVER_PORT
, httpServer
);