Skip to content

Commit

Permalink
Merge pull request #42 from boschrexroth/bugfix/disconnect-on-sequent…
Browse files Browse the repository at this point in the history
…ial-write

Bugfix/disconnect on sequential write
  • Loading branch information
Sebastian Krauskopf committed Apr 26, 2022
2 parents 926bd56 + 48b4a01 commit 05f73cf
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 165 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -96,6 +96,7 @@ Any use of the source code and related documents of this repository in applicati
* 2022-03-02: 1.8.14 - fix: improve diagnostics for misconfigured subscriptions. E.g. when a single node of a subscription is missing (Bug449366).
* 2022-03-14: 1.8.15 - fix: make subscribe node useable on other ports than 443 (Bug457112).
fix: remove an uncaught exception which was introduced with version 1.8.14 (Bug454078).
* 2022-04-26: 1.8.16 - fix: possible connection break on heavy load for commands: create, delete, write.

## About

Expand Down
70 changes: 35 additions & 35 deletions lib/CtrlxCore.js
Expand Up @@ -170,8 +170,8 @@ class CtrlxCore {
static _parseJwt(token) {
let base64Url = token.split('.')[1];
let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));

return JSON.parse(jsonPayload);
Expand Down Expand Up @@ -222,11 +222,11 @@ class CtrlxCore {
let data = "";

res.setEncoding('utf8');
res.on('data', function(chunk) {
res.on('data', function (chunk) {
data += chunk;
});

res.on('end', function() {
res.on('end', function () {

// We expect statusCode 201 if authentication was successful.
if (res.statusCode === 201) {
Expand Down Expand Up @@ -275,7 +275,7 @@ class CtrlxCore {
headers: {
'Authorization': tokenType + ' ' + token,
'Connection': 'close',
},
},
rejectUnauthorized: false // accept self-signed certificates
};

Expand Down Expand Up @@ -358,7 +358,7 @@ class CtrlxCore {
*/
async logIn() {

return new Promise( (resolve, reject) => {
return new Promise((resolve, reject) => {

debug(`logIn(${this._hostname})`);

Expand All @@ -367,9 +367,9 @@ class CtrlxCore {

this.logOut()
// After we logged out, we login. Regardless if logout was done correct or not.
.then(() => {return this.logIn()}, () => {return this.logIn()})
.then(() => { return this.logIn() }, () => { return this.logIn() })
// Resolve the original promise with the result of the new login promise.
.then((result) => {resolve(result);}, (err) => {reject(err);});
.then((result) => { resolve(result); }, (err) => { reject(err); });
return;
}

Expand Down Expand Up @@ -512,7 +512,7 @@ class CtrlxCore {
// Login first, then make a new read promise to resolve the original promise.
this.logIn().then(() => { return this.datalayerRead(path, data, type); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); });
.catch((err) => { reject(err); });

return;
}
Expand All @@ -527,22 +527,22 @@ class CtrlxCore {
type,
this._timeout,
(err, data) => {
if (err) {
// If automatic reconnect is enabled, then we try one login attempt and then try again.
if (err.status === 401 && this._autoReconnect) {
debug(`datalayerRead(${type}) RECONNECT`);
this.logIn().then(() => { return this.datalayerRead(path, data, type); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
} else {
debug(`datalayerRead(${type}) ERROR`);
reject(err);
}
if (err) {
// If automatic reconnect is enabled, then we try one login attempt and then try again.
if (err.status === 401 && this._autoReconnect) {
debug(`datalayerRead(${type}) RECONNECT`);
this.logIn().then(() => { return this.datalayerRead(path, data, type); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
} else {
debug(`datalayerRead(${type}) DONE`);
resolve(data);
debug(`datalayerRead(${type}) ERROR`);
reject(err);
}
} else {
debug(`datalayerRead(${type}) DONE`);
resolve(data);
}
});

});
Expand Down Expand Up @@ -578,7 +578,7 @@ class CtrlxCore {
// Login first, then make a new read promise to resolve the original promise.
this.logIn().then(() => { return this.datalayerWrite(path, data); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); });
.catch((err) => { reject(err); });

return;
}
Expand All @@ -598,8 +598,8 @@ class CtrlxCore {
debug(`datalayerWrite() RECONNECT`);
this.logIn().then(() => { return this.datalayerWrite(path, data); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
} else {
reject(err);
debug('datalayerWrite() ERROR');
Expand Down Expand Up @@ -671,7 +671,7 @@ class CtrlxCore {
// Login first, then make a new create promise to resolve the original promise.
this.logIn().then(() => { return this.datalayerCreate(path, data); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); });
.catch((err) => { reject(err); });

return;
}
Expand All @@ -691,8 +691,8 @@ class CtrlxCore {
debug(`datalayerCreate() RECONNECT`);
this.logIn().then(() => { return this.datalayerCreate(path, data); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
} else {
reject(err);
debug('datalayerCreate() ERROR');
Expand Down Expand Up @@ -735,7 +735,7 @@ class CtrlxCore {
// Login first, then make a new delete promise to resolve the original promise.
this.logIn().then(() => { return this.datalayerDelete(path); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); });
.catch((err) => { reject(err); });

return;
}
Expand All @@ -754,8 +754,8 @@ class CtrlxCore {
debug(`datalayerDelete() RECONNECT`);
this.logIn().then(() => { return this.datalayerDelete(path); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
} else {
reject(err);
debug('datalayerDelete() ERROR');
Expand Down Expand Up @@ -801,7 +801,7 @@ class CtrlxCore {
// Login first, then make a new read promise to resolve the original promise.
this.logIn().then(() => { return this.datalayerSubscribe(paths); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); });
.catch((err) => { reject(err); });

return;
}
Expand All @@ -816,8 +816,8 @@ class CtrlxCore {
debug(`datalayerSubscribe(${paths}) RECONNECT`);
this.logIn().then(() => { return this.datalayerSubscribe(paths); })
.then((result) => { resolve(result); })
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
.catch((err) => { reject(err); })
.finally(() => { this._state = STATE_LOGGED_IN; });
} else {
debug(`datalayerSubscribe(${paths}) ERROR`);
reject(err);
Expand Down
4 changes: 2 additions & 2 deletions lib/CtrlxDatalayerSubscription.js
Expand Up @@ -131,7 +131,7 @@ class CtrlxDatalayerSubscription extends EventEmitter {
headers: {
'Authorization': this._authorization, // forward the authorization token
},
errorFilter: function(e) { // note: will be called for e.type='error' as well as e.type='end'
errorFilter: function (e) { // note: will be called for e.type='error' as well as e.type='end'
// will try reconnect on true.
if (sub._noInternalReconnect) {
return false; // reconnect of lib is disabled. Has to be handled by caller
Expand Down Expand Up @@ -231,7 +231,7 @@ class CtrlxDatalayerSubscription extends EventEmitter {

if (!this.emit('update', payload, e.lastEventId)) {
// Listener seems not yet to be attached. Retry on next tick.
setTimeout(()=>this.emit('update', payload, e.lastEventId), 0);
setTimeout(() => this.emit('update', payload, e.lastEventId), 0);
}
});

Expand Down
61 changes: 32 additions & 29 deletions lib/CtrlxDatalayerV1.js
Expand Up @@ -89,7 +89,8 @@ class CtrlxDatalayer {
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData)
},
},
agent: keepAliveAgent,
rejectUnauthorized: false // accept self-signed certificates
};

Expand All @@ -101,11 +102,11 @@ class CtrlxDatalayer {
let data = "";

res.setEncoding('utf8');
res.on('data', function(chunk) {
res.on('data', function (chunk) {
data += chunk;
});

res.on('end', function() {
res.on('end', function () {

// We expect 200 or 201 on success
if (res.statusCode !== 200 && res.statusCode !== 201) {
Expand Down Expand Up @@ -168,7 +169,8 @@ class CtrlxDatalayer {
'Accept': 'application/json',
'Authorization': authorization,
'Connection': 'keep-alive'
},
},
agent: keepAliveAgent,
rejectUnauthorized: false // accept self-signed certificates
};

Expand All @@ -180,11 +182,11 @@ class CtrlxDatalayer {
let data = "";

res.setEncoding('utf8');
res.on('data', function(chunk) {
res.on('data', function (chunk) {
data += chunk;
});

res.on('end', function() {
res.on('end', function () {

// We expect 200 or 204 on success
if (res.statusCode !== 200 && res.statusCode !== 204) {
Expand All @@ -209,23 +211,23 @@ class CtrlxDatalayer {
}


/**
* Read a value from the Data Layer.
*
* @static
* @param {string} hostname - The hostname of the device. Can also be a ipv4-, ipv6-address or 'localhost'.
* @param {number} port - The port of the server socket on the device. Usually 443 (https).
* @param {string} servername - The TLS servername of the device as defined by RFC 6066. Empty string in case of an ip-address.
* @param {string} authorization - The full authorization header, usually Bearer with token. Note, that this needs to be a valid session token on the given hostname.
* @param {string} path - The datalayer path, that you want to access.
* @param {*|undefined} data - Data to be tansfered in case of a read request with input data. Set to undefined in no input data (default).
* @param {string} type - The type of information you want to read. Either 'data', 'metadata' or 'browse'.
* @param {number} timeout - Request timeout in milliseconds. Set to -1 to use defaults.
* @param {function} callback(err, data) - After the read, the callback will be called.
* @memberof CtrlxDatalayer
* @throws {CtrlxProblemError} Throws an error when device returns an error.
* @throws Throws different http errors when connection could not be established.
*/
/**
* Read a value from the Data Layer.
*
* @static
* @param {string} hostname - The hostname of the device. Can also be a ipv4-, ipv6-address or 'localhost'.
* @param {number} port - The port of the server socket on the device. Usually 443 (https).
* @param {string} servername - The TLS servername of the device as defined by RFC 6066. Empty string in case of an ip-address.
* @param {string} authorization - The full authorization header, usually Bearer with token. Note, that this needs to be a valid session token on the given hostname.
* @param {string} path - The datalayer path, that you want to access.
* @param {*|undefined} data - Data to be tansfered in case of a read request with input data. Set to undefined in no input data (default).
* @param {string} type - The type of information you want to read. Either 'data', 'metadata' or 'browse'.
* @param {number} timeout - Request timeout in milliseconds. Set to -1 to use defaults.
* @param {function} callback(err, data) - After the read, the callback will be called.
* @memberof CtrlxDatalayer
* @throws {CtrlxProblemError} Throws an error when device returns an error.
* @throws Throws different http errors when connection could not be established.
*/
static read(hostname, port, servername, authorization, path, data = undefined, type, timeout, callback) {

let options = {
Expand All @@ -238,7 +240,7 @@ class CtrlxDatalayer {
'Accept': 'application/json',
'Authorization': authorization,
'Connection': 'keep-alive'
},
},
agent: keepAliveAgent,
rejectUnauthorized: false // accept self-signed certificates
};
Expand All @@ -258,11 +260,11 @@ class CtrlxDatalayer {
let data = "";

res.setEncoding('utf8');
res.on('data', function(chunk) {
res.on('data', function (chunk) {
data += chunk;
});

res.on('end', function() {
res.on('end', function () {

// We expect 200 on success
if (res.statusCode !== 200) {
Expand Down Expand Up @@ -330,7 +332,8 @@ class CtrlxDatalayer {
'Connection': 'keep-alive',
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(putData)
},
},
agent: keepAliveAgent,
rejectUnauthorized: false // accept self-signed certificates
};

Expand All @@ -342,11 +345,11 @@ class CtrlxDatalayer {
let data = "";

res.setEncoding('utf8');
res.on('data', function(chunk) {
res.on('data', function (chunk) {
data += chunk;
});

res.on('end', function() {
res.on('end', function () {

// We expect 200 on success
if (res.statusCode !== 200) {
Expand Down

0 comments on commit 05f73cf

Please sign in to comment.