зеркало из
1
0
Форкнуть 0

Merge pull request #50 from amarzavery/handlers

More updates
This commit is contained in:
Amar Zavery 2018-04-23 11:12:50 -07:00 коммит произвёл GitHub
Родитель 0943af6465 a8fe942cb1
Коммит 6aeafc07f8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
50 изменённых файлов: 932 добавлений и 326 удалений

3
.vscode/settings.json поставляемый
Просмотреть файл

@ -21,5 +21,6 @@
"editor.formatOnPaste": true,
"editor.tabSize": 2,
"editor.detectIndentation": false
}
},
"editor.rulers": [100]
}

Просмотреть файл

@ -3,6 +3,13 @@ azure-event-hubs
_This SDK is currently in preview._
- **Node.js version: 6.x or higher.** We would encourage you to install the latest available LTS version from https://nodejs.org.
## Installation ##
```bash
npm install -g azure-event-hubs
```
## Usage ##
See [examples](./examples) directory for some examples.

2
dist/examples/batchReceive.js поставляемый
Просмотреть файл

@ -16,7 +16,7 @@ const path = process.env[entityPath] || "";
function main() {
return __awaiter(this, void 0, void 0, function* () {
const client = lib_1.EventHubClient.createFromConnectionString(str, path);
const result = yield client.receiveBatch("0", 10, 20, { enableReceiverRuntimeMetric: true });
const result = yield client.receiveBatch("0", 10, 20);
console.log(">>> EventDataObjects: ", result);
let i = 0;
for (let data of result) {

2
dist/examples/batchReceive.js.map поставляемый
Просмотреть файл

@ -1 +1 @@
{"version":3,"file":"batchReceive.js","sourceRoot":"","sources":["../../examples/batchReceive.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,gCAAmD;AAEnD,MAAM,gBAAgB,GAAG,4BAA4B,CAAC;AACtD,MAAM,UAAU,GAAG,eAAe,CAAC;AACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;AAChD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;AAG3C;;QACE,MAAM,MAAM,GAAG,oBAAc,CAAC,0BAA0B,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,MAAM,GAAgB,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,2BAA2B,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1G,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,IAAI,IAAI,IAAI,MAAM,EAAE;YACvB,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SACvF;QACD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CAAA;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC"}
{"version":3,"file":"batchReceive.js","sourceRoot":"","sources":["../../examples/batchReceive.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,gCAAmD;AAEnD,MAAM,gBAAgB,GAAG,4BAA4B,CAAC;AACtD,MAAM,UAAU,GAAG,eAAe,CAAC;AACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;AAChD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;AAG3C;;QACE,MAAM,MAAM,GAAG,oBAAc,CAAC,0BAA0B,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,MAAM,GAAgB,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,IAAI,IAAI,IAAI,MAAM,EAAE;YACvB,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SACvF;QACD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CAAA;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC"}

30
dist/examples/simpleSender.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,30 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const lib_1 = require("../lib");
const connectionString = "EVENTHUB_CONNECTION_STRING";
const entityPath = "EVENTHUB_NAME";
const str = process.env[connectionString] || "";
const path = process.env[entityPath] || "";
function main() {
return __awaiter(this, void 0, void 0, function* () {
const client = lib_1.EventHubClient.createFromConnectionString(str, path);
const data = {
body: "Hello World!!"
};
const delivery = yield client.send(data);
console.log(">>> Sent the message successfully: ", delivery.id);
// await client.close();
});
}
main().catch((err) => {
console.log("error: ", err);
});
//# sourceMappingURL=simpleSender.js.map

1
dist/examples/simpleSender.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"simpleSender.js","sourceRoot":"","sources":["../../examples/simpleSender.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,gCAAmD;AAEnD,MAAM,gBAAgB,GAAG,4BAA4B,CAAC;AACtD,MAAM,UAAU,GAAG,eAAe,CAAC;AACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;AAChD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;AAG3C;;QACE,MAAM,MAAM,GAAG,oBAAc,CAAC,0BAA0B,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,IAAI,GAAc;YACtB,IAAI,EAAE,eAAe;SACtB,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QAChE,wBAAwB;IAC1B,CAAC;CAAA;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC"}

37
dist/examples/streamingReceive.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,37 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const lib_1 = require("../lib");
const connectionString = "EVENTHUB_CONNECTION_STRING";
const entityPath = "EVENTHUB_NAME";
const str = process.env[connectionString] || "";
const path = process.env[entityPath] || "";
function main() {
return __awaiter(this, void 0, void 0, function* () {
const client = lib_1.EventHubClient.createFromConnectionString(str, path);
const onMessage = (eventData) => __awaiter(this, void 0, void 0, function* () {
console.log(">>> EventDataObject: ", eventData);
console.log("### Actual message:", eventData.body ? eventData.body.toString() : null);
});
const onError = (err) => {
console.log(">>>>> Error occurred: ", err);
};
const options = {
eventPosition: lib_1.EventPosition.fromEnqueuedTime(Date.now()),
enableReceiverRuntimeMetric: true
};
const rcvHandler = client.receiveOnMessage("0", onMessage, onError, options);
console.log("rcvHandler: ", rcvHandler.name);
});
}
main().catch((err) => {
console.log("error: ", err);
});
//# sourceMappingURL=streamingReceive.js.map

1
dist/examples/streamingReceive.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"streamingReceive.js","sourceRoot":"","sources":["../../examples/streamingReceive.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,gCAA2G;AAE3G,MAAM,gBAAgB,GAAG,4BAA4B,CAAC;AACtD,MAAM,UAAU,GAAG,eAAe,CAAC;AACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;AAChD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;AAG3C;;QACE,MAAM,MAAM,GAAG,oBAAc,CAAC,0BAA0B,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpE,MAAM,SAAS,GAAc,CAAO,SAAc,EAAE,EAAE;YACpD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,SAAS,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACxF,CAAC,CAAA,CAAA;QACD,MAAM,OAAO,GAAY,CAAC,GAA2B,EAAE,EAAE;YACvD,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;QAC7C,CAAC,CAAC;QACF,MAAM,OAAO,GAAmB;YAC9B,aAAa,EAAE,mBAAa,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACzD,2BAA2B,EAAE,IAAI;SAClC,CAAA;QACD,MAAM,UAAU,GAAG,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;CAAA;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC"}

2
dist/lib/batchingReceiver.js поставляемый
Просмотреть файл

@ -113,7 +113,7 @@ class BatchingReceiver extends eventHubReceiver_1.EventHubReceiver {
debug(msg, this._context.connectionId, maxWaitTimeInSeconds, this.name);
waitTimer = setTimeout(actionAfterWaitTimeout, maxWaitTimeInSeconds * 1000);
};
if (!this._session && !this._receiver) {
if (!this._isOpen()) {
debug("[%s] Receiver '%s', setting the prefetch count to 0.", this._context.connectionId, this.name);
this.prefetchCount = 0;
this._init(onReceiveMessage, onReceiveError).then(() => addCreditAndSetTimer()).catch(reject);

2
dist/lib/batchingReceiver.js.map поставляемый
Просмотреть файл

@ -1 +1 @@
{"version":3,"file":"batchingReceiver.js","sourceRoot":"","sources":["../../lib/batchingReceiver.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"batchingReceiver.js","sourceRoot":"","sources":["../../lib/batchingReceiver.ts"],"names":[],"mappings":"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"}

9
dist/lib/cbs.js поставляемый
Просмотреть файл

@ -15,6 +15,7 @@ const rheaPromise = require("./rhea-promise");
const uuid = require("uuid/v4");
const Constants = require("./util/constants");
const debugModule = require("debug");
const errors_1 = require("./errors");
const debug = debugModule("azure:event-hubs:cbs");
/**
* @class CbsClient
@ -50,6 +51,14 @@ class CbsClient {
name: this.replyTo
};
this._cbsSenderReceiverLink = yield rpc_1.createRequestResponseLink(connection, { target: { address: this.endpoint } }, rxOpt);
this._cbsSenderReceiverLink.sender.on("sender_error", (context) => {
const ehError = errors_1.translate(context.sender.error);
debug("An error occurred on the cbs sender link.. %O", ehError);
});
this._cbsSenderReceiverLink.receiver.on("receiver_error", (context) => {
const ehError = errors_1.translate(context.receiver.error);
debug("An error occurred on the cbs receiver link.. %O", ehError);
});
debug("[%s] Successfully created the cbs sender '%s' and receiver '%s' links over cbs session.", connection.options.id, this._cbsSenderReceiverLink.sender.name, this._cbsSenderReceiverLink.receiver.name);
}
else {

2
dist/lib/cbs.js.map поставляемый
Просмотреть файл

@ -1 +1 @@
{"version":3,"file":"cbs.js","sourceRoot":"","sources":["../../lib/cbs.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"cbs.js","sourceRoot":"","sources":["../../lib/cbs.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;;;;;;;;;AAG/F,+BAAoF;AACpF,8CAA8C;AAC9C,gCAAgC;AAChC,8CAA8C;AAC9C,qCAAqC;AAErC,qCAAqC;AACrC,MAAM,KAAK,GAAG,WAAW,CAAC,sBAAsB,CAAC,CAAC;AAElD;;;GAGG;AACH;IAAA;QACE;;WAEG;QACM,aAAQ,GAAW,SAAS,CAAC,WAAW,CAAC;QAClD;;WAEG;QACM,YAAO,GAAW,GAAG,SAAS,CAAC,UAAU,IAAI,IAAI,EAAE,EAAE,CAAC;QAE/D;;;WAGG;QACM,YAAO,GAAW,GAAG,SAAS,CAAC,eAAe,IAAI,IAAI,EAAE,EAAE,CAAC;IAmFtE,CAAC;IA5EC;;;OAGG;IACG,IAAI,CAAC,UAAe;;YACxB,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE;gBAChC,MAAM,KAAK,GAAgC;oBACzC,MAAM,EAAE;wBACN,OAAO,EAAE,IAAI,CAAC,QAAQ;qBACvB;oBACD,IAAI,EAAE,IAAI,CAAC,OAAO;iBACnB,CAAC;gBACF,IAAI,CAAC,sBAAsB,GAAG,MAAM,+BAAyB,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;gBACzH,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,OAA4B,EAAE,EAAE;oBACrF,MAAM,OAAO,GAAG,kBAAS,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChD,KAAK,CAAC,+CAA+C,EAAE,OAAO,CAAC,CAAC;gBAClE,CAAC,CAAC,CAAC;gBACH,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC,gBAAgB,EAAE,CAAC,OAA4B,EAAE,EAAE;oBACzF,MAAM,OAAO,GAAG,kBAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;oBAClD,KAAK,CAAC,iDAAiD,EAAE,OAAO,CAAC,CAAC;gBACpE,CAAC,CAAC,CAAC;gBACH,KAAK,CAAC,yFAAyF,EAC7F,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aAC9G;iBAAM;gBACL,KAAK,CAAC,4GAA4G,EAChH,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;aAC9G;QACH,CAAC;KAAA;IAED;;;;;;;OAOG;IACG,cAAc,CAAC,QAAgB,EAAE,UAAe,EAAE,WAAsB;;YAC5E,IAAI;gBACF,MAAM,OAAO,GAAgB;oBAC3B,IAAI,EAAE,WAAW,CAAC,KAAK;oBACvB,UAAU,EAAE,IAAI,EAAE;oBAClB,QAAQ,EAAE,IAAI,CAAC,OAAO;oBACtB,EAAE,EAAE,IAAI,CAAC,QAAQ;oBACjB,sBAAsB,EAAE;wBACtB,SAAS,EAAE,SAAS,CAAC,iBAAiB;wBACtC,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,WAAW,CAAC,SAAS;qBAC5B;iBACF,CAAC;gBACF,MAAM,QAAQ,GAAG,MAAM,iBAAW,CAAC,UAAU,EAAE,IAAI,CAAC,sBAAuB,EAAE,OAAO,CAAC,CAAC;gBACtF,OAAO,QAAQ,CAAC;aACjB;YAAC,OAAO,GAAG,EAAE;gBACZ,KAAK,CAAC,0DAA0D,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;gBAC9F,MAAM,GAAG,CAAC;aACX;QACH,CAAC;KAAA;IAED;;;;OAIG;IACG,KAAK;;YACT,IAAI;gBACF,IAAI,IAAI,CAAC,sBAAsB,EAAE;oBAC/B,MAAM,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;oBACpE,KAAK,CAAC,sCAAsC,CAAC,CAAC;oBAC9C,IAAI,CAAC,sBAAsB,GAAG,SAAS,CAAC;iBACzC;aACF;YAAC,OAAO,GAAG,EAAE;gBACZ,MAAM,GAAG,GAAG,oDAAoD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;gBACvF,KAAK,CAAC,GAAG,CAAC,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;aACtB;QACH,CAAC;KAAA;CACF;AAjGD,8BAiGC"}

10
dist/lib/errors.js поставляемый
Просмотреть файл

@ -309,9 +309,9 @@ class EventHubsError extends Error {
*/
this.name = "EventHubsError";
/**
* @property {boolean} translated Has the error been previously translated. Default value: false.
* @property {boolean} translated Has the error been translated. Default: true.
*/
this.translated = false;
this.translated = true;
/**
*
* @param {boolean} retryable Describes whether the error is retryable. Default: false.
@ -362,8 +362,9 @@ function translate(err) {
description.match(/The messaging entity .* could not be found.*/i) !== null)) {
error.name = "MessagingEntityNotFoundError";
}
error.translated = true;
if (error.name === "InternalServerError" || error.name === "ServerBusyError") {
if (error.name === "InternalServerError"
|| error.name === "ServerBusyError"
|| error.name === "ServiceUnavailableError") {
error.retryable = true;
}
return error;
@ -371,7 +372,6 @@ function translate(err) {
else {
// Translate a generic error into EventHubsError.
const error = new EventHubsError(err.message);
error.translated = true;
return error;
}
}

2
dist/lib/errors.js.map поставляемый
Просмотреть файл

@ -1 +1 @@
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../lib/errors.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../lib/errors.ts"],"names":[],"mappings":"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"}

18
dist/lib/eventHubReceiver.js поставляемый
Просмотреть файл

@ -82,6 +82,7 @@ class EventHubReceiver {
this._onAmqpError = (context) => {
const ehError = errors_1.translate(context.receiver.error);
// TODO: Should we retry before calling user's error method?
debug("[%s] An error occurred for Receiver '%s': %O.", this._context.connectionId, this.name, ehError);
this._onError(ehError);
};
}
@ -122,7 +123,7 @@ class EventHubReceiver {
debug("[%s] EH Receiver '%s' establishing AMQP connection.", this._context.connectionId, this.name);
yield utils_1.defaultLock.acquire(this._context.connectionLock, () => { return rpc.open(this._context); });
}
if (!this._session && !this._receiver) {
if (!this._isOpen()) {
yield this._negotiateClaim();
if (!onAmqpMessage) {
onAmqpMessage = this._onAmqpMessage;
@ -150,6 +151,21 @@ class EventHubReceiver {
}
});
}
/**
* Determines whether the AMQP receiver link is open. If open then returns true else returns false.
* @protected
*
* @return {boolean} boolean
*/
_isOpen() {
let result = false;
if (this._session && this._receiver) {
if (this._receiver.is_open && this._receiver.is_open()) {
result = true;
}
}
return result;
}
/**
* Creates the options that need to be specified while creating an AMQP receiver link.
* @private

2
dist/lib/eventHubReceiver.js.map поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

121
dist/lib/eventHubSender.js поставляемый
Просмотреть файл

@ -16,10 +16,9 @@ const uuid = require("uuid/v4");
const errors_1 = require("./errors");
const rpc = require("./rpc");
const rheaPromise = require("./rhea-promise");
const Constants = require("./util/constants");
const events_1 = require("events");
const eventData_1 = require("./eventData");
const utils_1 = require("./util/utils");
const retry_1 = require("./retry");
const debug = debugModule("azure:event-hubs:sender");
/**
* Instantiates a new sender from the AMQP `Sender`. Used by `EventHubClient`.
@ -28,15 +27,15 @@ const debug = debugModule("azure:event-hubs:sender");
* @param {any} sender - The amqp sender link.
* @constructor
*/
class EventHubSender extends events_1.EventEmitter {
class EventHubSender {
/**
* Creates a new EventHubSender instance.
* @constructor
* @param {EventHubClient} client The EventHub client.
* @param {string|number} [partitionId] The EventHub partition id to which the sender wants to send the event data.
* @param {string|number} [partitionId] The EventHub partition id to which the sender
* wants to send the event data.
*/
constructor(context, partitionId, name) {
super();
this.senderLock = `sender-${uuid()}`;
this._context = context;
this.name = name || uuid();
@ -46,31 +45,12 @@ class EventHubSender extends events_1.EventEmitter {
this.address += `/Partitions/${this.partitionId}`;
}
this.audience = `${this._context.config.endpoint}${this.address}`;
const onError = (context) => {
this.emit(Constants.error, errors_1.translate(context.sender.error));
};
this.on("newListener", (event) => {
if (event === Constants.error) {
if (this._session && this._sender) {
debug("Attaching an event handler for the 'sender_error' event on the underlying amqp sender: ", this.name);
this._sender.on(Constants.senderError, onError);
}
}
});
this.on("removeListener", (event) => {
if (event === Constants.error) {
if (this._session && this._sender) {
debug("Removing an event handler for the 'sender_error' event on the underlying amqp sender: ", this.name);
this._sender.removeListener(Constants.senderError, onError);
}
}
});
}
/**
* Sends the given message, with the given options on this link
*
* @method send
* @param {any} data Message to send. Will be sent as UTF8-encoded JSON string.
* @param {any} data Message to send. Will be sent as UTF8-encoded JSON string.
* @returns {Promise<rheaPromise.Delivery>} Promise<rheaPromise.Delivery>
*/
send(data) {
@ -79,8 +59,9 @@ class EventHubSender extends events_1.EventEmitter {
if (!data || (data && typeof data !== "object")) {
throw new Error("data is required and it must be of type object.");
}
if (!this._session && !this._sender) {
debug("Acquiring lock %s for initializing the session, sender and possibly the connection.", this.senderLock);
if (!this._isOpen()) {
debug("Acquiring lock %s for initializing the session, sender and " +
"possibly the connection.", this.senderLock);
yield utils_1.defaultLock.acquire(this.senderLock, () => { return this._init(); });
}
const message = eventData_1.EventData.toAmqpMessage(data);
@ -93,8 +74,9 @@ class EventHubSender extends events_1.EventEmitter {
});
}
/**
* Send a batch of EventData to the EventHub. The "message_annotations", "application_properties" and "properties"
* of the first message will be set as that of the envelope (batch message).
* Send a batch of EventData to the EventHub. The "message_annotations",
* "application_properties" and "properties" of the first message will be set as that
* of the envelope (batch message).
* @param {Array<EventData>} datas An array of EventData objects to be sent in a Batch message.
* @return {Promise<rheaPromise.Delivery>} Promise<rheaPromise.Delivery>
*/
@ -104,8 +86,9 @@ class EventHubSender extends events_1.EventEmitter {
if (!datas || (datas && !Array.isArray(datas))) {
throw new Error("data is required and it must be an Array.");
}
if (!this._session && !this._sender) {
debug("Acquiring lock %s for initializing the session, sender and possibly the connection.", this.senderLock);
if (!this._isOpen()) {
debug("Acquiring lock %s for initializing the session, sender and " +
"possibly the connection.", this.senderLock);
yield utils_1.defaultLock.acquire(this.senderLock, () => { return this._init(); });
}
debug("[%s] Sender '%s', trying to send EventData[]: %O", this._context.connectionId, this.name, datas);
@ -145,7 +128,7 @@ class EventHubSender extends events_1.EventEmitter {
}
/**
* "Unlink" this sender, closing the link and resolving when that operation is complete.
* Leaves the underlying connection/session open.
* Leaves the underlying connection open.
* @method close
* @return {Promise<void>} Promise<void>
*/
@ -154,7 +137,6 @@ class EventHubSender extends events_1.EventEmitter {
if (this._sender) {
try {
yield rheaPromise.closeSender(this._sender);
this.removeAllListeners();
delete this._context.senders[this.name];
debug("[%s] Deleted the sender '%s' from the client cache.", this._context.connectionId, this.name);
this._sender = undefined;
@ -183,15 +165,15 @@ class EventHubSender extends events_1.EventEmitter {
* Tries to send the message to EventHub if there is enough credit to send them
* and the circular buffer has available space to settle the message after sending them.
*
* We have implemented a synchronous send over here. We shall be waiting for the message
* to be accepted or rejected and accordingly resolve or reject the promise.
* We have implemented a synchronous send over here in the sense that we shall be waiting
* for the message to be accepted or rejected and accordingly resolve or reject the promise.
*
* @param message The message to be sent to EventHub.
* @return {Promise<rheaPromise.Delivery>} Promise<rheaPromise.Delivery>
*/
_trySend(message, tag, format) {
return new Promise((resolve, reject) => {
debug("[%s] Sender '%s', credit: %d available: %d", this._context.connectionId, this._sender.credit, this._sender.session.outgoing.available());
const sendEventPromise = new Promise((resolve, reject) => {
debug("[%s] Sender '%s', credit: %d available: %d", this._context.connectionId, this.name, this._sender.credit, this._sender.session.outgoing.available());
if (this._sender.sendable()) {
debug("[%s] Sender '%s', sending message: %O", this._context.connectionId, this.name, message);
let onRejected;
@ -225,7 +207,8 @@ class EventHubSender extends events_1.EventEmitter {
err = errors_1.translate(context.delivery.remote_state.error);
}
else {
err = new Error(`[${this._context.connectionId}] Sender '${this.name}', received a release disposition. Hence we are rejecting the promise.`);
err = new Error(`[${this._context.connectionId}] Sender '${this.name}', ` +
`received a release disposition. Hence we are rejecting the promise.`);
}
reject(err);
};
@ -237,7 +220,8 @@ class EventHubSender extends events_1.EventEmitter {
err = errors_1.translate(context.delivery.remote_state.error);
}
else {
err = new Error(`[%s]Sender '%s', received a modified disposition.Hence we are rejecting the promise.`);
err = new Error(`[${this._context.connectionId}] Sender "${this.name}", ` +
`received a modified disposition. Hence we are rejecting the promise.`);
}
reject(err);
};
@ -249,11 +233,28 @@ class EventHubSender extends events_1.EventEmitter {
debug("[%s] Sender '%s', sent message with delivery id: %d", this._context.connectionId, this.name, delivery.id);
}
else {
const msg = `[${this._context.connectionId}] Sender '${this.name}', cannot send the message right now.Please try later.`;
const msg = `[${this._context.connectionId}] Sender "${this.name}", ` +
`cannot send the message right now. Please try later.`;
debug(msg);
reject(new Error(msg));
}
});
return retry_1.retry(() => sendEventPromise);
}
/**
* Determines whether the AMQP sender link is open. If open then returns true else returns false.
* @private
*
* @return {boolean} boolean
*/
_isOpen() {
let result = false;
if (this._session && this._sender) {
if (this._sender.is_open && this._sender.is_open()) {
result = true;
}
}
return result;
}
/**
* Initializes the sender session on the connection.
@ -269,30 +270,21 @@ class EventHubSender extends events_1.EventEmitter {
}
if (!this._session && !this._sender) {
yield this._negotiateClaim();
let senderError;
this._session = yield rheaPromise.createSession(this._context.connection);
const handleSenderError = (context) => {
senderError = errors_1.translate(context.sender.error);
debug("[%s] An error occurred while creating the sender: %O.", this._context.connectionId, senderError);
const onAmqpError = (context) => {
const senderError = errors_1.translate(context.sender.error);
// TODO: Should we retry before calling user's error method?
debug("[%s] An error occurred for sender '%s': %O.", this._context.connectionId, this.name, senderError);
};
this._session.on(Constants.senderError, handleSenderError);
this._session = yield rheaPromise.createSession(this._context.connection);
debug("[%s] Trying to create sender '%s'...", this._context.connectionId, this.name);
const options = this._createSenderOptions();
debug("[%s] Trying to create a sender...", this._context.connectionId);
this._sender = yield rheaPromise.createSender(this._session, options);
this._sender = yield rheaPromise.createSenderWithHandlers(this._session, onAmqpError, options);
debug("[%s] Promise to create the sender resolved. Created sender with name: %s", this._context.connectionId, this.name);
if (senderError) {
// There are cases where the EH service sends an attach frame, which causes rhea to emit sender_open event
// thus resolving the promise to create a sender and moments later the service sends back a detach frame
// indicating that there was some error. Hence we check for senderError, even after the promise has resolved.
debug("[%s] throwing the senderError, %O", senderError, this._context.connectionId);
throw senderError;
}
this._session.removeListener(Constants.senderError, handleSenderError);
debug("[%s] Sender '%s' created with sender options: %O", this._context.connectionId, this.name, options);
// It is possible for someone to close the sender and then start it again.
// Thus make sure that the sender is present in the client cache.
if (!this._context.senders[this.name])
this._context.senders[this.name] = this;
if (!this._context.senders[this.address])
this._context.senders[this.address] = this;
yield this._ensureTokenRenewal();
}
}
@ -311,10 +303,10 @@ class EventHubSender extends events_1.EventEmitter {
*/
_negotiateClaim(setTokenRenewal) {
return __awaiter(this, void 0, void 0, function* () {
// Acquire the lock and establish a cbs session if it does not exist on the connection. Although node.js
// is single threaded, we need a locking mechanism to ensure that a race condition does not happen while
// creating a shared resource (in this case the cbs session, since we want to have exactly 1 cbs session
// per connection).
// Acquire the lock and establish a cbs session if it does not exist on the connection.
// Although node.js is single threaded, we need a locking mechanism to ensure that a
// race condition does not happen while creating a shared resource (in this case the
// cbs session, since we want to have exactly 1 cbs session per connection).
debug("[%s] Acquiring lock: '%s' for creating the cbs session while creating the sender: '%s'.", this._context.connectionId, this._context.cbsSession.cbsLock, this.name);
yield utils_1.defaultLock.acquire(this._context.cbsSession.cbsLock, () => { return this._context.cbsSession.init(this._context.connection); });
const tokenObject = yield this._context.tokenProvider.getToken(this.audience);
@ -347,15 +339,14 @@ class EventHubSender extends events_1.EventEmitter {
catch (err) {
// TODO: May be add some retries over here before emitting the error.
debug("[%s] Sender '%s', an error occurred while renewing the token: %O", this._context.connectionId, this.name, err);
this.emit(Constants.error, errors_1.translate(err));
}
}), nextRenewalTimeout);
debug("[%s]Sender '%s', has next token renewal in %d seconds @(%s).", nextRenewalTimeout / 1000, new Date(Date.now() + nextRenewalTimeout).toString());
});
}
/**
* Creates a new sender to the given event hub, and optionally to a given partition if it is not present
* in the context or returns the one present in the context.
* Creates a new sender to the given event hub, and optionally to a given partition if it is
* not present in the context or returns the one present in the context.
* @static
* @param {(string|number)} [partitionId] Partition ID to which it will send event data.
* @returns {Promise<EventHubSender>}

2
dist/lib/eventHubSender.js.map поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

90
dist/lib/retry.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,90 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const errors_1 = require("./errors");
const _1 = require(".");
const debugModule = require("debug");
const debug = debugModule("azure:event-hubs:retry");
function isDelivery(obj) {
let result = false;
if (obj && typeof obj.id === "number" && typeof obj.settled === "boolean" &&
typeof obj.remote_settled === "boolean" && typeof obj.format === "number") {
result = true;
}
return result;
}
/**
* It will attempt to linearly retry an operation specified number of times with a specified
* delay in between each retry. The retries will only happen if the error is retryable.
*
* @param {Promise<T>} operation The operation that needs to be retried.
* @param {number} [times] Number of times the operation needs to be retried in case of error. Default: 3.
* @param {number} [delayInSeconds] Amount of time to wait in seconds before making the next attempt. Default: 15.
*
* @return {Promise<T>} Promise<T>.
*/
function retry(operation, times, delayInSeconds) {
return __awaiter(this, void 0, void 0, function* () {
if (!operation || typeof operation !== "function") {
throw new Error("'operation' is a required parameter and must be of type 'function'.");
}
if (times && typeof times !== "number") {
throw new Error("'times' must be of type 'number'.");
}
if (delayInSeconds && typeof delayInSeconds !== "number") {
throw new Error("'delayInSeconds' must be of type 'number'.");
}
if (!times)
times = 3;
if (!delayInSeconds)
delayInSeconds = 15;
let lastError;
let result;
let success = false;
for (let i = 0; i < times; i++) {
const j = i + 1;
debug("Retry attempt number: %d", j);
try {
result = yield operation();
success = true;
debug("Success, after attempt number: %d.", j);
if (!isDelivery(result)) {
debug("Success result: %O", result);
}
break;
}
catch (err) {
if (!err.translated) {
err = errors_1.translate(err);
}
lastError = err;
debug("Error occured in attempt number %d: %O", j, err);
if (lastError.retryable) {
debug("Sleeping for %d seconds.", delayInSeconds);
yield _1.delay(delayInSeconds * 1000);
continue;
}
else {
break;
}
}
}
if (success) {
return result;
}
else {
throw lastError;
}
});
}
exports.retry = retry;
//# sourceMappingURL=retry.js.map

1
dist/lib/retry.js.map поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../lib/retry.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,+FAA+F;;;;;;;;;;AAE/F,qCAAqD;AACrD,wBAA0B;AAC1B,qCAAqC;AACrC,MAAM,KAAK,GAAG,WAAW,CAAC,wBAAwB,CAAC,CAAC;AAEpD,oBAAoB,GAAQ;IAC1B,IAAI,MAAM,GAAY,KAAK,CAAC;IAC5B,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS;QACvE,OAAO,GAAG,CAAC,cAAc,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE;QAC3E,MAAM,GAAG,IAAI,CAAC;KACf;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;GASG;AACH,eAA+B,SAA2B,EAAE,KAAc,EAAE,cAAuB;;QACjG,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE;YACjD,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;SACxF;QAED,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;YACtC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;SACtD;QAED,IAAI,cAAc,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE;YACxD,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;SAC/D;QAED,IAAI,CAAC,KAAK;YAAE,KAAK,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,cAAc;YAAE,cAAc,GAAG,EAAE,CAAC;QACzC,IAAI,SAAqC,CAAC;QAC1C,IAAI,MAAW,CAAC;QAChB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;YAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,KAAK,CAAC,0BAA0B,EAAE,CAAC,CAAC,CAAC;YACrC,IAAI;gBACF,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;gBAC3B,OAAO,GAAG,IAAI,CAAC;gBACf,KAAK,CAAC,oCAAoC,EAAE,CAAC,CAAC,CAAC;gBAC/C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;oBACvB,KAAK,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;iBACrC;gBACD,MAAM;aACP;YAAC,OAAO,GAAG,EAAE;gBACZ,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE;oBACnB,GAAG,GAAG,kBAAS,CAAC,GAAG,CAAC,CAAC;iBACtB;gBACD,SAAS,GAAG,GAAG,CAAC;gBAChB,KAAK,CAAC,wCAAwC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;gBACxD,IAAI,SAAU,CAAC,SAAS,EAAE;oBACxB,KAAK,CAAC,0BAA0B,EAAE,cAAc,CAAC,CAAC;oBAClD,MAAM,QAAK,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;oBACnC,SAAS;iBACV;qBAAM;oBACL,MAAM;iBACP;aACF;SACF;QACD,IAAI,OAAO,EAAE;YACX,OAAO,MAAM,CAAC;SACf;aAAM;YACL,MAAM,SAAS,CAAC;SACjB;IACH,CAAC;CAAA;AAjDD,sBAiDC"}

38
dist/lib/rhea-promise/index.js поставляемый
Просмотреть файл

@ -184,6 +184,44 @@ function createSender(session, options) {
});
}
exports.createSender = createSender;
/**
* Creates an amqp sender on the provided amqp session.
* @param {Session} session The amqp session object on which the sender link needs to be established.
* @param {OnAmqpEvent} onError The event handler for the "error" event for the sender.
* @param {SenderOptions} [options] Options that can be provided while creating an amqp sender.
* @return {Promise<Sender>} Promise<Sender>
* - **Resolves** the promise with the Sender object when rhea emits the "sender_open" event.
* - **Rejects** the promise with an AmqpError when rhea emits the "sender_close" event while trying
* to create an amqp sender.
*/
function createSenderWithHandlers(session, onError, options) {
if (!session || (session && typeof session !== "object")) {
throw new Error("session is a required parameter and must be of type 'object'.");
}
return new Promise((resolve, reject) => {
const sender = session.attach_sender(options);
sender.on("sender_error", onError);
function removeListeners(session) {
sender.removeListener("sendable", onOpen);
sender.removeListener("sender_close", onClose);
}
function onOpen(context) {
removeListeners(session);
process.nextTick(() => {
debug(`Resolving the promise with amqp sender "${sender.name}".`);
resolve(sender);
});
}
function onClose(context) {
removeListeners(session);
debug(`Error occurred while creating a sender over amqp connection.`, context.sender.error);
reject(context.sender.error);
}
sender.once("sendable", onOpen);
sender.once("sender_close", onClose);
});
}
exports.createSenderWithHandlers = createSenderWithHandlers;
/**
* Closes the amqp sender.
* @param {Sender} sender The amqp sender that needs to be closed.

2
dist/lib/rhea-promise/index.js.map поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

27
dist/lib/rpc.js поставляемый
Просмотреть файл

@ -19,6 +19,7 @@ const rhea_promise_1 = require("./rhea-promise");
const Constants = require("./util/constants");
const connectionContext_1 = require("./connectionContext");
const errors_1 = require("./errors");
const retry_1 = require("./retry");
const debug = debugModule("azure:event-hubs:rpc");
function createRequestResponseLink(connection, senderOptions, receiverOptions) {
return __awaiter(this, void 0, void 0, function* () {
@ -105,6 +106,27 @@ function createSenderLink(connection, senderOptions) {
});
}
exports.createSenderLink = createSenderLink;
function createSenderLinkWithHandlers(options) {
return __awaiter(this, void 0, void 0, function* () {
if (!options.connection) {
throw new Error(`Please provide a connection to create the sender link on a session.`);
}
if (!options.senderOptions) {
throw new Error(`Please provide sender options.`);
}
if (!options.onError) {
throw new Error(`Please provide onError.`);
}
const session = yield rhea_promise_1.createSession(options.connection);
const sender = yield rhea_promise_1.createSenderWithHandlers(session, options.onError, options.senderOptions);
debug("[%s] Successfully created the sender link on a dedicated session for it.", options.connection.options.id);
return {
session: session,
sender: sender
};
});
}
exports.createSenderLinkWithHandlers = createSenderLinkWithHandlers;
function sendRequest(connection, link, request, timeoutInSeconds) {
if (!connection) {
throw new Error("connection is a required parameter and must be of type 'object'.");
@ -118,9 +140,9 @@ function sendRequest(connection, link, request, timeoutInSeconds) {
if (!request.message_id)
request.message_id = uuid();
if (!timeoutInSeconds) {
timeoutInSeconds = 30;
timeoutInSeconds = 10;
}
return new Promise((resolve, reject) => {
const sendRequestPromise = new Promise((resolve, reject) => {
let waitTimer;
let timeOver = false;
const messageCallback = (context) => {
@ -171,6 +193,7 @@ function sendRequest(connection, link, request, timeoutInSeconds) {
debug("[%s] %s request sent: %O", connection.options.id, request.to || "$managment", request);
link.sender.send(request);
});
return retry_1.retry(() => sendRequestPromise);
}
exports.sendRequest = sendRequest;
/**

2
dist/lib/rpc.js.map поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

13
dist/lib/streamingReceiver.js поставляемый
Просмотреть файл

@ -22,7 +22,16 @@ class ReceiveHandler {
*/
constructor(receiver) {
this._receiver = receiver;
this.name = receiver.name;
this.name = receiver ? receiver.name : "ReceiveHandler";
}
/**
* @property {ReceiverRuntimeInfo} runtimeInfo The receiver runtime info. This property will only
* be enabled when `enableReceiverRuntimeMetric` option is set to true in the
* `client.receiveOnMessage()` method.
* @readonly
*/
get runtimeInfo() {
return this._receiver ? this._receiver.runtimeInfo : undefined;
}
/**
* Stops the underlying EventHubReceiver from receiving more messages.
@ -81,7 +90,7 @@ class StreamingReceiver extends eventHubReceiver_1.EventHubReceiver {
}
this._onMessage = onMessage;
this._onError = onError;
if (!this._session && !this._receiver) {
if (!this._isOpen()) {
this._init().catch((err) => {
this._onError(err);
});

2
dist/lib/streamingReceiver.js.map поставляемый
Просмотреть файл

@ -1 +1 @@
{"version":3,"file":"streamingReceiver.js","sourceRoot":"","sources":["../../lib/streamingReceiver.ts"],"names":[],"mappings":";AACA,4DAA4D;AAC5D,+FAA+F;;;;;;;;;;AAE/F,qCAAqC;AAErC,yDAAsD;AAEtD,8CAA8C;AAC9C,MAAM,KAAK,GAAG,WAAW,CAAC,oCAAoC,CAAC,CAAC;AAEhE;IAUE;;;;OAIG;IACH,YAAY,QAA0B;QACpC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACG,IAAI;;YACR,IAAI,IAAI,CAAC,SAAS,EAAE;gBAClB,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;aAC9B;QACH,CAAC;KAAA;CACF;AA7BD,wCA6BC;AAED;;;;;GAKG;AACH,uBAA+B,SAAQ,mCAAgB;IAErD;;;;;;;;;;;;;;;;;;OAkBG;IACH,YAAY,OAA0B,EAAE,WAA4B,EAAE,OAAwB;QAC5F,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACH,gBAAgB,CAAC,SAAoB,EAAE,OAAgB;QACrD,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE;YACjD,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;SACxF;QACD,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;YAC7C,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;SACtF;QACD,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACrC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACzB,IAAI,CAAC,QAAS,CAAC,GAAG,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;SACJ;aAAM;YACL,uGAAuG;YACvG,0GAA0G;YAC1G,gDAAgD;YAChD,KAAK,CAAC,kFAAkF;gBACtF,4DAA4D,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACvG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1D,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YAC9D,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;YACjE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;YAC1D,KAAK,CAAC,yDAAyD;gBAC7D,wCAAwC,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;SACpF;IACH,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,MAAM,CAAC,OAA0B,EAAE,WAA4B,EAAE,OAAwB;QAC9F,MAAM,SAAS,GAAG,IAAI,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QACvE,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;QAC9C,OAAO,SAAS,CAAC;IACnB,CAAC;CACF;AAxED,8CAwEC"}
{"version":3,"file":"streamingReceiver.js","sourceRoot":"","sources":["../../lib/streamingReceiver.ts"],"names":[],"mappings":"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"}

Просмотреть файл

@ -8,7 +8,7 @@ const path = process.env[entityPath] || "";
async function main(): Promise<void> {
const client = EventHubClient.createFromConnectionString(str, path);
const result: EventData[] = await client.receiveBatch("0", 10, 20, { enableReceiverRuntimeMetric: true });
const result: EventData[] = await client.receiveBatch("0", 10, 20);
console.log(">>> EventDataObjects: ", result);
let i = 0;
for (let data of result) {

21
examples/simpleSender.ts Normal file
Просмотреть файл

@ -0,0 +1,21 @@
import { EventHubClient, EventData } from "../lib";
const connectionString = "EVENTHUB_CONNECTION_STRING";
const entityPath = "EVENTHUB_NAME";
const str = process.env[connectionString] || "";
const path = process.env[entityPath] || "";
async function main(): Promise<void> {
const client = EventHubClient.createFromConnectionString(str, path);
const data: EventData = {
body: "Hello World!!"
};
const delivery = await client.send(data);
console.log(">>> Sent the message successfully: ", delivery.id);
// await client.close();
}
main().catch((err) => {
console.log("error: ", err);
});

Просмотреть файл

@ -0,0 +1,28 @@
import { EventHubClient, EventPosition, OnMessage, OnError, EventHubsError, ReceiveOptions } from "../lib";
const connectionString = "EVENTHUB_CONNECTION_STRING";
const entityPath = "EVENTHUB_NAME";
const str = process.env[connectionString] || "";
const path = process.env[entityPath] || "";
async function main(): Promise<void> {
const client = EventHubClient.createFromConnectionString(str, path);
const onMessage: OnMessage = async (eventData: any) => {
console.log(">>> EventDataObject: ", eventData);
console.log("### Actual message:", eventData.body ? eventData.body.toString() : null);
}
const onError: OnError = (err: EventHubsError | Error) => {
console.log(">>>>> Error occurred: ", err);
};
const options: ReceiveOptions = {
eventPosition: EventPosition.fromEnqueuedTime(Date.now()),
enableReceiverRuntimeMetric: true
}
const rcvHandler = client.receiveOnMessage("0", onMessage, onError, options);
console.log("rcvHandler: ", rcvHandler.name);
}
main().catch((err) => {
console.log("error: ", err);
});

Просмотреть файл

@ -125,7 +125,7 @@ export class BatchingReceiver extends EventHubReceiver {
waitTimer = setTimeout(actionAfterWaitTimeout, (maxWaitTimeInSeconds as number) * 1000);
};
if (!this._session && !this._receiver) {
if (!this._isOpen()) {
debug("[%s] Receiver '%s', setting the prefetch count to 0.", this._context.connectionId, this.name);
this.prefetchCount = 0;
this._init(onReceiveMessage, onReceiveError).then(() => addCreditAndSetTimer()).catch(reject);

Просмотреть файл

@ -8,6 +8,7 @@ import * as uuid from "uuid/v4";
import * as Constants from "./util/constants";
import * as debugModule from "debug";
import { AmqpMessage } from ".";
import { translate } from "./errors";
const debug = debugModule("azure:event-hubs:cbs");
/**
@ -48,6 +49,14 @@ export class CbsClient {
name: this.replyTo
};
this._cbsSenderReceiverLink = await createRequestResponseLink(connection, { target: { address: this.endpoint } }, rxOpt);
this._cbsSenderReceiverLink.sender.on("sender_error", (context: rheaPromise.Context) => {
const ehError = translate(context.sender.error);
debug("An error occurred on the cbs sender link.. %O", ehError);
});
this._cbsSenderReceiverLink.receiver.on("receiver_error", (context: rheaPromise.Context) => {
const ehError = translate(context.receiver.error);
debug("An error occurred on the cbs receiver link.. %O", ehError);
});
debug("[%s] Successfully created the cbs sender '%s' and receiver '%s' links over cbs session.",
connection.options.id, this._cbsSenderReceiverLink.sender.name, this._cbsSenderReceiverLink.receiver.name);
} else {

Просмотреть файл

@ -66,7 +66,7 @@ export enum ConditionErrorNameMapper {
/**
* Error is thrown when the service is unavailable. The operation should be retried.
*/
"com.microsoft:timeout" = "ServiceUnavailableError",
"com.microsoft:timeout" = "ServiceUnavailableError", // Retryable
/**
* Error is thrown when an argument has a value that is out of the admissible range.
*/
@ -198,7 +198,7 @@ export enum ErrorNameConditionMapper {
/**
* Error is thrown when the service is unavailable. The operation should be retried.
*/
ServiceUnavailableError = "com.microsoft:timeout",
ServiceUnavailableError = "com.microsoft:timeout", // Retryable
/**
* Error is thrown when an argument has a value that is out of the admissible range.
*/
@ -309,9 +309,9 @@ export class EventHubsError extends Error {
*/
name: string = "EventHubsError";
/**
* @property {boolean} translated Has the error been previously translated. Default value: false.
* @property {boolean} translated Has the error been translated. Default: true.
*/
translated: boolean = false;
translated: boolean = true;
/**
*
* @param {boolean} retryable Describes whether the error is retryable. Default: false.
@ -367,15 +367,15 @@ export function translate(err: AmqpError | Error): EventHubsError {
description.match(/The messaging entity .* could not be found.*/i) !== null)) {
error.name = "MessagingEntityNotFoundError";
}
error.translated = true;
if (error.name === "InternalServerError" || error.name === "ServerBusyError") {
if (error.name === "InternalServerError"
|| error.name === "ServerBusyError"
|| error.name === "ServiceUnavailableError") {
error.retryable = true;
}
return error;
} else {
// Translate a generic error into EventHubsError.
const error = new EventHubsError((err as Error).message);
error.translated = true;
return error;
}
}

Просмотреть файл

@ -199,6 +199,8 @@ export class EventHubReceiver {
this._onAmqpError = (context: rheaPromise.Context) => {
const ehError = translate(context.receiver.error);
// TODO: Should we retry before calling user's error method?
debug("[%s] An error occurred for Receiver '%s': %O.",
this._context.connectionId, this.name, ehError);
this._onError!(ehError);
};
}
@ -240,7 +242,7 @@ export class EventHubReceiver {
await defaultLock.acquire(this._context.connectionLock, () => { return rpc.open(this._context); });
}
if (!this._session && !this._receiver) {
if (!this._isOpen()) {
await this._negotiateClaim();
if (!onAmqpMessage) {
onAmqpMessage = this._onAmqpMessage;
@ -253,7 +255,8 @@ export class EventHubReceiver {
const rcvrOptions = this._createReceiverOptions();
this._receiver = await rheaPromise.createReceiverWithHandlers(this._session, onAmqpMessage, onAmqpError, rcvrOptions);
debug("Promise to create the receiver resolved. Created receiver with name: ", this.name);
debug("[%s] Receiver '%s' created with receiver options: %O", this._context.connectionId, this.name, rcvrOptions);
debug("[%s] Receiver '%s' created with receiver options: %O",
this._context.connectionId, this.name, rcvrOptions);
// It is possible for someone to close the receiver and then start it again.
// Thus make sure that the receiver is present in the client cache.
if (!this._context.receivers[this.name]) this._context.receivers[this.name] = this;
@ -261,11 +264,28 @@ export class EventHubReceiver {
}
} catch (err) {
err = translate(err);
debug("[%s] An error occured while creating the receiver '%s': %O", this._context.connectionId, this.name, err);
debug("[%s] An error occured while creating the receiver '%s': %O",
this._context.connectionId, this.name, err);
throw err;
}
}
/**
* Determines whether the AMQP receiver link is open. If open then returns true else returns false.
* @protected
*
* @return {boolean} boolean
*/
protected _isOpen(): boolean {
let result: boolean = false;
if (this._session && this._receiver) {
if (this._receiver.is_open && this._receiver.is_open()) {
result = true;
}
}
return result;
}
/**
* Creates the options that need to be specified while creating an AMQP receiver link.
* @private

Просмотреть файл

@ -7,11 +7,10 @@ import * as uuid from "uuid/v4";
import { translate } from "./errors";
import * as rpc from "./rpc";
import * as rheaPromise from "./rhea-promise";
import * as Constants from "./util/constants";
import { EventEmitter } from "events";
import { EventData, AmqpMessage, messageProperties } from "./eventData";
import { ConnectionContext } from "./connectionContext";
import { defaultLock, Func } from "./util/utils";
import { retry } from "./retry";
const debug = debugModule("azure:event-hubs:sender");
@ -22,7 +21,7 @@ const debug = debugModule("azure:event-hubs:sender");
* @param {any} sender - The amqp sender link.
* @constructor
*/
export class EventHubSender extends EventEmitter {
export class EventHubSender {
/**
* @property {string} [name] The unique EventHub Sender name (mostly a guid).
*/
@ -71,10 +70,10 @@ export class EventHubSender extends EventEmitter {
* Creates a new EventHubSender instance.
* @constructor
* @param {EventHubClient} client The EventHub client.
* @param {string|number} [partitionId] The EventHub partition id to which the sender wants to send the event data.
* @param {string|number} [partitionId] The EventHub partition id to which the sender
* wants to send the event data.
*/
constructor(context: ConnectionContext, partitionId?: string | number, name?: string) {
super();
this._context = context;
this.name = name || uuid();
this.address = this._context.config.entityPath as string;
@ -83,34 +82,13 @@ export class EventHubSender extends EventEmitter {
this.address += `/Partitions/${this.partitionId}`;
}
this.audience = `${this._context.config.endpoint}${this.address}`;
const onError = (context: rheaPromise.Context) => {
this.emit(Constants.error, translate(context.sender.error));
};
this.on("newListener", (event) => {
if (event === Constants.error) {
if (this._session && this._sender) {
debug("Attaching an event handler for the 'sender_error' event on the underlying amqp sender: ", this.name!);
this._sender.on(Constants.senderError, onError);
}
}
});
this.on("removeListener", (event) => {
if (event === Constants.error) {
if (this._session && this._sender) {
debug("Removing an event handler for the 'sender_error' event on the underlying amqp sender: ", this.name!);
this._sender.removeListener(Constants.senderError, onError);
}
}
});
}
/**
* Sends the given message, with the given options on this link
*
* @method send
* @param {any} data Message to send. Will be sent as UTF8-encoded JSON string.
* @param {any} data Message to send. Will be sent as UTF8-encoded JSON string.
* @returns {Promise<rheaPromise.Delivery>} Promise<rheaPromise.Delivery>
*/
async send(data: EventData): Promise<rheaPromise.Delivery> {
@ -119,8 +97,9 @@ export class EventHubSender extends EventEmitter {
throw new Error("data is required and it must be of type object.");
}
if (!this._session && !this._sender) {
debug("Acquiring lock %s for initializing the session, sender and possibly the connection.", this.senderLock);
if (!this._isOpen()) {
debug("Acquiring lock %s for initializing the session, sender and " +
"possibly the connection.", this.senderLock);
await defaultLock.acquire(this.senderLock, () => { return this._init(); });
}
@ -133,8 +112,9 @@ export class EventHubSender extends EventEmitter {
}
/**
* Send a batch of EventData to the EventHub. The "message_annotations", "application_properties" and "properties"
* of the first message will be set as that of the envelope (batch message).
* Send a batch of EventData to the EventHub. The "message_annotations",
* "application_properties" and "properties" of the first message will be set as that
* of the envelope (batch message).
* @param {Array<EventData>} datas An array of EventData objects to be sent in a Batch message.
* @return {Promise<rheaPromise.Delivery>} Promise<rheaPromise.Delivery>
*/
@ -144,11 +124,13 @@ export class EventHubSender extends EventEmitter {
throw new Error("data is required and it must be an Array.");
}
if (!this._session && !this._sender) {
debug("Acquiring lock %s for initializing the session, sender and possibly the connection.", this.senderLock);
if (!this._isOpen()) {
debug("Acquiring lock %s for initializing the session, sender and " +
"possibly the connection.", this.senderLock);
await defaultLock.acquire(this.senderLock, () => { return this._init(); });
}
debug("[%s] Sender '%s', trying to send EventData[]: %O", this._context.connectionId, this.name, datas);
debug("[%s] Sender '%s', trying to send EventData[]: %O",
this._context.connectionId, this.name, datas);
const messages: AmqpMessage[] = [];
// Convert EventData to AmqpMessage.
for (let i = 0; i < datas.length; i++) {
@ -175,7 +157,8 @@ export class EventHubSender extends EventEmitter {
// Finally encode the envelope (batch message).
const encodedBatchMessage = rhea.message.encode(batchMessage);
debug("[%s]Sender '%s', sending encoded batch message.", this._context.connectionId, this.name, encodedBatchMessage);
debug("[%s]Sender '%s', sending encoded batch message.",
this._context.connectionId, this.name, encodedBatchMessage);
return await this._trySend(encodedBatchMessage, undefined, 0x80013700);
} catch (err) {
debug("An error occurred while sending the batch message %O", err);
@ -185,7 +168,7 @@ export class EventHubSender extends EventEmitter {
/**
* "Unlink" this sender, closing the link and resolving when that operation is complete.
* Leaves the underlying connection/session open.
* Leaves the underlying connection open.
* @method close
* @return {Promise<void>} Promise<void>
*/
@ -193,9 +176,9 @@ export class EventHubSender extends EventEmitter {
if (this._sender) {
try {
await rheaPromise.closeSender(this._sender);
this.removeAllListeners();
delete this._context.senders[this.name!];
debug("[%s] Deleted the sender '%s' from the client cache.", this._context.connectionId, this.name);
debug("[%s] Deleted the sender '%s' from the client cache.",
this._context.connectionId, this.name);
this._sender = undefined;
this._session = undefined;
clearTimeout(this._tokenRenewalTimer as NodeJS.Timer);
@ -222,15 +205,16 @@ export class EventHubSender extends EventEmitter {
* Tries to send the message to EventHub if there is enough credit to send them
* and the circular buffer has available space to settle the message after sending them.
*
* We have implemented a synchronous send over here. We shall be waiting for the message
* to be accepted or rejected and accordingly resolve or reject the promise.
* We have implemented a synchronous send over here in the sense that we shall be waiting
* for the message to be accepted or rejected and accordingly resolve or reject the promise.
*
* @param message The message to be sent to EventHub.
* @return {Promise<rheaPromise.Delivery>} Promise<rheaPromise.Delivery>
*/
private _trySend(message: AmqpMessage, tag?: any, format?: number): Promise<rheaPromise.Delivery> {
return new Promise((resolve, reject) => {
debug("[%s] Sender '%s', credit: %d available: %d", this._context.connectionId, this._sender.credit, this._sender.session.outgoing.available());
const sendEventPromise = new Promise<rheaPromise.Delivery>((resolve, reject) => {
debug("[%s] Sender '%s', credit: %d available: %d", this._context.connectionId, this.name,
this._sender.credit, this._sender.session.outgoing.available());
if (this._sender.sendable()) {
debug("[%s] Sender '%s', sending message: %O", this._context.connectionId, this.name, message);
let onRejected: Func<rheaPromise.Context, void>;
@ -264,7 +248,8 @@ export class EventHubSender extends EventEmitter {
if (context!.delivery!.remote_state.error) {
err = translate(context!.delivery!.remote_state.error);
} else {
err = new Error(`[${this._context.connectionId}] Sender '${this.name}', received a release disposition. Hence we are rejecting the promise.`);
err = new Error(`[${this._context.connectionId}] Sender '${this.name}', ` +
`received a release disposition. Hence we are rejecting the promise.`);
}
reject(err);
};
@ -275,7 +260,8 @@ export class EventHubSender extends EventEmitter {
if (context!.delivery!.remote_state.error) {
err = translate(context!.delivery!.remote_state.error);
} else {
err = new Error(`[${this._context.connectionId}] Sender "${this.name}", received a modified disposition. Hence we are rejecting the promise.`);
err = new Error(`[${this._context.connectionId}] Sender "${this.name}", ` +
`received a modified disposition. Hence we are rejecting the promise.`);
}
reject(err);
};
@ -284,13 +270,33 @@ export class EventHubSender extends EventEmitter {
this._sender.on("modified", onModified);
this._sender.on("released", onReleased);
const delivery = this._sender.send(message, tag, format);
debug("[%s] Sender '%s', sent message with delivery id: %d", this._context.connectionId, this.name, delivery.id);
debug("[%s] Sender '%s', sent message with delivery id: %d",
this._context.connectionId, this.name, delivery.id);
} else {
const msg = `[${this._context.connectionId}] Sender "${this.name}", cannot send the message right now. Please try later.`;
const msg = `[${this._context.connectionId}] Sender "${this.name}", ` +
`cannot send the message right now. Please try later.`;
debug(msg);
reject(new Error(msg));
}
});
return retry<rheaPromise.Delivery>(() => sendEventPromise);
}
/**
* Determines whether the AMQP sender link is open. If open then returns true else returns false.
* @private
*
* @return {boolean} boolean
*/
private _isOpen(): boolean {
let result: boolean = false;
if (this._session && this._sender) {
if (this._sender.is_open && this._sender.is_open()) {
result = true;
}
}
return result;
}
/**
@ -301,40 +307,36 @@ export class EventHubSender extends EventEmitter {
try {
// Acquire the lock and establish an amqp connection if it does not exist.
if (!this._context.connection) {
debug("[%s] EH Sender '%s' establishing an AMQP connection.", this._context.connectionId, this.name);
debug("[%s] EH Sender '%s' establishing an AMQP connection.",
this._context.connectionId, this.name);
await defaultLock.acquire(this._context.connectionLock, () => { return rpc.open(this._context); });
}
if (!this._session && !this._sender) {
await this._negotiateClaim();
let senderError: any;
this._session = await rheaPromise.createSession(this._context.connection);
const handleSenderError = (context: rheaPromise.Context) => {
senderError = translate(context.sender.error);
debug("[%s] An error occurred while creating the sender: %O.", this._context.connectionId, senderError);
const onAmqpError = (context: rheaPromise.Context) => {
const senderError = translate(context.sender.error);
// TODO: Should we retry before calling user's error method?
debug("[%s] An error occurred for sender '%s': %O.",
this._context.connectionId, this.name, senderError);
};
this._session.on(Constants.senderError, handleSenderError);
this._session = await rheaPromise.createSession(this._context.connection);
debug("[%s] Trying to create sender '%s'...", this._context.connectionId, this.name);
const options = this._createSenderOptions();
debug("[%s] Trying to create a sender...", this._context.connectionId, );
this._sender = await rheaPromise.createSender(this._session, options);
debug("[%s] Promise to create the sender resolved. Created sender with name: %s", this._context.connectionId, this.name);
if (senderError) {
// There are cases where the EH service sends an attach frame, which causes rhea to emit sender_open event
// thus resolving the promise to create a sender and moments later the service sends back a detach frame
// indicating that there was some error. Hence we check for senderError, even after the promise has resolved.
debug("[%s] throwing the senderError, %O", this._context.connectionId, senderError);
throw senderError;
}
this._session.removeListener(Constants.senderError, handleSenderError);
debug("[%s] Sender '%s' created with sender options: %O", this._context.connectionId, this.name, options);
this._sender = await rheaPromise.createSenderWithHandlers(this._session, onAmqpError, options);
debug("[%s] Promise to create the sender resolved. Created sender with name: %s",
this._context.connectionId, this.name);
debug("[%s] Sender '%s' created with sender options: %O",
this._context.connectionId, this.name, options);
// It is possible for someone to close the sender and then start it again.
// Thus make sure that the sender is present in the client cache.
if (!this._context.senders[this.name]) this._context.senders[this.name] = this;
if (!this._context.senders[this.address]) this._context.senders[this.address] = this;
await this._ensureTokenRenewal();
}
} catch (err) {
err = translate(err);
debug("[%s] An error occurred while creating the sender %s", this._context.connectionId, this.name, err);
debug("[%s] An error occurred while creating the sender %s",
this._context.connectionId, this.name, err);
throw err;
}
}
@ -346,23 +348,26 @@ export class EventHubSender extends EventEmitter {
* @return {Promise<void>} Promise<void>
*/
private async _negotiateClaim(setTokenRenewal?: boolean): Promise<void> {
// Acquire the lock and establish a cbs session if it does not exist on the connection. Although node.js
// is single threaded, we need a locking mechanism to ensure that a race condition does not happen while
// creating a shared resource (in this case the cbs session, since we want to have exactly 1 cbs session
// per connection).
// Acquire the lock and establish a cbs session if it does not exist on the connection.
// Although node.js is single threaded, we need a locking mechanism to ensure that a
// race condition does not happen while creating a shared resource (in this case the
// cbs session, since we want to have exactly 1 cbs session per connection).
debug("[%s] Acquiring lock: '%s' for creating the cbs session while creating the sender: '%s'.",
this._context.connectionId, this._context.cbsSession.cbsLock, this.name);
await defaultLock.acquire(this._context.cbsSession.cbsLock,
() => { return this._context.cbsSession.init(this._context.connection); });
const tokenObject = await this._context.tokenProvider.getToken(this.audience);
debug("[%s] EH Sender: calling negotiateClaim for audience '%s'.", this._context.connectionId, this.audience);
debug("[%s] EH Sender: calling negotiateClaim for audience '%s'.",
this._context.connectionId, this.audience);
// Acquire the lock to negotiate the CBS claim.
debug("[%s] Acquiring lock: '%s' for cbs auth for sender: '%s'.",
this._context.connectionId, this._context.negotiateClaimLock, this.name);
await defaultLock.acquire(this._context.negotiateClaimLock, () => {
return this._context.cbsSession.negotiateClaim(this.audience, this._context.connection, tokenObject);
return this._context.cbsSession.negotiateClaim(this.audience,
this._context.connection, tokenObject);
});
debug("[%s] Negotiated claim for sender '%s' with with partition: %s", this._context.connectionId, this.partitionId);
debug("[%s] Negotiated claim for sender '%s' with with partition: %s",
this._context.connectionId, this.partitionId);
if (setTokenRenewal) {
await this._ensureTokenRenewal();
}
@ -382,8 +387,8 @@ export class EventHubSender extends EventEmitter {
await this._negotiateClaim(true);
} catch (err) {
// TODO: May be add some retries over here before emitting the error.
debug("[%s] Sender '%s', an error occurred while renewing the token: %O", this._context.connectionId, this.name, err);
this.emit(Constants.error, translate(err));
debug("[%s] Sender '%s', an error occurred while renewing the token: %O",
this._context.connectionId, this.name, err);
}
}, nextRenewalTimeout);
debug("[%s]Sender '%s', has next token renewal in %d seconds @(%s).",
@ -391,8 +396,8 @@ export class EventHubSender extends EventEmitter {
}
/**
* Creates a new sender to the given event hub, and optionally to a given partition if it is not present
* in the context or returns the one present in the context.
* Creates a new sender to the given event hub, and optionally to a given partition if it is
* not present in the context or returns the one present in the context.
* @static
* @param {(string|number)} [partitionId] Partition ID to which it will send event data.
* @returns {Promise<EventHubSender>}

77
lib/retry.ts Normal file
Просмотреть файл

@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import { translate, EventHubsError } from "./errors";
import { delay } from ".";
import * as debugModule from "debug";
const debug = debugModule("azure:event-hubs:retry");
function isDelivery(obj: any): boolean {
let result: boolean = false;
if (obj && typeof obj.id === "number" && typeof obj.settled === "boolean" &&
typeof obj.remote_settled === "boolean" && typeof obj.format === "number") {
result = true;
}
return result;
}
/**
* It will attempt to linearly retry an operation specified number of times with a specified
* delay in between each retry. The retries will only happen if the error is retryable.
*
* @param {Promise<T>} operation The operation that needs to be retried.
* @param {number} [times] Number of times the operation needs to be retried in case of error. Default: 3.
* @param {number} [delayInSeconds] Amount of time to wait in seconds before making the next attempt. Default: 15.
*
* @return {Promise<T>} Promise<T>.
*/
export async function retry<T>(operation: () => Promise<T>, times?: number, delayInSeconds?: number): Promise<T> {
if (!operation || typeof operation !== "function") {
throw new Error("'operation' is a required parameter and must be of type 'function'.");
}
if (times && typeof times !== "number") {
throw new Error("'times' must be of type 'number'.");
}
if (delayInSeconds && typeof delayInSeconds !== "number") {
throw new Error("'delayInSeconds' must be of type 'number'.");
}
if (!times) times = 3;
if (!delayInSeconds) delayInSeconds = 15;
let lastError: EventHubsError | undefined;
let result: any;
let success = false;
for (let i = 0; i < times; i++) {
const j = i + 1;
debug("Retry attempt number: %d", j);
try {
result = await operation();
success = true;
debug("Success, after attempt number: %d.", j);
if (!isDelivery(result)) {
debug("Success result: %O", result);
}
break;
} catch (err) {
if (!err.translated) {
err = translate(err);
}
lastError = err;
debug("Error occured in attempt number %d: %O", j, err);
if (lastError!.retryable) {
debug("Sleeping for %d seconds.", delayInSeconds);
await delay(delayInSeconds * 1000);
continue;
} else {
break;
}
}
}
if (success) {
return result;
} else {
throw lastError;
}
}

Просмотреть файл

@ -204,6 +204,49 @@ export function createSender(session: any, options?: SenderOptions): Promise<any
});
}
/**
* Creates an amqp sender on the provided amqp session.
* @param {Session} session The amqp session object on which the sender link needs to be established.
* @param {OnAmqpEvent} onError The event handler for the "error" event for the sender.
* @param {SenderOptions} [options] Options that can be provided while creating an amqp sender.
* @return {Promise<Sender>} Promise<Sender>
* - **Resolves** the promise with the Sender object when rhea emits the "sender_open" event.
* - **Rejects** the promise with an AmqpError when rhea emits the "sender_close" event while trying
* to create an amqp sender.
*/
export function createSenderWithHandlers(session: any, onError: OnAmqpEvent, options?: SenderOptions): Promise<any> {
if (!session || (session && typeof session !== "object")) {
throw new Error("session is a required parameter and must be of type 'object'.");
}
return new Promise((resolve, reject) => {
const sender = session.attach_sender(options);
sender.on("sender_error", onError);
function removeListeners(session: any): void {
sender.removeListener("sendable", onOpen);
sender.removeListener("sender_close", onClose);
}
function onOpen(context: any): void {
removeListeners(session);
process.nextTick(() => {
debug(`Resolving the promise with amqp sender "${sender.name}".`);
resolve(sender);
});
}
function onClose(context: Context): void {
removeListeners(session);
debug(`Error occurred while creating a sender over amqp connection.`, context.sender.error);
reject(context.sender.error);
}
sender.once("sendable", onOpen);
sender.once("sender_close", onClose);
});
}
/**
* Closes the amqp sender.
* @param {Sender} sender The amqp sender that needs to be closed.
@ -315,6 +358,7 @@ export function createReceiverWithHandlers(session: any, onMessage: OnAmqpEvent,
const receiver = session.attach_receiver(options);
receiver.on("message", onMessage);
receiver.on("receiver_error", onError);
function removeListeners(receiver: any): void {
receiver.removeListener("receiver_open", onOpen);
receiver.removeListener("receiver_close", onClose);

Просмотреть файл

@ -7,7 +7,7 @@ import * as debugModule from "debug";
import * as uuid from "uuid/v4";
import { defaultLock } from "./util/utils";
import {
ReceiverOptions, SenderOptions, createSession,
ReceiverOptions, SenderOptions, createSession, createSenderWithHandlers,
createSender, createReceiver, connect, ConnectionOptions,
OnAmqpEvent, AmqpError, createReceiverWithHandlers, Context
} from "./rhea-promise";
@ -15,6 +15,7 @@ import * as Constants from "./util/constants";
import { ConnectionContext } from "./connectionContext";
import { ConditionStatusMapper, translate } from "./errors";
import { AmqpMessage } from ".";
import { retry } from "./retry";
const debug = debugModule("azure:event-hubs:rpc");
export interface RequestResponseLink {
@ -35,14 +36,18 @@ export interface SenderLink {
export interface LinkOptions {
connection: any;
onError: OnAmqpEvent;
}
export interface ReceiverLinkOptions extends LinkOptions {
onMessage: OnAmqpEvent;
onError: OnAmqpEvent;
receiverOptions: ReceiverOptions;
}
export interface SenderLinkOptions extends LinkOptions {
senderOptions: SenderOptions;
}
export async function createRequestResponseLink(connection: any, senderOptions: SenderOptions, receiverOptions: ReceiverOptions): Promise<RequestResponseLink> {
if (!connection) {
throw new Error(`Please provide a connection to create the sender/receiver link on the same session.`);
@ -99,7 +104,8 @@ export async function createReceiverLinkWithHandlers(options: ReceiverLinkOption
}
const session = await createSession(options.connection);
const receiver = await createReceiverWithHandlers(session, options.onMessage, options.onError, options.receiverOptions);
debug("[%s] Successfully created the receiver link on a dedicated session for it.", options.connection.options.id);
debug("[%s] Successfully created the receiver link on a dedicated session for it.",
options.connection.options.id);
return {
session: session,
receiver: receiver
@ -115,7 +121,29 @@ export async function createSenderLink(connection: any, senderOptions: SenderOpt
}
const session = await createSession(connection);
const sender = await createSender(session, senderOptions);
debug("[%s] Successfully created the sender link on a dedicated session for it.", connection.options.id);
debug("[%s] Successfully created the sender link on a dedicated session for it.",
connection.options.id);
return {
session: session,
sender: sender
};
}
export async function createSenderLinkWithHandlers(options: SenderLinkOptions): Promise<SenderLink> {
if (!options.connection) {
throw new Error(`Please provide a connection to create the sender link on a session.`);
}
if (!options.senderOptions) {
throw new Error(`Please provide sender options.`);
}
if (!options.onError) {
throw new Error(`Please provide onError.`);
}
const session = await createSession(options.connection);
const sender = await createSenderWithHandlers(session, options.onError, options.senderOptions);
debug("[%s] Successfully created the sender link on a dedicated session for it.",
options.connection.options.id);
return {
session: session,
sender: sender
@ -138,10 +166,10 @@ export function sendRequest(connection: any, link: RequestResponseLink, request:
if (!request.message_id) request.message_id = uuid();
if (!timeoutInSeconds) {
timeoutInSeconds = 30;
timeoutInSeconds = 10;
}
return new Promise((resolve: any, reject: any) => {
const sendRequestPromise: Promise<any> = new Promise((resolve: any, reject: any) => {
let waitTimer: any;
let timeOver: boolean = false;
@ -194,6 +222,8 @@ export function sendRequest(connection: any, link: RequestResponseLink, request:
debug("[%s] %s request sent: %O", connection.options.id, request.to || "$managment", request);
link.sender.send(request);
});
return retry(() => sendRequestPromise);
}
/**

Просмотреть файл

@ -4,7 +4,7 @@
import * as debugModule from "debug";
import { ReceiveOptions, OnMessage, OnError } from ".";
import { EventHubReceiver } from "./eventHubReceiver";
import { EventHubReceiver, ReceiverRuntimeInfo } from "./eventHubReceiver";
import { ConnectionContext } from "./connectionContext";
import * as Constants from "./util/constants";
const debug = debugModule("azure:event-hubs:receiverstreaming");
@ -12,13 +12,16 @@ const debug = debugModule("azure:event-hubs:receiverstreaming");
export class ReceiveHandler {
/**
* @property {string} name The Receiver handler name.
* @readonly
*/
name: string;
readonly name: string;
/**
* @property {EventHubReceiver} _receiver The underlying EventHubReceiver.
* @private
*/
private _receiver: EventHubReceiver;
/**
* Creates an instance of the ReceiveHandler.
* @constructor
@ -26,7 +29,17 @@ export class ReceiveHandler {
*/
constructor(receiver: EventHubReceiver) {
this._receiver = receiver;
this.name = receiver.name;
this.name = receiver ? receiver.name : "ReceiveHandler";
}
/**
* @property {ReceiverRuntimeInfo} runtimeInfo The receiver runtime info. This property will only
* be enabled when `enableReceiverRuntimeMetric` option is set to true in the
* `client.receiveOnMessage()` method.
* @readonly
*/
get runtimeInfo(): ReceiverRuntimeInfo | undefined {
return this._receiver ? this._receiver.runtimeInfo : undefined;
}
/**
@ -86,7 +99,7 @@ export class StreamingReceiver extends EventHubReceiver {
}
this._onMessage = onMessage;
this._onError = onError;
if (!this._session && !this._receiver) {
if (!this._isOpen()) {
this._init().catch((err) => {
this._onError!(err);
});

120
package-lock.json сгенерированный
Просмотреть файл

@ -184,31 +184,6 @@
"ms-rest-azure": "2.5.5"
}
},
"azure-storage": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/azure-storage/-/azure-storage-2.8.1.tgz",
"integrity": "sha1-7LnQUO8Tleef+7ZSwC/mQ2h77GM=",
"requires": {
"browserify-mime": "1.2.9",
"extend": "1.2.1",
"json-edm-parser": "0.1.2",
"md5.js": "1.3.4",
"readable-stream": "2.0.6",
"request": "2.83.0",
"underscore": "1.8.3",
"uuid": "3.2.1",
"validator": "9.4.1",
"xml2js": "0.2.8",
"xmlbuilder": "0.4.3"
},
"dependencies": {
"extend": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-1.2.1.tgz",
"integrity": "sha1-oPX9bPyDpf5J72mNYOyKYk3UV2w="
}
}
},
"babel-code-frame": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@ -284,11 +259,6 @@
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
"browserify-mime": {
"version": "1.2.9",
"resolved": "https://registry.npmjs.org/browserify-mime/-/browserify-mime-1.2.9.tgz",
"integrity": "sha1-rrGvKN5sDXpqLOQK22j/GEIq8x8="
},
"buffer": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz",
@ -623,15 +593,6 @@
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"hash-base": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
"integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
"requires": {
"inherits": "2.0.3",
"safe-buffer": "5.1.1"
}
},
"hawk": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
@ -682,7 +643,8 @@
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
"is-buffer": {
"version": "1.1.6",
@ -699,11 +661,6 @@
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@ -731,14 +688,6 @@
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
},
"json-edm-parser": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/json-edm-parser/-/json-edm-parser-0.1.2.tgz",
"integrity": "sha1-HmCw/vG8CvZ7wNFG393lSGzWFbQ=",
"requires": {
"jsonparse": "1.2.0"
}
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
@ -754,11 +703,6 @@
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsonparse": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.2.0.tgz",
"integrity": "sha1-XAxWhRBxYOcv50ib3eoLRMK8Z70="
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@ -802,15 +746,6 @@
"integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==",
"dev": true
},
"md5.js": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
"integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
"requires": {
"hash-base": "3.0.4",
"inherits": "2.0.3"
}
},
"mime-db": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
@ -981,11 +916,6 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"process-nextick-args": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
@ -996,19 +926,6 @@
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
},
"readable-stream": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
"integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "1.0.7",
"string_decoder": "0.10.31",
"util-deprecate": "1.0.2"
}
},
"request": {
"version": "2.83.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
@ -1060,11 +977,6 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"sax": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz",
"integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE="
},
"semver": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
@ -1115,11 +1027,6 @@
"tweetnacl": "0.14.5"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
@ -1248,21 +1155,11 @@
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"uuid": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
"integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA=="
},
"validator": {
"version": "9.4.1",
"resolved": "https://registry.npmjs.org/validator/-/validator-9.4.1.tgz",
"integrity": "sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA=="
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
@ -1279,19 +1176,6 @@
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"xml2js": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.2.8.tgz",
"integrity": "sha1-m4FpCTFjH/CdGVdUn69U9PmAs8I=",
"requires": {
"sax": "0.5.8"
}
},
"xmlbuilder": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.4.3.tgz",
"integrity": "sha1-xGFLp04K0ZbmCcknLNnh3bKKilg="
},
"xmldom": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",

Просмотреть файл

@ -12,7 +12,6 @@
"@types/node": "^8.0.37",
"async-lock": "^1.1.2",
"azure-arm-eventhub": "^1.3.0",
"azure-storage": "^2.8.1",
"buffer": "^5.1.0",
"debug": "^3.1.0",
"ms-rest": "^2.3.3",

Просмотреть файл

@ -24,7 +24,6 @@ describe("Errors", function () {
const err = new MyError();
const msg: any = undefined;
const ehError = new Errors.EventHubsError(msg);
ehError.translated = true;
const translatedError = Errors.translate(err);
translatedError.name.should.equal(ehError.name);
translatedError.retryable.should.equal(ehError.retryable);

155
tests/retry.spec.ts Normal file
Просмотреть файл

@ -0,0 +1,155 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
import { retry } from "../lib/retry";
import * as chai from "chai";
import { delay, EventHubsError } from "../lib";
import * as debugModule from "debug";
import { translate } from "../lib/errors";
const debug = debugModule("azure:event-hubs:retry-spec");
const should = chai.should();
describe("retry function", function () {
it("should succeed if the operation succeeds.", async function () {
let counter = 0;
try {
const operation = async () => {
debug("counter: %d", ++counter);
await delay(200);
return {
code: 200,
description: "OK"
}
};
const result = await retry(operation);
result.code.should.equal(200);
result.description.should.equal("OK");
counter.should.equal(1);
} catch (err) {
debug("An error occurred in a test that should have succeeded: %O", err);
throw err;
}
});
it("should fail if the operation returns a non retryable error", async function () {
let counter = 0;
try {
const operation = async () => {
debug("counter: %d", ++counter);
await delay(200);
throw new Error("I would like to fail.");
};
await retry(operation);
} catch (err) {
should.exist(err);
should.equal(true, err instanceof EventHubsError);
err.message.should.equal("I would like to fail.");
counter.should.equal(1);
}
});
it.only("should succeed if the operation initially fails with a retryable error and then succeeds.", async function () {
let counter = 0;
try {
const operation = async () => {
await delay(200);
debug("counter: %d", ++counter);
if (counter == 1) {
throw translate({
condition: "com.microsoft:server-busy",
description: "The server is busy right now. Retry later."
});
} else {
return {
code: 200,
description: "OK"
};
}
};
const result = await retry(operation, 3, 0.5);
result.code.should.equal(200);
result.description.should.equal("OK");
counter.should.equal(2);
} catch (err) {
debug("An error occurred in a test that should have succeeded: %O", err);
throw err;
}
});
it("should succeed in the last attempt.", async function () {
let counter = 0;
try {
const operation = async () => {
await delay(200);
debug("counter: %d", ++counter);
if (counter == 1) {
const e = new EventHubsError("A retryable error.");
e.retryable = true;
throw e;
} else if (counter == 2) {
const e = new EventHubsError("A retryable error.");
e.retryable = true;
throw e;
} else {
return {
code: 200,
description: "OK"
};
}
};
const result = await retry(operation, 3, 0.5);
result.code.should.equal(200);
result.description.should.equal("OK");
counter.should.equal(3);
} catch (err) {
debug("An error occurred in a test that should have succeeded: %O", err);
throw err;
}
});
it("should fail if the last attempt return a non-retryable error", async function () {
let counter = 0;
try {
const operation = async () => {
await delay(200);
debug("counter: %d", ++counter);
if (counter == 1) {
const e = new EventHubsError("A retryable error.");
e.retryable = true;
throw e;
} else if (counter == 2) {
const e = new EventHubsError("A retryable error.");
e.retryable = true;
throw e;
} else {
throw new Error("I would like to fail.");
}
};
await retry(operation, 3, 0.5);
} catch (err) {
should.exist(err);
should.equal(true, err instanceof EventHubsError);
err.message.should.equal("I would like to fail.");
counter.should.equal(3);
}
});
it("should fail if all attempts return a retryable error", async function () {
let counter = 0;
try {
const operation = async () => {
debug("counter: %d", ++counter);
await delay(200);
const e = new EventHubsError("I would always like to fail, keep retrying.");
e.retryable = true;
throw e;
};
await retry(operation, 4, 0.5);
} catch (err) {
should.exist(err);
should.equal(true, err instanceof EventHubsError);
err.message.should.equal("I would always like to fail, keep retrying.");
counter.should.equal(4);
}
});
});

Просмотреть файл

@ -7,9 +7,9 @@ import * as chaiAsPromised from "chai-as-promised";
chai.use(chaiAsPromised);
import * as debugModule from "debug";
const debug = debugModule("azure:event-hubs:sender-spec");
import { EventHubClient, EventData, delay } from "../lib";
import { EventHubClient, EventData } from "../lib";
describe("EventHub Sender", function () {
this.timeout(6000);
this.timeout(20000);
const service = { connectionString: process.env.EVENTHUB_CONNECTION_STRING, path: process.env.EVENTHUB_NAME };
let client: EventHubClient = EventHubClient.createFromConnectionString(service.connectionString!, service.path);
before("validate environment", function () {
@ -151,6 +151,26 @@ describe("EventHub Sender", function () {
throw err;
}
});
it("should fail when a message greater than 256 KB is sent and succeed when a normal message is sent after that on the same link.", async function () {
let data: EventData = {
body: Buffer.from("Z".repeat(300000))
}
try {
debug("Sendina message of 300KB...");
await client.send(data, "0");
} catch (err) {
debug(err);
should.exist(err);
should.equal(err.name, "MessageTooLargeError");
err.message.should.match(/.*The received message \(delivery-id:(\d+), size:3000\d\d bytes\) exceeds the limit \(262144 bytes\) currently allowed on the link\..*/ig);
}
const delivery = await client.send({ body: "Hello World EventHub!!" }, "0");
debug("Sent the message successfully on the same link..");
delivery.format.should.equal(0);
delivery.settled.should.equal(true);
delivery.remote_settled.should.equal(true);
});
});
describe("Negative scenarios", function () {
@ -175,7 +195,7 @@ describe("EventHub Sender", function () {
it(`"${id}" should throw an error`, async function () {
try {
debug("Created sender and will be sending a message to partition id ...", id);
await client.send({ body: "Hello world!" }, id);
await client.send({ body: "Hello world!" }, id as any);
debug("sent the message.");
} catch (err) {
debug(`>>>> Received error for invalid partition id "${id}" - `, err);

2
typings/lib/errors.d.ts поставляемый
Просмотреть файл

@ -302,7 +302,7 @@ export declare class EventHubsError extends Error {
*/
name: string;
/**
* @property {boolean} translated Has the error been previously translated. Default value: false.
* @property {boolean} translated Has the error been translated. Default: true.
*/
translated: boolean;
/**

7
typings/lib/eventHubReceiver.d.ts поставляемый
Просмотреть файл

@ -163,6 +163,13 @@ export declare class EventHubReceiver {
* @returns {Promise<void>}
*/
protected _init(onAmqpMessage?: rheaPromise.OnAmqpEvent, onAmqpError?: rheaPromise.OnAmqpEvent): Promise<void>;
/**
* Determines whether the AMQP receiver link is open. If open then returns true else returns false.
* @protected
*
* @return {boolean} boolean
*/
protected _isOpen(): boolean;
/**
* Creates the options that need to be specified while creating an AMQP receiver link.
* @private

31
typings/lib/eventHubSender.d.ts поставляемый
Просмотреть файл

@ -1,6 +1,4 @@
/// <reference types="node" />
import * as rheaPromise from "./rhea-promise";
import { EventEmitter } from "events";
import { EventData } from "./eventData";
import { ConnectionContext } from "./connectionContext";
/**
@ -10,7 +8,7 @@ import { ConnectionContext } from "./connectionContext";
* @param {any} sender - The amqp sender link.
* @constructor
*/
export declare class EventHubSender extends EventEmitter {
export declare class EventHubSender {
/**
* @property {string} [name] The unique EventHub Sender name (mostly a guid).
*/
@ -58,27 +56,29 @@ export declare class EventHubSender extends EventEmitter {
* Creates a new EventHubSender instance.
* @constructor
* @param {EventHubClient} client The EventHub client.
* @param {string|number} [partitionId] The EventHub partition id to which the sender wants to send the event data.
* @param {string|number} [partitionId] The EventHub partition id to which the sender
* wants to send the event data.
*/
constructor(context: ConnectionContext, partitionId?: string | number, name?: string);
/**
* Sends the given message, with the given options on this link
*
* @method send
* @param {any} data Message to send. Will be sent as UTF8-encoded JSON string.
* @param {any} data Message to send. Will be sent as UTF8-encoded JSON string.
* @returns {Promise<rheaPromise.Delivery>} Promise<rheaPromise.Delivery>
*/
send(data: EventData): Promise<rheaPromise.Delivery>;
/**
* Send a batch of EventData to the EventHub. The "message_annotations", "application_properties" and "properties"
* of the first message will be set as that of the envelope (batch message).
* Send a batch of EventData to the EventHub. The "message_annotations",
* "application_properties" and "properties" of the first message will be set as that
* of the envelope (batch message).
* @param {Array<EventData>} datas An array of EventData objects to be sent in a Batch message.
* @return {Promise<rheaPromise.Delivery>} Promise<rheaPromise.Delivery>
*/
sendBatch(datas: EventData[]): Promise<rheaPromise.Delivery>;
/**
* "Unlink" this sender, closing the link and resolving when that operation is complete.
* Leaves the underlying connection/session open.
* Leaves the underlying connection open.
* @method close
* @return {Promise<void>} Promise<void>
*/
@ -88,13 +88,20 @@ export declare class EventHubSender extends EventEmitter {
* Tries to send the message to EventHub if there is enough credit to send them
* and the circular buffer has available space to settle the message after sending them.
*
* We have implemented a synchronous send over here. We shall be waiting for the message
* to be accepted or rejected and accordingly resolve or reject the promise.
* We have implemented a synchronous send over here in the sense that we shall be waiting
* for the message to be accepted or rejected and accordingly resolve or reject the promise.
*
* @param message The message to be sent to EventHub.
* @return {Promise<rheaPromise.Delivery>} Promise<rheaPromise.Delivery>
*/
private _trySend(message, tag?, format?);
/**
* Determines whether the AMQP sender link is open. If open then returns true else returns false.
* @private
*
* @return {boolean} boolean
*/
private _isOpen();
/**
* Initializes the sender session on the connection.
* @returns {Promise<void>}
@ -114,8 +121,8 @@ export declare class EventHubSender extends EventEmitter {
*/
private _ensureTokenRenewal();
/**
* Creates a new sender to the given event hub, and optionally to a given partition if it is not present
* in the context or returns the one present in the context.
* Creates a new sender to the given event hub, and optionally to a given partition if it is
* not present in the context or returns the one present in the context.
* @static
* @param {(string|number)} [partitionId] Partition ID to which it will send event data.
* @returns {Promise<EventHubSender>}

11
typings/lib/retry.d.ts поставляемый Normal file
Просмотреть файл

@ -0,0 +1,11 @@
/**
* It will attempt to linearly retry an operation specified number of times with a specified
* delay in between each retry. The retries will only happen if the error is retryable.
*
* @param {Promise<T>} operation The operation that needs to be retried.
* @param {number} [times] Number of times the operation needs to be retried in case of error. Default: 3.
* @param {number} [delayInSeconds] Amount of time to wait in seconds before making the next attempt. Default: 15.
*
* @return {Promise<T>} Promise<T>.
*/
export declare function retry<T>(operation: () => Promise<T>, times?: number, delayInSeconds?: number): Promise<T>;

11
typings/lib/rhea-promise/index.d.ts поставляемый
Просмотреть файл

@ -46,6 +46,17 @@ export declare function closeSession(session: any): Promise<void>;
* to create an amqp sender.
*/
export declare function createSender(session: any, options?: SenderOptions): Promise<any>;
/**
* Creates an amqp sender on the provided amqp session.
* @param {Session} session The amqp session object on which the sender link needs to be established.
* @param {OnAmqpEvent} onError The event handler for the "error" event for the sender.
* @param {SenderOptions} [options] Options that can be provided while creating an amqp sender.
* @return {Promise<Sender>} Promise<Sender>
* - **Resolves** the promise with the Sender object when rhea emits the "sender_open" event.
* - **Rejects** the promise with an AmqpError when rhea emits the "sender_close" event while trying
* to create an amqp sender.
*/
export declare function createSenderWithHandlers(session: any, onError: OnAmqpEvent, options?: SenderOptions): Promise<any>;
/**
* Closes the amqp sender.
* @param {Sender} sender The amqp sender that needs to be closed.

6
typings/lib/rpc.d.ts поставляемый
Просмотреть файл

@ -16,16 +16,20 @@ export interface SenderLink {
}
export interface LinkOptions {
connection: any;
onError: OnAmqpEvent;
}
export interface ReceiverLinkOptions extends LinkOptions {
onMessage: OnAmqpEvent;
onError: OnAmqpEvent;
receiverOptions: ReceiverOptions;
}
export interface SenderLinkOptions extends LinkOptions {
senderOptions: SenderOptions;
}
export declare function createRequestResponseLink(connection: any, senderOptions: SenderOptions, receiverOptions: ReceiverOptions): Promise<RequestResponseLink>;
export declare function createReceiverLink(connection: any, receiverOptions: ReceiverOptions): Promise<ReceiverLink>;
export declare function createReceiverLinkWithHandlers(options: ReceiverLinkOptions): Promise<ReceiverLink>;
export declare function createSenderLink(connection: any, senderOptions: SenderOptions): Promise<SenderLink>;
export declare function createSenderLinkWithHandlers(options: SenderLinkOptions): Promise<SenderLink>;
export declare function sendRequest(connection: any, link: RequestResponseLink, request: AmqpMessage, timeoutInSeconds?: number): Promise<any>;
/**
* Opens the AMQP connection to the Event Hub for this client, returning a promise

12
typings/lib/streamingReceiver.d.ts поставляемый
Просмотреть файл

@ -1,11 +1,12 @@
import { ReceiveOptions, OnMessage, OnError } from ".";
import { EventHubReceiver } from "./eventHubReceiver";
import { EventHubReceiver, ReceiverRuntimeInfo } from "./eventHubReceiver";
import { ConnectionContext } from "./connectionContext";
export declare class ReceiveHandler {
/**
* @property {string} name The Receiver handler name.
* @readonly
*/
name: string;
readonly name: string;
/**
* @property {EventHubReceiver} _receiver The underlying EventHubReceiver.
* @private
@ -17,6 +18,13 @@ export declare class ReceiveHandler {
* @param {EventHubReceiver} receiver The underlying EventHubReceiver.
*/
constructor(receiver: EventHubReceiver);
/**
* @property {ReceiverRuntimeInfo} runtimeInfo The receiver runtime info. This property will only
* be enabled when `enableReceiverRuntimeMetric` option is set to true in the
* `client.receiveOnMessage()` method.
* @readonly
*/
readonly runtimeInfo: ReceiverRuntimeInfo | undefined;
/**
* Stops the underlying EventHubReceiver from receiving more messages.
* @return {Promise<void>} Promise<void>