blob: 970c1831506dca2edd7ea01d31c378f0ed5e6e3a [file] [log] [blame]
TamasBakai9b780332019-02-15 08:38:16 +00001var http = require('http');
2var https = require('https');
3
4var express = require('express');
5const stream = require('stream');
6var app = express();
7var fs = require("fs");
8var path = require('path');
BjornMagnussonXA42dcb262019-04-26 19:29:54 +00009const sleep = (milliseconds) => {
10 return new Promise(resolve => setTimeout(resolve, milliseconds))
11}
BjornMagnussonXAf4e18362019-04-10 13:04:08 +000012var ArgumentParser = require('argparse').ArgumentParser;
TamasBakai9b780332019-02-15 08:38:16 +000013var privateKey = fs.readFileSync('cert/private.key', 'utf8');
14var certificate = fs.readFileSync('cert/certificate.crt', 'utf8');
15var credentials = {key: privateKey, cert: certificate};
16
BjornMagnussonXAf4e18362019-04-10 13:04:08 +000017
TamasBakai9b780332019-02-15 08:38:16 +000018var bodyParser = require('body-parser')
BjornMagnussonXAf4e18362019-04-10 13:04:08 +000019var startTime = Date.now();
20
21var dr_callback_ip = '192.168.100.2'; //IP for DR when running as container. Can be changed by env DR_SIM_IP
22
23//Counters
24var ctr_publish_requests = 0;
25var ctr_publish_responses = 0;
26var lastPublish = "";
27var dwl_volume = 0;
28
29var parser = new ArgumentParser({
30 version: '0.0.1',
31 addHelp:true,
32 description: 'Datarouter redirect simulator'
33 });
34
35parser.addArgument('--tc' , { help: 'TC $NoOfTc' } );
36parser.addArgument('--printtc' ,
37 {
38 help: 'Print complete usage help',
39 action: 'storeTrue'
40 }
41 );
42
43var args = parser.parseArgs();
44const tc_normal = "normal";
45const tc_no_publish ="no_publish"
46const tc_10p_no_response = "10p_no_response";
47const tc_10first_no_response = "10first_no_response";
48const tc_100first_no_response = "100first_no_response";
BjornMagnussonXA42dcb262019-04-26 19:29:54 +000049const tc_all_delay_1s = "all_delay_1s";
BjornMagnussonXAf4e18362019-04-10 13:04:08 +000050const tc_all_delay_10s = "all_delay_10s";
51const tc_10p_delay_10s = "10p_delay_10s";
52const tc_10p_error_response = "10p_error_response";
53const tc_10first_error_response = "10first_error_response";
54const tc_100first_error_response = "100first_error_response";
55
56if (args.tc==tc_normal) {
57 console.log("TC: " + args.tc)
58
59} else if (args.tc==tc_no_publish) {
60 console.log("TC: " + args.tc)
61
62} else if (args.tc==tc_10p_no_response) {
63 console.log("TC: " + args.tc)
64
65} else if (args.tc==tc_10first_no_response) {
66 console.log("TC: " + args.tc)
67
68} else if (args.tc==tc_100first_no_response) {
69 console.log("TC: " + args.tc)
70
BjornMagnussonXA42dcb262019-04-26 19:29:54 +000071} else if (args.tc==tc_all_delay_1s) {
72 console.log("TC: " + args.tc)
73
74 } else if (args.tc==tc_all_delay_10s) {
BjornMagnussonXAf4e18362019-04-10 13:04:08 +000075 console.log("TC: " + args.tc)
76
77} else if (args.tc==tc_10p_delay_10s) {
78 console.log("TC: " + args.tc)
79
80} else if (args.tc==tc_10p_error_response) {
81 console.log("TC: " + args.tc)
82
83} else if (args.tc==tc_10first_error_response) {
84 console.log("TC: " + args.tc)
85
86} else if (args.tc==tc_100first_error_response) {
87 console.log("TC: " + args.tc)
88} else {
89 console.log("No TC specified, use: --tc <tc-id>");
90 process.exit(0);
91}
92
93if (args.printtc) {
94 console.log("TC " + tc_normal + ": Normal case, all files publish and DR updated");
95 console.log("TC " + tc_no_publish + ": Ok response but no files published");
96 console.log("TC " + tc_10p_no_response + ": 10% % no response (file not published)");
97 console.log("TC " + tc_10first_no_response + ": 10 first requests give no response (files not published)");
98 console.log("TC " + tc_100first_no_response + ": 100 first requests give no response (files not published)");
BjornMagnussonXA42dcb262019-04-26 19:29:54 +000099 console.log("TC " + tc_all_delay_1s + ": All responses delayed 1s, normal publish");
BjornMagnussonXAf4e18362019-04-10 13:04:08 +0000100 console.log("TC " + tc_all_delay_10s + ": All responses delayed 10s, normal publish");
101 console.log("TC " + tc_10p_delay_10s + ": 10% of responses delayed 10s, normal publish");
102 console.log("TC " + tc_10p_error_response + ": 10% error response (file not published)");
103 console.log("TC " + tc_10first_error_response + ": 10 first requests give error response (file not published)");
104 console.log("TC " + tc_100first_error_response + ": 100 first requests give error responses (file not published)");
105
106 process.exit(0);
107}
TamasBakai9b780332019-02-15 08:38:16 +0000108
109// parse application/x-www-form-urlencoded
110app.use(bodyParser.urlencoded({ extended: false }))
111
112// parse application/json
113app.use(bodyParser.json())
114
115// parse application/vnd.api+json as json
116app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
117
118// parse some custom thing into a Buffer
BjornMagnussonXAf4e18362019-04-10 13:04:08 +0000119app.use(bodyParser.raw({limit:1024*1024*60, type: 'application/octet-stream' }))
TamasBakai9b780332019-02-15 08:38:16 +0000120
121// parse an HTML body into a string
122app.use(bodyParser.text({ type: 'text/html' }))
BjornMagnussonXAf4e18362019-04-10 13:04:08 +0000123
124//Formatting
125function fmtMSS(s){
126 return(s-(s%=60))/60+(9<s?':':':0')+s //Format time diff to mm:ss
127}
128function fmtLargeNumber(x) {
129 return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " "); //Format large with space, eg: 1 000 000
130}
131
132//I'm alive function
TamasBakai9b780332019-02-15 08:38:16 +0000133app.get("/",function(req, res){
134 res.send("ok");
135})
136
BjornMagnussonXAf4e18362019-04-10 13:04:08 +0000137//Counter readout
138app.get("/ctr_publish_requests",function(req, res){
139 res.send(""+ctr_publish_requests);
TamasBakai9b780332019-02-15 08:38:16 +0000140})
BjornMagnussonXAf4e18362019-04-10 13:04:08 +0000141app.get("/ctr_publish_responses",function(req, res){
142 res.send(""+ctr_publish_responses);
143})
144app.get("/execution_time",function(req, res){
145 diff = fmtMSS(Math.floor((Date.now()-startTime)/1000));
146 res.send(""+diff);
147})
148app.get("/time_lastpublish",function(req, res){
149 res.send(""+lastPublish);
150})
151app.get("/dwl_volume",function(req, res){
152 res.send(""+fmtLargeNumber(dwl_volume));
153})
154app.get("/tc_info",function(req, res){
155 res.send(args.tc);
156})
157
158app.put('/publish/1/:filename', function (req, res) {
159 console.log(req.url);
160 console.log("First 25 bytes of body: " + req.body.slice(0,25))
161 console.log(req.headers)
162 ctr_publish_requests++;
163 if (args.tc == tc_no_publish) {
164 tr_publish_responses++;
165 res.send("ok")
166 return;
167 } else if (args.tc==tc_10p_no_response && (ctr_publish_requests%10)==0) {
168 return;
169 } else if (args.tc==tc_10first_no_response && ctr_publish_requests<11) {
170 return;
171 } else if (args.tc==tc_100first_no_response && ctr_publish_requests<101) {
172 return;
173 } else if (args.tc==tc_10p_error_response && (ctr_publish_requests%10)==0) {
174 tr_publish_responses++;
175 res.send(400, "");
176 return;
177 } else if (args.tc==tc_10first_error_response && ctr_publish_requests<11) {
178 tr_publish_responses++;
179 res.send(400, "");
180 return;
181 } else if (args.tc==tc_100first_error_response && ctr_publish_requests<101) {
182 tr_publish_responses++;
183 res.send(400, "");
184 return;
BjornMagnussonXAf4e18362019-04-10 13:04:08 +0000185 }
186
187 //Remaining part if normal file publish
188
189 var filename = req.params.filename;
190 console.log(filename);
191 //Create filename (appending file size to name) to store
192 var storedFilename = path.resolve(__dirname, filename+"-"+req.body.length);
193 fs.writeFile(storedFilename, "", function (error) { //Store file with zero size
194 if (error) { console.error(error); }
195 });
196
197 //Make callback to update list of publish files in DR sim
198 //Note the hard code ip-adress, DR sim get this ip if simulators started from the
199 //script in the 'simulatorgroup' dir.
200 //Work around: Could not get a normal http put to work from nodejs, using curl instead
201 var util = require('util');
202 var exec = require('child_process').exec;
203
204 var command = 'curl -s -X PUT http://' + dr_callback_ip + ':3906/dr_redir_publish/' +req.params.filename;
205
206 console.log("Callback to DR sim to report file published, cmd: " + command);
207 child = exec(command, function(error, stdout, stderr){
208 console.log('stdout: ' + stdout);
209 console.log('stderr: ' + stderr);
210 if(error !== null) {
211 console.log('exec error: ' + error);
212 }
213
214 });
215
216 //Update status variables
217 ctr_publish_responses++;
218 lastPublish = fmtMSS(Math.floor((Date.now()-startTime)/1000));
219 dwl_volume = dwl_volume + req.body.length;
220
BjornMagnussonXA42dcb262019-04-26 19:29:54 +0000221 if (args.tc==tc_10p_delay_10s && (ctr_publish_requests%10)==0) {
222 sleep(10000).then(() => {
223 res.send("ok");
224 });
225 return;
226 } else if (args.tc==tc_all_delay_10s) {
227 sleep(10000).then(() => {
228 res.send("ok");
229 });
230 return;
231 } else if (args.tc==tc_all_delay_1s) {
232 sleep(1000).then(() => {
233 res.send("ok");
234 });
235 return;
236 }
BjornMagnussonXAf4e18362019-04-10 13:04:08 +0000237 res.send("ok")
238});
239
240
TamasBakai9b780332019-02-15 08:38:16 +0000241var httpServer = http.createServer(app);
242var httpsServer = https.createServer(credentials, app);
243
244var httpPort=3908
245var httpsPort=3909
246httpServer.listen(httpPort);
247console.log("DR-simulator listening (http) at "+httpPort)
248httpsServer.listen(httpsPort);
249console.log("DR-simulator listening (https) at "+httpsPort)
250
BjornMagnussonXAf4e18362019-04-10 13:04:08 +0000251if (process.env.DR_SIM_IP) {
252 dr_callback_ip=process.env.DR_SIM_IP;
253}
254console.log("Using IP " + dr_callback_ip + " for callback to DR sim");