Reload App Script
davidgutierrez opened this issue · 6 comments
Description
I been working in a Script that allows the reload of an app under petition, but im getting a "socket hang up". error:
Steps to Reproduce
Script Used:
/* eslint import/no-unresolved:0, import/extensions:0, no-console:0 */
const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');
const path = require('path');
const fs = require('fs');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var args = process.argv.slice(2)
var urlws = args[0]; // path
var nombreDoc = args[1];
var userDir = args[2]; // The Sense Enterprise-configured user directory
// for the user you want to identify as
var userId = args[3]; // The user to use when creating the session
var certPath = args[4]; // Path to a local folder containing the Sense
// Enterprise exported certificates
var readCert = filename => fs.readFileSync(path.resolve(__dirname, certPath, filename));
// Helper function to read the contents of the certificate files:
var certificates = {
cert: fs.readFileSync(path.resolve(certPath, 'client.pem')),
key: fs.readFileSync(path.resolve(certPath, 'client_key.pem')),
root: fs.readFileSync(path.resolve(certPath, 'root.pem'))
};
var session = enigma.create({
schema,
url: `${urlws}`,
// Notice the non-standard second parameter here, this is how you pass in
// additional configuration to the 'ws' npm library, if you use a different
// library you may configure this differently:
createSocket: url => new WebSocket(url, {
ca: [certificates.root],
cert: certificates.cert,
key: certificates.key,
headers: {
'X-Qlik-User': `UserDirectory=${encodeURIComponent(userDir)}; UserId=${encodeURIComponent(userId)}`,
},
}),
});
start();
function start(){
var docId = '';
// bind traffic events to log what is sent and received on the socket:
session.on('traffic:sent', data => console.log('sent:', data));
session.on('traffic:received', data => console.log('received:', data));
session.open()
.then( (global) => {
var docList =global.getDocList();
docList.then(function(docList) {
console.log('Reloaded',nombreDoc);
docId = docList.filter(obj => obj.qTitle ==nombreDoc )[0].qDocId;
console.log(docId);
global.openDoc(docId).then((app) => {reload(app)})
.catch((err) => {
console.log(err);
process.exit(1);
});
}).catch((error) => {
console.log('Error using docList:', error);
process.exit(1);
});
})
.catch((error) => {
console.log('Error using global:', error);
process.exit(1);
});
}
async function reload(app){
await app.doReload();
console.log('Completed');
save(app);
}
function save(app){
app.doSave().then(function (value) {
console.log('save promise returned',value);
session.close();
}, function(reason) {
setTimeout(() =>{
console.log('razon',reason);
guardar(app);
},50000);
})
}
Is called from a console using this command:
node reloadApp.js wss://<<IP QLIK ENTERPRISE>>:4747/app/engineData "<<APP NAME>>" "<<user directory>>" "<<USER>>" "./"
Expected behavior
This must uptate the apication.
Actual behavior
Error using global: ErrorEvent {
target: WebSocket {
_events: [Object: null prototype] {
open: [Function],
close: [Function],
error: [Function],
message: [Function]
},
_eventsCount: 4,
_maxListeners: undefined,
readyState: 3,
protocol: '',
_binaryType: 'nodebuffer',
_closeFrameReceived: false,
_closeFrameSent: false,
_closeMessage: '',
_closeTimer: null,
_closeCode: 1006,
_extensions: {},
_receiver: null,
_sender: null,
_socket: null,
_bufferedAmount: 0,
_isServer: false,
_redirects: 0,
url: 'wss://<<IP QLIK ENTERPRISE>>:4747/app/engineData',
_req: null
},
type: 'error',
message: 'socket hang up',
error: Error: socket hang up
at connResetException (internal/errors.js:570:14)
at TLSSocket.socketOnEnd (_http_client.js:440:23)
at TLSSocket.emit (events.js:215:7)
at endReadableNT (_stream_readable.js:1184:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
code: 'ECONNRESET'
}
}
Environment
Library
[X ] Node.js
[ ] Browser
Operating system
[X ] Windows
[ ] OSX
[ X] Linux
Qlik Sense
[ ] Desktop
[ X] Enterprise
Versions
- Node.js: v12.14.0
- Browser:
- Qlik Sense: April 2020
- Operating system: Windows 10 and Ubuntu Linux.
I'm having a similar issue but surely not the same. I don't want to hijack your issue, just sharing.
I'm getting an "Error: Socket closed. (onMaxParallelSessionsExceeded)" but I'm consistently closing it for every single session.
session.on('opened', () => { global.semaphore++; console.log('opened: ${this.semaphore}'); });
session.on('closed', () => { global.semaphore--; console.log('closed: ${this.semaphore}'); });
this never exceeds 1.
Node.js + Qlik Sense April 2020 + Windows .
@davidgutierrez When do you get "socket hang up". I tried against a Qlik Sense Enterprise and can't reproduce this behaviour
Did a small change to make the whole script async
const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');
const path = require('path');
const fs = require('fs');
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var args = process.argv.slice(2)
var urlws = args[0];
var nombreDoc = args[1];
var userDir = args[2];
var userId = args[3];
var certPath = args[4];
var session = enigma.create({
schema,
url: `${urlws}`,
createSocket: url => new WebSocket(url, {
ca: fs.readFileSync(path.resolve(certPath, 'root.pem')),
cert: fs.readFileSync(path.resolve(certPath, 'client.pem')),
key: fs.readFileSync(path.resolve(certPath, 'client_key.pem')),
headers: {
'X-Qlik-User': `UserDirectory=${encodeURIComponent(userDir)}; UserId=${encodeURIComponent(userId)}`,
},
}),
});
(async () => {
const global = await session.open();
const docList = await global.getDocList();
docId = docList.filter(obj => obj.qTitle == nombreDoc)[0].qDocId;
console.log(`\nStarting to RELOAD the app '${nombreDoc}' with 'docId'=${docId}`);
const app = await global.openDoc(docId);
console.log(`\t- Opening the app`);
await app.doReload();
console.log(`\t- Reloading the app`);
await app.doSave();
console.log(`\t- Saving the app`);
const appInfo = await app.getAppProperties();
console.log(`The app '${nombreDoc}' was last reloaded at:${appInfo.qLastReloadTime}`);
session.close();
console.log(`Closing the session`);
})().catch(err => {
console.error(err);
});
@willenjs when connecting through the Qlik Sense Proxy the closed sockets are quarantined for some time before they can be "re-used". This is for preventing misusage of the license model.
I'm not sure what the "cool-down" time is for closed connections.
If you need more connection simultaneous you could use certificates and connect directly to the engine
Thank you very much @axelssonHakan . The default 'cool-down' seems to be something around ~5 mins.
I will definitely change it to certificates or jwt?.
Marking this as resolved and closing issue
it worked very well
/* eslint import/no-unresolved:0, import/extensions:0, no-console:0 */
const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');
const path = require('path');
const fs = require('fs');
//process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var args = process.argv.slice(2)
var urlws = args[0];
var nombreDoc = args[1];
var userDir = args[2];
var userId = args[3];
var certPath = args[4];
var session = enigma.create({
schema,
url: urlws,
createSocket: url => new WebSocket(url, {
ca: fs.readFileSync(path.resolve(certPath, 'root.pem')),
cert: fs.readFileSync(path.resolve(certPath, 'client.pem')),
key: fs.readFileSync(path.resolve(certPath, 'client_key.pem')),
headers: {
'X-Qlik-User': `UserDirectory=${encodeURIComponent(userDir)}; UserId=${encodeURIComponent(userId)}`,
},
}),
});
(async () => {
const global = await session.open();
const docList = await global.getDocList();
console.log(docList);
docId = docList.filter(obj => obj.qTitle == nombreDoc)[0].qDocId;
console.log(`\nStarting to RELOAD the app ${nombreDoc} with docId=${docId}`);
const app = await global.openDoc(docId);
console.log('\t- Opening the app');
await app.doReload();
console.log('\t- Reloading the app');
await app.doSave();
console.log('\t- Saving the app');
const appInfo = await app.getAppProperties();
console.log(`The app ${nombreDoc} was last reloaded at:${appInfo.qLastReloadTime}`);
session.close();
console.log('Closing the session');
})().catch(err => {
console.error(err);
});
i just made a small changes to your code.
And found that the problem the "socket hang up" is more that the certificates are not longer working outside of the server... is more a configuration of the server problem.