[event-hubs] re-add support for custom endpoint address (#13287)

We had reverted the custom endpoint address changes in #13096 so that we could do a core-amqp release.

This PR reverts that revert and removes the 'beta' moniker from the event hubs version number.

Original PR: #12909
This commit is contained in:
chradek 2021-01-19 17:09:11 -08:00 коммит произвёл GitHub
Родитель e1f8788193
Коммит 7f9696888d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
19 изменённых файлов: 518 добавлений и 17 удалений

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

@ -1,7 +1,13 @@
# Release History
## 2.0.2 (Unreleased)
## 2.1.0 (Unreleased)
- Adds the ability to configure the `amqpHostname` and `port` that a `ConnectionContextBase` will use when connecting to a service.
The `host` field refers to the DNS host or IP address of the service, whereas the `amqpHostname`
is the fully qualified host name of the service. Normally `host` and `amqpHostname` will be the same.
However if your network does not allow connecting to the service via the public host,
you can specify a custom host (e.g. an application gateway) via the `host` field and continue
using the public host as the `amqpHostname`.
## 2.0.1 (2021-01-07)

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

@ -1,7 +1,7 @@
{
"name": "@azure/core-amqp",
"sdk-type": "client",
"version": "2.0.2",
"version": "2.1.0",
"description": "Common library for amqp based azure sdks like @azure/event-hubs.",
"author": "Microsoft Corporation",
"license": "MIT",

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

@ -159,10 +159,12 @@ export enum ConditionErrorNameMapper {
// @public
export interface ConnectionConfig {
amqpHostname?: string;
connectionString: string;
endpoint: string;
entityPath?: string;
host: string;
port?: number;
sharedAccessKey: string;
sharedAccessKeyName: string;
webSocket?: WebSocketImpl;

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

@ -122,9 +122,9 @@ export const ConnectionContextBase = {
const connectionOptions: ConnectionOptions = {
transport: Constants.TLS,
host: parameters.config.host,
hostname: parameters.config.host,
hostname: parameters.config.amqpHostname ?? parameters.config.host,
username: parameters.config.sharedAccessKeyName,
port: 5671,
port: parameters.config.port ?? 5671,
reconnect: false,
properties: {
product: parameters.connectionProperties.product,
@ -147,10 +147,11 @@ export const ConnectionContextBase = {
const host = parameters.config.host;
const endpoint = parameters.config.webSocketEndpointPath || "";
const socketOptions = parameters.config.webSocketConstructorOptions || {};
const port = parameters.config.port ?? 443;
connectionOptions.webSocketOptions = {
webSocket: socket,
url: `wss://${host}:443/${endpoint}`,
url: `wss://${host}:${port}/${endpoint}`,
protocol: ["AMQPWSB10"],
options: socketOptions
};

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

@ -26,9 +26,22 @@ export interface ConnectionConfig {
*/
endpoint: string;
/**
* @property {string} host - The host "<yournamespace>.servicebus.windows.net".
* The DNS hostname or IP address of the service.
* Typically of the form "<yournamespace>.servicebus.windows.net" unless connecting
* to the service through an intermediary.
*/
host: string;
/**
* The fully qualified name of the host to connect to.
* This field can be used by AMQP proxies to determine the correct back-end service to
* connect the client to.
* Typically of the form "<yournamespace>.servicebus.windows.net".
*/
amqpHostname?: string;
/**
* The port number.
*/
port?: number;
/**
* @property {string} connectionString - The connection string.
*/
@ -135,7 +148,7 @@ export const ConnectionConfig = {
throw new TypeError("Missing 'entityPath' in configuration");
}
if (config.entityPath != undefined) {
config.entityPath = String(config.entityPath);
config.entityPath = String(config.entityPath);
}
if (!isSharedAccessSignature(config.connectionString)) {

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

@ -35,6 +35,215 @@ describe("ConnectionContextBase", function() {
done();
});
it("should set host and hostname to the same value by default", function() {
const connectionString =
"Endpoint=sb://hostname.servicebus.windows.net/;SharedAccessKeyName=sakName;SharedAccessKey=sak;EntityPath=ep";
const path = "mypath";
const config = ConnectionConfig.create(connectionString, path);
const context = ConnectionContextBase.create({
config: config,
connectionProperties: {
product: "MSJSClient",
userAgent: "/js-amqp-client",
version: "1.0.0"
}
});
should.exist(context.config);
should.exist(context.connection);
should.exist(context.connectionId);
should.exist(context.connectionLock);
should.exist(context.negotiateClaimLock);
context.connection.options.hostname!.should.equal("hostname.servicebus.windows.net");
context.connection.options.host!.should.equal("hostname.servicebus.windows.net");
context.wasConnectionCloseCalled.should.equal(false);
context.connection.should.instanceOf(Connection);
context.connection.options.properties!.product.should.equal("MSJSClient");
context.connection.options.properties!["user-agent"].should.equal("/js-amqp-client");
context.connection.options.properties!.version.should.equal("1.0.0");
context.cbsSession.should.instanceOf(CbsClient);
});
it("should allow setting host and hostname to different values", function() {
const connectionString =
"Endpoint=sb://hostname.servicebus.windows.net/;SharedAccessKeyName=sakName;SharedAccessKey=sak;EntityPath=ep";
const path = "mypath";
const config = ConnectionConfig.create(connectionString, path);
config.amqpHostname = "127.0.0.1";
const context = ConnectionContextBase.create({
config: config,
connectionProperties: {
product: "MSJSClient",
userAgent: "/js-amqp-client",
version: "1.0.0"
}
});
should.exist(context.config);
should.exist(context.connection);
should.exist(context.connectionId);
should.exist(context.connectionLock);
should.exist(context.negotiateClaimLock);
context.connection.options.hostname!.should.equal("127.0.0.1");
context.connection.options.host!.should.equal("hostname.servicebus.windows.net");
context.wasConnectionCloseCalled.should.equal(false);
context.connection.should.instanceOf(Connection);
context.connection.options.properties!.product.should.equal("MSJSClient");
context.connection.options.properties!["user-agent"].should.equal("/js-amqp-client");
context.connection.options.properties!.version.should.equal("1.0.0");
context.cbsSession.should.instanceOf(CbsClient);
});
it("should allow specifying a port", function() {
const connectionString =
"Endpoint=sb://hostname.servicebus.windows.net/;SharedAccessKeyName=sakName;SharedAccessKey=sak;EntityPath=ep";
const path = "mypath";
const config = ConnectionConfig.create(connectionString, path);
config.port = 1111;
const context = ConnectionContextBase.create({
config: config,
connectionProperties: {
product: "MSJSClient",
userAgent: "/js-amqp-client",
version: "1.0.0"
}
});
should.exist(context.config);
should.exist(context.connection);
should.exist(context.connectionId);
should.exist(context.connectionLock);
should.exist(context.negotiateClaimLock);
context.connection.options.port!.should.equal(1111);
context.wasConnectionCloseCalled.should.equal(false);
context.connection.should.instanceOf(Connection);
context.connection.options.properties!.product.should.equal("MSJSClient");
context.connection.options.properties!["user-agent"].should.equal("/js-amqp-client");
context.connection.options.properties!.version.should.equal("1.0.0");
context.cbsSession.should.instanceOf(CbsClient);
});
it("should have a default port (5671)", function() {
const connectionString =
"Endpoint=sb://hostname.servicebus.windows.net/;SharedAccessKeyName=sakName;SharedAccessKey=sak;EntityPath=ep";
const path = "mypath";
const config = ConnectionConfig.create(connectionString, path);
const context = ConnectionContextBase.create({
config: config,
connectionProperties: {
product: "MSJSClient",
userAgent: "/js-amqp-client",
version: "1.0.0"
}
});
should.exist(context.config);
should.exist(context.connection);
should.exist(context.connectionId);
should.exist(context.connectionLock);
should.exist(context.negotiateClaimLock);
context.connection.options.port!.should.equal(5671);
context.wasConnectionCloseCalled.should.equal(false);
context.connection.should.instanceOf(Connection);
context.connection.options.properties!.product.should.equal("MSJSClient");
context.connection.options.properties!["user-agent"].should.equal("/js-amqp-client");
context.connection.options.properties!.version.should.equal("1.0.0");
context.cbsSession.should.instanceOf(CbsClient);
});
it("should allow setting host and hostname to different values when using websockets", function() {
const websockets: any = () => {};
const connectionString =
"Endpoint=sb://hostname.servicebus.windows.net/;SharedAccessKeyName=sakName;SharedAccessKey=sak;EntityPath=ep";
const path = "mypath";
const config = ConnectionConfig.create(connectionString, path);
config.webSocket = websockets;
config.amqpHostname = config.host;
config.host = "127.0.0.1";
const context = ConnectionContextBase.create({
config: config,
connectionProperties: {
product: "MSJSClient",
userAgent: "/js-amqp-client",
version: "1.0.0"
}
});
should.exist(context.config);
should.exist(context.connection);
should.exist(context.connectionId);
should.exist(context.connectionLock);
should.exist(context.negotiateClaimLock);
context.connection.options.host!.should.equal("127.0.0.1");
context.connection.options.hostname!.should.equal("hostname.servicebus.windows.net");
context.wasConnectionCloseCalled.should.equal(false);
context.connection.should.instanceOf(Connection);
context.connection.options.properties!.product.should.equal("MSJSClient");
context.connection.options.properties!["user-agent"].should.equal("/js-amqp-client");
context.connection.options.properties!.version.should.equal("1.0.0");
context.connection.options.webSocketOptions!.url.should.equal(`wss://127.0.0.1:443/`);
context.cbsSession.should.instanceOf(CbsClient);
});
it("should have a default port when using websockets (443)", function() {
const websockets: any = () => {};
const connectionString =
"Endpoint=sb://hostname.servicebus.windows.net/;SharedAccessKeyName=sakName;SharedAccessKey=sak;EntityPath=ep";
const path = "mypath";
const config = ConnectionConfig.create(connectionString, path);
config.webSocket = websockets;
const context = ConnectionContextBase.create({
config: config,
connectionProperties: {
product: "MSJSClient",
userAgent: "/js-amqp-client",
version: "1.0.0"
}
});
should.exist(context.config);
should.exist(context.connection);
should.exist(context.connectionId);
should.exist(context.connectionLock);
should.exist(context.negotiateClaimLock);
context.wasConnectionCloseCalled.should.equal(false);
context.connection.should.instanceOf(Connection);
context.connection.options.properties!.product.should.equal("MSJSClient");
context.connection.options.properties!["user-agent"].should.equal("/js-amqp-client");
context.connection.options.properties!.version.should.equal("1.0.0");
context.connection.options.webSocketOptions!.url.should.equal(
`wss://hostname.servicebus.windows.net:443/`
);
context.cbsSession.should.instanceOf(CbsClient);
});
it("should allow specifying a port when using websockets", function() {
const websockets: any = () => {};
const connectionString =
"Endpoint=sb://hostname.servicebus.windows.net/;SharedAccessKeyName=sakName;SharedAccessKey=sak;EntityPath=ep";
const path = "mypath";
const config = ConnectionConfig.create(connectionString, path);
config.webSocket = websockets;
config.port = 1111;
const context = ConnectionContextBase.create({
config: config,
connectionProperties: {
product: "MSJSClient",
userAgent: "/js-amqp-client",
version: "1.0.0"
}
});
should.exist(context.config);
should.exist(context.connection);
should.exist(context.connectionId);
should.exist(context.connectionLock);
should.exist(context.negotiateClaimLock);
context.connection.options.port!.should.equal(1111);
context.wasConnectionCloseCalled.should.equal(false);
context.connection.should.instanceOf(Connection);
context.connection.options.properties!.product.should.equal("MSJSClient");
context.connection.options.properties!["user-agent"].should.equal("/js-amqp-client");
context.connection.options.properties!.version.should.equal("1.0.0");
context.connection.options.webSocketOptions!.url.should.equal(
`wss://hostname.servicebus.windows.net:1111/`
);
context.cbsSession.should.instanceOf(CbsClient);
});
if (isNode) {
it("should accept a websocket constructor in Node", async () => {
const connectionString =

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

@ -1,6 +1,12 @@
# Release History
## 5.3.2 (Unreleased)
## 5.4.0 (Unreleased)
- Adds the `customEndpointAddress` field to `EventHubClientOptions`.
This allows for specifying a custom endpoint to use when communicating
with the Event Hubs service, which is useful when your network does not
allow communicating to the standard Event Hubs endpoint.
Resolves [#12901](https://github.com/Azure/azure-sdk-for-js/issues/12901).
- Updates documentation for `EventData` to call out that the `body` field
must be converted to a byte array or `Buffer` when cross-language

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

@ -1,7 +1,7 @@
{
"name": "@azure/event-hubs",
"sdk-type": "client",
"version": "5.3.2",
"version": "5.4.0",
"description": "Azure Event Hubs SDK for JS.",
"author": "Microsoft Corporation",
"license": "MIT",
@ -89,7 +89,7 @@
},
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-amqp": "^2.0.0",
"@azure/core-amqp": "^2.1.0",
"@azure/core-asynciterator-polyfill": "^1.0.0",
"@azure/core-tracing": "1.0.0-preview.9",
"@azure/core-auth": "^1.1.3",

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

@ -74,6 +74,7 @@ export interface EventDataBatch {
// @public
export interface EventHubClientOptions {
customEndpointAddress?: string;
retryOptions?: RetryOptions;
userAgent?: string;
webSocketOptions?: WebSocketOptions;

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

@ -19,7 +19,7 @@ const input = "dist-esm/src/index.js";
const production = process.env.NODE_ENV === "production";
export function nodeConfig(test = false) {
const externalNodeBuiltins = ["events", "util", "os"];
const externalNodeBuiltins = ["events", "util", "os", "url"];
const baseConfig = {
input: input,
external: depNames.concat(externalNodeBuiltins),

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

@ -501,6 +501,10 @@ export function createConnectionContext(
config = EventHubConnectionConfig.create(connectionString);
}
if (options?.customEndpointAddress) {
EventHubConnectionConfig.setCustomEndpointAddress(config, options.customEndpointAddress);
}
ConnectionConfig.validate(config);
return ConnectionContext.create(config, credential, options);

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

@ -3,11 +3,14 @@
/* eslint-disable eqeqeq */
import { ConnectionConfig } from "@azure/core-amqp";
import { parseEndpoint } from "./util/parseEndpoint";
/**
* Describes the connection config object that is created after parsing an EventHub connection
* string. It also provides some convenience methods for getting the address and audience for
* different entities.
* @internal
* @ignore
*/
export interface EventHubConnectionConfig extends ConnectionConfig {
/**
@ -65,7 +68,8 @@ export interface EventHubConnectionConfig extends ConnectionConfig {
* Describes the connection config object that is created after parsing an EventHub connection
* string. It also provides some convenience methods for getting the address and audience for
* different entities.
* @module EventHubConnectionConfig
* @internal
* @ignore
*/
export const EventHubConnectionConfig = {
/**
@ -141,6 +145,22 @@ export const EventHubConnectionConfig = {
return config as EventHubConnectionConfig;
},
/**
* Updates the provided EventHubConnectionConfig to use the custom endpoint address.
* @param config An existing connection configuration to be updated.
* @param customEndpointAddress The custom endpoint address to use.
*/
setCustomEndpointAddress(config: EventHubConnectionConfig, customEndpointAddress: string): void {
// The amqpHostname should match the host prior to using the custom endpoint.
config.amqpHostname = config.host;
const { hostname, port } = parseEndpoint(customEndpointAddress);
// Since we specify the port separately, set host to the customEndpointAddress hostname.
config.host = hostname;
if (port) {
config.port = parseInt(port, 10);
}
},
/**
* Validates the properties of connection config.
* @param {ConnectionConfig} config The connection config to be validated.

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

@ -111,18 +111,24 @@ export enum CloseReason {
*/
export interface EventHubClientOptions {
/**
* @property
* A custom endpoint to use when connecting to the Event Hubs service.
* This can be useful when your network does not allow connecting to the
* standard Azure Event Hubs endpoint address, but does allow connecting
* through an intermediary.
*
* Example: "https://my.custom.endpoint:100/"
*/
customEndpointAddress?: string;
/**
* Options to configure the retry policy for all the operations on the client.
* For example, `{ "maxRetries": 4 }` or `{ "maxRetries": 4, "retryDelayInMs": 30000 }`.
*/
retryOptions?: RetryOptions;
/**
* @property
* Options to configure the channelling of the AMQP connection over Web Sockets.
*/
webSocketOptions?: WebSocketOptions;
/**
* @property
* Value that is appended to the built in user agent string that is passed to the Event Hubs service.
*/
userAgent?: string;

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

@ -6,5 +6,5 @@
*/
export const packageJsonInfo = {
name: "@azure/event-hubs",
version: "5.3.2"
version: "5.4.0"
};

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

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
* Parses the host, hostname, and port from an endpoint.
* @param endpoint And endpoint to parse.
* @hidden
* @internal
*/
export function parseEndpoint(endpoint: string): { host: string; hostname: string; port?: string } {
const hostMatch = endpoint.match(/.*:\/\/([^/]*)/);
if (!hostMatch) {
throw new TypeError(`Invalid endpoint missing host: ${endpoint}`);
}
const [, host] = hostMatch;
const [hostname, port] = host.split(":");
return { host, hostname, port };
}

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

@ -89,6 +89,40 @@ describe("Create EventHubConsumerClient", function(): void {
should.equal(client.eventHubName, "my-event-hub-name");
should.equal(client.fullyQualifiedNamespace, "test.servicebus.windows.net");
});
it("respects customEndpointAddress when using connection string", () => {
const client = new EventHubConsumerClient(
"dummy",
"Endpoint=sb://test.servicebus.windows.net;SharedAccessKeyName=b;SharedAccessKey=c;EntityPath=my-event-hub-name",
{ customEndpointAddress: "sb://foo.private.bar:111" }
);
client.should.be.an.instanceof(EventHubConsumerClient);
client["_context"].config.host.should.equal("foo.private.bar");
client["_context"].config.amqpHostname!.should.equal("test.servicebus.windows.net");
client["_context"].config.port!.should.equal(111);
});
it("respects customEndpointAddress when using credentials", () => {
const dummyCredential: TokenCredential = {
getToken: async () => {
return {
token: "boo",
expiresOnTimestamp: 12324
};
}
};
const client = new EventHubConsumerClient(
"dummy",
"test.servicebus.windows.net",
"my-event-hub-name",
dummyCredential,
{ customEndpointAddress: "sb://foo.private.bar:111" }
);
client.should.be.an.instanceof(EventHubConsumerClient);
client["_context"].config.host.should.equal("foo.private.bar");
client["_context"].config.amqpHostname!.should.equal("test.servicebus.windows.net");
client["_context"].config.port!.should.equal(111);
});
});
describe("Create EventHubProducerClient", function(): void {
@ -155,6 +189,38 @@ describe("Create EventHubProducerClient", function(): void {
should.equal(client.eventHubName, "my-event-hub-name");
should.equal(client.fullyQualifiedNamespace, "test.servicebus.windows.net");
});
it("respects customEndpointAddress when using connection string", () => {
const client = new EventHubProducerClient(
"Endpoint=sb://test.servicebus.windows.net;SharedAccessKeyName=b;SharedAccessKey=c;EntityPath=my-event-hub-name",
{ customEndpointAddress: "sb://foo.private.bar:111" }
);
client.should.be.an.instanceof(EventHubProducerClient);
client["_context"].config.host.should.equal("foo.private.bar");
client["_context"].config.amqpHostname!.should.equal("test.servicebus.windows.net");
client["_context"].config.port!.should.equal(111);
});
it("respects customEndpointAddress when using credentials", () => {
const dummyCredential: TokenCredential = {
getToken: async () => {
return {
token: "boo",
expiresOnTimestamp: 12324
};
}
};
const client = new EventHubProducerClient(
"test.servicebus.windows.net",
"my-event-hub-name",
dummyCredential,
{ customEndpointAddress: "sb://foo.private.bar:111" }
);
client.should.be.an.instanceof(EventHubProducerClient);
client["_context"].config.host.should.equal("foo.private.bar");
client["_context"].config.amqpHostname!.should.equal("test.servicebus.windows.net");
client["_context"].config.port!.should.equal(111);
});
});
describe("EventHubConsumerClient with non existent namespace", function(): void {

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

@ -75,5 +75,112 @@ describe("ConnectionConfig", function() {
done();
});
describe("setCustomEndpointAddress", () => {
it("overwrites host", () => {
const config = EventHubConnectionConfig.create(
"Endpoint=sb://hostname.servicebus.windows.net/;SharedAccessKeyName=sakName;SharedAccessKey=sak;EntityPath=ep"
);
config.should.have.property("host").that.equals("hostname.servicebus.windows.net");
config.should.have.property("sharedAccessKeyName").that.equals("sakName");
config.should.have.property("sharedAccessKey").that.equals("sak");
config.should.have.property("entityPath").that.equals("ep");
config.getManagementAddress().should.equal("ep/$management");
config.getSenderAddress().should.equal("ep");
config.getSenderAddress("0").should.equal("ep/Partitions/0");
config.getSenderAddress(0).should.equal("ep/Partitions/0");
config.getReceiverAddress("0").should.equal("ep/ConsumerGroups/$default/Partitions/0");
config.getReceiverAddress(0).should.equal("ep/ConsumerGroups/$default/Partitions/0");
config.getReceiverAddress("0", "cg").should.equal("ep/ConsumerGroups/cg/Partitions/0");
config.getReceiverAddress(0, "cg").should.equal("ep/ConsumerGroups/cg/Partitions/0");
config
.getManagementAudience()
.should.equal("sb://hostname.servicebus.windows.net/ep/$management");
config.getSenderAudience().should.equal("sb://hostname.servicebus.windows.net/ep");
config
.getSenderAudience("0")
.should.equal("sb://hostname.servicebus.windows.net/ep/Partitions/0");
config
.getSenderAudience(0)
.should.equal("sb://hostname.servicebus.windows.net/ep/Partitions/0");
config
.getReceiverAudience("0")
.should.equal(
"sb://hostname.servicebus.windows.net/ep/ConsumerGroups/$default/Partitions/0"
);
config
.getReceiverAudience(0)
.should.equal(
"sb://hostname.servicebus.windows.net/ep/ConsumerGroups/$default/Partitions/0"
);
config
.getReceiverAudience("0", "cg")
.should.equal("sb://hostname.servicebus.windows.net/ep/ConsumerGroups/cg/Partitions/0");
config
.getReceiverAudience(0, "cg")
.should.equal("sb://hostname.servicebus.windows.net/ep/ConsumerGroups/cg/Partitions/0");
EventHubConnectionConfig.setCustomEndpointAddress(config, "https://foo.private.endpoint");
config.should.have.property("amqpHostname").that.equals("hostname.servicebus.windows.net");
config.should.have.property("host").that.equals("foo.private.endpoint");
config.should.not.have.property("port");
});
it("overwrites host and port", () => {
const config = EventHubConnectionConfig.create(
"Endpoint=sb://hostname.servicebus.windows.net/;SharedAccessKeyName=sakName;SharedAccessKey=sak;EntityPath=ep"
);
config.should.have.property("host").that.equals("hostname.servicebus.windows.net");
config.should.have.property("sharedAccessKeyName").that.equals("sakName");
config.should.have.property("sharedAccessKey").that.equals("sak");
config.should.have.property("entityPath").that.equals("ep");
config.getManagementAddress().should.equal("ep/$management");
config.getSenderAddress().should.equal("ep");
config.getSenderAddress("0").should.equal("ep/Partitions/0");
config.getSenderAddress(0).should.equal("ep/Partitions/0");
config.getReceiverAddress("0").should.equal("ep/ConsumerGroups/$default/Partitions/0");
config.getReceiverAddress(0).should.equal("ep/ConsumerGroups/$default/Partitions/0");
config.getReceiverAddress("0", "cg").should.equal("ep/ConsumerGroups/cg/Partitions/0");
config.getReceiverAddress(0, "cg").should.equal("ep/ConsumerGroups/cg/Partitions/0");
config
.getManagementAudience()
.should.equal("sb://hostname.servicebus.windows.net/ep/$management");
config.getSenderAudience().should.equal("sb://hostname.servicebus.windows.net/ep");
config
.getSenderAudience("0")
.should.equal("sb://hostname.servicebus.windows.net/ep/Partitions/0");
config
.getSenderAudience(0)
.should.equal("sb://hostname.servicebus.windows.net/ep/Partitions/0");
config
.getReceiverAudience("0")
.should.equal(
"sb://hostname.servicebus.windows.net/ep/ConsumerGroups/$default/Partitions/0"
);
config
.getReceiverAudience(0)
.should.equal(
"sb://hostname.servicebus.windows.net/ep/ConsumerGroups/$default/Partitions/0"
);
config
.getReceiverAudience("0", "cg")
.should.equal("sb://hostname.servicebus.windows.net/ep/ConsumerGroups/cg/Partitions/0");
config
.getReceiverAudience(0, "cg")
.should.equal("sb://hostname.servicebus.windows.net/ep/ConsumerGroups/cg/Partitions/0");
EventHubConnectionConfig.setCustomEndpointAddress(
config,
"https://foo.private.endpoint:1111"
);
config.should.have.property("amqpHostname").that.equals("hostname.servicebus.windows.net");
config.should.have.property("host").that.equals("foo.private.endpoint");
config.should.have.property("port").that.equals(1111);
});
});
});
});

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

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { parseEndpoint } from "../../src/util/parseEndpoint";
import chai from "chai";
const should = chai.should();
describe("parseEndpoint", () => {
it("throws an error for invalid inputs", () => {
should.throw(() => parseEndpoint(""), /Invalid endpoint/);
should.throw(() => parseEndpoint("missing-protocol"), /Invalid endpoint/);
should.throw(() => parseEndpoint("//missing-protocol"), /Invalid endpoint/);
});
it("extracts host, hostname, and port", () => {
parseEndpoint("sb://test.servicebus.windows.net:5671").should.eql({
host: "test.servicebus.windows.net:5671",
hostname: "test.servicebus.windows.net",
port: "5671"
} as ReturnType<typeof parseEndpoint>);
parseEndpoint("https://127.0.0.1:5671").should.eql({
host: "127.0.0.1:5671",
hostname: "127.0.0.1",
port: "5671"
} as ReturnType<typeof parseEndpoint>);
parseEndpoint("amqps://127.0.0.1:5671/path/?query=foo").should.eql({
host: "127.0.0.1:5671",
hostname: "127.0.0.1",
port: "5671"
} as ReturnType<typeof parseEndpoint>);
parseEndpoint("wss://127.0.0.1/path/?query=foo").should.eql({
host: "127.0.0.1",
hostname: "127.0.0.1",
port: undefined
} as ReturnType<typeof parseEndpoint>);
});
});

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

@ -95,7 +95,7 @@
},
"dependencies": {
"@azure/abort-controller": "^1.0.0",
"@azure/core-amqp": "^2.0.0",
"@azure/core-amqp": "^2.1.0",
"@azure/core-asynciterator-polyfill": "^1.0.0",
"@azure/core-http": "^1.2.0",
"@azure/core-tracing": "1.0.0-preview.9",