Skip to content
This repository was archived by the owner on May 31, 2024. It is now read-only.

Commit da237e3

Browse files
committed
Remove augmented type field + make sendData callback optional (#5)
1 parent 5542a15 commit da237e3

File tree

6 files changed

+99
-107
lines changed

6 files changed

+99
-107
lines changed

.eslintrc

Lines changed: 0 additions & 12 deletions
This file was deleted.

.eslintrc.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
rules:
2+
semi: error
3+
quotes: [error, single, {allowTemplateLiterals: true}]
4+
indent: [error, 4]
5+
linebreak-style: [error, unix]
6+
no-console: warn
7+
env:
8+
es6: true
9+
node: true
10+
extends: eslint:recommended

LogmetProducer.js

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ module.exports = LogmetProducer;
118118
*/
119119

120120
LogmetProducer.prototype.connect = function(callback) {
121-
// Connect to Logmet so that data can be sent out
121+
// Connect to Logmet so that data can be sent out
122122
connectToMTLumberjackServer(this.endpoint, this.port, this.tenantOrSupertenantId, this.logmetToken, this.isSuperTenant, callback);
123123
};
124124

@@ -128,30 +128,32 @@ LogmetProducer.prototype.connect = function(callback) {
128128
* A call to the connectToMTLumberjackServer() function must be made before sendData() can be called.
129129
*
130130
* @param {object} data The object representing the data to be sent out to Logmet
131-
* @param {string} type The type that identifies the data
132-
* @param {function} callback(error, data) A callback function that is called to notify the caller of the operation result
133131
* @param {string} tenantId The id of the tenant who owns the data
132+
* @param {function} (optional) callback(error, data) A callback function that is called to notify the caller of the operation result
134133
*/
135-
LogmetProducer.prototype.sendData = function(data, type, tenantId, callback) {
134+
LogmetProducer.prototype.sendData = function(data, tenantId, callback) {
136135

137136
var activeConnection = socketWrapper.state === State.CONNECTED;
138137

139138
if (pendingDataElements.length >= MAX_PENDING_ELEMENTS) {
140-
// Our buffer is full. Apply back pressure.
139+
// Our buffer is full. Apply back pressure.
141140
logger.warn('Buffer of data elements is full. Rejecting new data. Connection state: ' + socketWrapper.state);
142-
callback('ERROR: Buffer of data elements is full.', {connectionActive: activeConnection});
141+
if (callback) {
142+
callback('ERROR: Buffer of data elements is full.', {connectionActive: activeConnection});
143+
}
143144
return;
144145
}
145146

146147
var augmentedData = Object.assign({}, data);
147148
augmentedData[ALCHEMY_TENANT_ID_KEY] = tenantId;
148-
augmentedData['type'] = type;
149149

150150
pendingDataElements.push(augmentedData);
151151

152152
logger.debug('Current size of pending data buffer: ' + pendingDataElements.length);
153153

154-
callback('', {connectionActive: activeConnection});
154+
if (callback) {
155+
callback(null, {connectionActive: activeConnection});
156+
}
155157
if (activeConnection) {
156158
processDataBuffer();
157159
}
@@ -211,7 +213,7 @@ function connectToMTLumberjackServer(endpoint, port, tenantOrSupertenantId, logm
211213
if (tlsSocket.authorized) {
212214
logger.info('Successfully established a connection with Logmet');
213215

214-
// Now that the connection has been established, let's perform the handshake with Logmet
216+
// Now that the connection has been established, let's perform the handshake with Logmet
215217
authenticate(tenantOrSupertenantId, logmetToken, isSuperTenant);
216218
} else {
217219
logger.error('Failed to establish a connection with Logmet: ' + tlsSocket.authorizationError);
@@ -228,7 +230,7 @@ function connectToMTLumberjackServer(endpoint, port, tenantOrSupertenantId, logm
228230

229231
retryFunction = connectToMTLumberjackServer.bind(this, endpoint, port, tenantOrSupertenantId, logmetToken, isSuperTenant, callback);
230232

231-
// Define callbacks to handle the network communication with Logmet
233+
// Define callbacks to handle the network communication with Logmet
232234

233235
tlsSocket.setTimeout(INACTIVITY_TIMEOUT);
234236

@@ -258,10 +260,10 @@ function connectToMTLumberjackServer(endpoint, port, tenantOrSupertenantId, logm
258260
var version = ackBuffer[0];
259261
var type = ackBuffer[1];
260262
if (type != 65) {
261-
// Unknown ACK type
263+
// Unknown ACK type
262264
logger.error('Received an unknown ACK type from Logmet: ' + String.fromCharCode(type));
263265
} else if (version == 48) {
264-
// Got a "0A" from Logmet, that is, an invalid combination of tenant id and password was used
266+
// Got a "0A" from Logmet, that is, an invalid combination of tenant id and password was used
265267
logger.error('Logmet indicated an unauthorized connection due to invalid credentials.');
266268
socketWrapper.state = State.DISCONNECTED;
267269
tlsSocket.destroy();
@@ -272,15 +274,15 @@ function connectToMTLumberjackServer(endpoint, port, tenantOrSupertenantId, logm
272274
retryWithExponentialBackoff(retryFunction);
273275
}
274276
} else if (version == 49) {
275-
// We got a '"1A"<ack_number>'. Let's read the ACK number.
276-
logger.debug("Reading ACK number");
277+
// We got a '"1A"<ack_number>'. Let's read the ACK number.
278+
logger.debug('Reading ACK number');
277279
previousAck = currentAck;
278280
currentAck = ackBuffer.readInt32BE(2);
279281
logger.info('Last ACK received: ' + currentAck);
280282
if (currentAck == 0) {
281-
// The connection has just been established.
283+
// The connection has just been established.
282284

283-
// If this is a reconnection after a failure, let's check if there is unACKED data to be sent
285+
// If this is a reconnection after a failure, let's check if there is unACKED data to be sent
284286
if (unackedDataElements.length !== 0) {
285287
for (var i = 0; i < unackedDataElements.length; i++) {
286288
writeToSocket(unackedDataElements, i);
@@ -289,18 +291,18 @@ function connectToMTLumberjackServer(endpoint, port, tenantOrSupertenantId, logm
289291

290292
logger.info('Initialized the Logmet client. The Logmet handshake is complete.');
291293

292-
// Reset the retry delay, as we have just successfully connected.
294+
// Reset the retry delay, as we have just successfully connected.
293295
RETRY_DELAY = INITIAL_RETRY_DELAY;
294296

295297
if (!initialConnectionEstablished) {
296-
// Let's signal the constructor caller that the connection is established.
297-
// We only notify the constructor caller when the first connection is established.
298-
// We should NOT call back to the caller every time we reconnect due to an error.
298+
// Let's signal the constructor caller that the connection is established.
299+
// We only notify the constructor caller when the first connection is established.
300+
// We should NOT call back to the caller every time we reconnect due to an error.
299301
initialConnectionEstablished = true;
300302
callback('', {handshakeCompleted: true});
301303
}
302304
} else {
303-
// A data frame has been ACKed
305+
// A data frame has been ACKed
304306
if (socketWrapper.state === State.CONNECTED) {
305307
unackedDataElements.splice(0, currentAck - previousAck);
306308
}
@@ -309,31 +311,27 @@ function connectToMTLumberjackServer(endpoint, port, tenantOrSupertenantId, logm
309311
socketWrapper.state = State.CONNECTED;
310312
processDataBuffer();
311313
} else {
312-
// Unknown ACK version
314+
// Unknown ACK version
313315
logger.error('Received an unknown ACK version from Logmet: ' + String.fromCharCode(version));
314316
}
315317
});
316318
}
317319

318320
function socketEventHandler(eventName, error) {
319321
if (this.state === State.DISCONNECTED) {
320-
logger.debug("Caught '" + eventName + "' event. No action is being taken.");
322+
logger.debug('Caught \'' + eventName + '\' event. No action is being taken.');
321323
return;
322324
}
323325
this.state = State.DISCONNECTED;
324326
this.socket.destroy();
325327

326328
if (eventName === 'timeout') {
327-
logger.info("A 'timeout' event was caught. Proactively re-creating logmet connection.");
329+
logger.info('A \'timeout\' event was caught. Proactively re-creating logmet connection.');
328330
retryFunction();
329331
return;
330332
}
331333

332-
if (error && (error.code == 'ECONNREFUSED' || error.code == 'ENOTFOUND') ) {
333-
// While trying to connect or reconnect, either the connection attempt was refused or the network was down. Retry...
334-
logger.warn('Connection refused or network down.');
335-
}
336-
logger.warn("A '" + eventName + "' event was caught. The connection with Logmet was compromised. Will attempt to reconnect in " + RETRY_DELAY + " seconds.");
334+
logger.warn(`A(n) '${ eventName }' event was caught (details: ${ error && error.code || error }). Will attempt to reconnect to Logmet in ${ RETRY_DELAY } seconds.`);
337335
retryWithExponentialBackoff(retryFunction);
338336

339337
}
@@ -342,10 +340,10 @@ function socketEventHandler(eventName, error) {
342340
* Performs the Logmet authentication handshake
343341
*/
344342
function authenticate(tenantOrSupertenantId, logmetToken, isSuperTenant) {
345-
// Identification frame:
346-
// 1 | I | id_size | id
347-
var idFrameTypeAndVersion = "1I";
348-
var clientIdString = "standalone_dlms_data_client_v0.0.1_" + os.hostname();
343+
// Identification frame:
344+
// 1 | I | id_size | id
345+
var idFrameTypeAndVersion = '1I';
346+
var clientIdString = 'standalone_dlms_data_client_v0.0.1_' + os.hostname();
349347
logger.info('Identifying the Logmet client: ' + clientIdString);
350348

351349
var idDataBuffer = new Buffer(idFrameTypeAndVersion.length + 1 + clientIdString.length);
@@ -355,11 +353,11 @@ function authenticate(tenantOrSupertenantId, logmetToken, isSuperTenant) {
355353
idDataBuffer.writeUIntBE(clientIdString.length, idFrameTypeAndVersion.length, 1);
356354
idDataBuffer.write(clientIdString, idFrameTypeAndVersion.length + 1, clientIdString.length);
357355

358-
// Send the identification frame to Logmet
356+
// Send the identification frame to Logmet
359357
tlsSocket.write(idDataBuffer);
360358

361-
// Authentication frame:
362-
// 2 | S or T | tenant_id_size | tenant_id | token_size | token
359+
// Authentication frame:
360+
// 2 | S or T | tenant_id_size | tenant_id | token_size | token
363361
var authFrameTypeAndVersion = isSuperTenant ? '2S' : '2T';
364362
logger.info('Authenticating with Logmet with frame type: ' + authFrameTypeAndVersion[1]);
365363

@@ -374,7 +372,7 @@ function authenticate(tenantOrSupertenantId, logmetToken, isSuperTenant) {
374372
authDataBuffer.writeUIntBE(logmetToken.length, authFrameTypeAndVersion.length + 1 + tenantOrSupertenantId.length, 1);
375373
authDataBuffer.write(logmetToken, authFrameTypeAndVersion.length + 1 + tenantOrSupertenantId.length + 1, logmetToken.length);
376374

377-
// Send the authentication frame to Logmet
375+
// Send the authentication frame to Logmet
378376
tlsSocket.write(authDataBuffer);
379377
}
380378

@@ -386,8 +384,8 @@ function authenticate(tenantOrSupertenantId, logmetToken, isSuperTenant) {
386384
* @return A Buffer with a Lumberjack frame representing the provided data object
387385
*/
388386
function convertDataToFrame(data, sequence) {
389-
// Data frame:
390-
// 1 | D | <sequence> | <nkeys> | <key_length_i> | <key_i> | <val_length_i> | <val_i> | ...
387+
// Data frame:
388+
// 1 | D | <sequence> | <nkeys> | <key_length_i> | <key_i> | <val_length_i> | <val_i> | ...
391389

392390
var dottedNotationData = {};
393391
objectToFlatDottedNotation(data, '', dottedNotationData);
@@ -401,7 +399,7 @@ function convertDataToFrame(data, sequence) {
401399
}
402400

403401
var buffer = new Buffer(bufferSize);
404-
buffer.write("1D", 0, 2);
402+
buffer.write('1D', 0, 2);
405403
buffer.writeUInt32BE(sequence, 2);
406404
buffer.writeUInt32BE(numberOfPairs, 6);
407405

@@ -441,7 +439,7 @@ function objectToFlatDottedNotation(data, prefix, dottedNotationData) {
441439
}
442440

443441
function incrementSequenceNumber() {
444-
// Logmet doesn't seem to acknowledge an ACK if it has a number lower than the previous ACK
442+
// Logmet doesn't seem to acknowledge an ACK if it has a number lower than the previous ACK
445443
if (currentSequenceNumber + 1 > MAX_SEQ_NUMBER) {
446444
socketWrapper.state = State.DISCONNECTED;
447445
tlsSocket.destroy();
@@ -471,7 +469,7 @@ function writeToSocket(unackedDataElements, dataElementIndex) {
471469
logger.debug('Sent window frame: ' + windowFramebuffer);
472470
logger.debug('Data frame to be sent: ' + frame);
473471
tlsSocket.write(frame);
474-
logger.info("Sent data frame. Sequence number: " + currentSequenceNumber);
472+
logger.info('Sent data frame. Sequence number: ' + currentSequenceNumber);
475473
}
476474

477475
function sendWindowFrame(numberOfFrames) {

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ logmetProducer.connect(function(error, status) {
5757
});
5858

5959
function sendData(event) {
60-
logmetProducer.sendData(event, 'tool_id', logmetTenant, function(error, status) {
60+
logmetProducer.sendData(event, logmetTenant, function(error, status) {
6161
if (error) {
6262
console.log('Logmet client rejected the data. ERROR: ' + error);
6363
} else {
@@ -75,9 +75,8 @@ Before calling the `sendData` function for the first time, the program should ca
7575
The `sendData` function, as shown in the sample above, takes the following parameters in that order:
7676

7777
* the object to be send to Logmet.
78-
* the Elasticsearch type to be associated with the object.
7978
* the Bluemix space id corresponding to the owner of the data. If the constructor was called with a regular tenant id, that is, `isSuperTenant` was set to `false`, then the value of this parameter must match the id given to the constructor. Differently, if the constructor was called with `isSuperTenant` set to `true`, then the value of this parameter will contain a Bluemix space id corresponding to the tenant who will own the data, on behalf of whom the _supertenant_ is sending the data.
80-
* A callback function, indicating whether the data was accepted or not.
79+
* A callback function (optional), indicating whether the data was accepted or not.
8180

8281
If the data buffer is full, the data will not be accepted and the callback function will receive an error message in the `error` argument. The data returned by the callback function in the `status` argument is an object containing a Boolean-valued field:
8382

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "logmet-client",
3-
"version": "0.1.4",
3+
"version": "1.0.0",
44
"description": "Library for sending data to and querying data from Logmet",
55
"author": "Fabio A. Oliveira <[email protected]>",
66
"license": "Apache-2.0",

0 commit comments

Comments
 (0)