From 8b7a5444edc3b21c0a43eb72157adf960f7a3102 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Tue, 26 May 2020 13:45:07 -0700 Subject: [PATCH 01/61] Update Queue APIs aper the .NET proposal --- .../serializers/queueResourceSerializer.ts | 75 ++-- .../src/serviceBusAtomManagementClient.ts | 320 +++++++++++++----- 2 files changed, 279 insertions(+), 116 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts index 0b54c1d2a8ce..3cecd522fbda 100644 --- a/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts @@ -61,7 +61,7 @@ export function buildQueueOptions(queueOptions: QueueOptions): InternalQueueOpti * response from the service * @param rawQueue */ -export function buildQueue(rawQueue: any): QueueDetails { +export function buildQueue(rawQueue: any): QueueProperties { return { queueName: getString(rawQueue[Constants.QUEUE_NAME], "queueName"), @@ -69,10 +69,8 @@ export function buildQueue(rawQueue: any): QueueDetails { userMetadata: rawQueue[Constants.USER_METADATA], lockDuration: getString(rawQueue[Constants.LOCK_DURATION], "lockDuration"), - sizeInBytes: getIntegerOrUndefined(rawQueue[Constants.SIZE_IN_BYTES]), maxSizeInMegabytes: getInteger(rawQueue[Constants.MAX_SIZE_IN_MEGABYTES], "maxSizeInMegabytes"), - messageCount: getIntegerOrUndefined(rawQueue[Constants.MESSAGE_COUNT]), maxDeliveryCount: getInteger(rawQueue[Constants.MAX_DELIVERY_COUNT], "maxDeliveryCount"), enablePartitioning: getBoolean(rawQueue[Constants.ENABLE_PARTITIONING], "enablePartitioning"), @@ -104,7 +102,6 @@ export function buildQueue(rawQueue: any): QueueDetails { rawQueue[Constants.FORWARD_DEADLETTERED_MESSAGES_TO] ), - messageCountDetails: getCountDetailsOrUndefined(rawQueue[Constants.COUNT_DETAILS]), supportOrdering: getBooleanOrUndefined(rawQueue[Constants.SUPPORT_ORDERING]), enableExpress: getBooleanOrUndefined(rawQueue[Constants.ENABLE_EXPRESS]), @@ -113,7 +110,23 @@ export function buildQueue(rawQueue: any): QueueDetails { entityAvailabilityStatus: rawQueue[Constants.ENTITY_AVAILABILITY_STATUS], - status: rawQueue[Constants.STATUS], + status: rawQueue[Constants.STATUS] + }; +} + +/** + * @internal + * @ignore + * Builds the queue object from the raw json object gotten after deserializing the + * response from the service + * @param rawQueue + */ +export function buildQueueMetrics(rawQueue: any): QueueMetrics { + return { + queueName: getString(rawQueue[Constants.QUEUE_NAME], "queueName"), + sizeInBytes: getIntegerOrUndefined(rawQueue[Constants.SIZE_IN_BYTES]), + messageCount: getIntegerOrUndefined(rawQueue[Constants.MESSAGE_COUNT]), + messageCountDetails: getCountDetailsOrUndefined(rawQueue[Constants.COUNT_DETAILS]), createdOn: rawQueue[Constants.CREATED_AT], updatedOn: rawQueue[Constants.UPDATED_AT], accessedOn: rawQueue[Constants.ACCESSED_AT] @@ -126,6 +139,11 @@ export function buildQueue(rawQueue: any): QueueDetails { * Represents settable options on a queue */ export interface QueueOptions { + /** + * Name of the queue + */ + queueName: string; + /** * Determines the amount of time in seconds in which a message should be locked for * processing by a receiver. After this period, the message is unlocked and available @@ -364,7 +382,7 @@ export interface InternalQueueOptions { * @ignore * Represents all attributes of a queue entity */ -export interface QueueDetails { +export interface QueueProperties { /** * Name of the queue */ @@ -380,24 +398,12 @@ export interface QueueDetails { */ lockDuration: string; - /** - * The entity's size in bytes. - * - */ - sizeInBytes?: number; - /** * Specifies the maximum queue size in megabytes. Any attempt to enqueue * a message that will cause the queue to exceed this value will fail. */ maxSizeInMegabytes: number; - /** - * The entity's message count. - * - */ - messageCount?: number; - /** * Depending on whether DeadLettering is enabled, a message is automatically * moved to the DeadLetterQueue or deleted if it has been stored in the queue @@ -490,11 +496,6 @@ export interface QueueDetails { */ authorizationRules?: AuthorizationRule[]; - /** - * Message count details - */ - messageCountDetails?: MessageCountDetails; - /** * Ordering support for messages */ @@ -519,6 +520,17 @@ export interface QueueDetails { * Status of the messaging entity. */ status?: EntityStatus; +} +/** + * @internal + * @ignore + * Represents all attributes of a queue entity + */ +export interface QueueMetrics { + /** + * Name of the queue + */ + queueName: string; /** * Created at timestamp @@ -534,6 +546,23 @@ export interface QueueDetails { * Accessed at timestamp */ accessedOn?: string; + + /** + * The entity's message count. + * + */ + messageCount?: number; + + /** + * Message count details + */ + messageCountDetails?: MessageCountDetails; + + /** + * The entity's size in bytes. + * + */ + sizeInBytes?: number; } /** diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 4bd83ceea837..e3f433ad158f 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -29,8 +29,10 @@ import { InternalQueueOptions, QueueOptions, buildQueueOptions, - QueueDetails, - buildQueue + buildQueue, + QueueProperties, + buildQueueMetrics, + QueueMetrics } from "./serializers/queueResourceSerializer"; import { TopicResourceSerializer, @@ -59,8 +61,6 @@ import { import { isJSONLikeObject, isAbsoluteUrl } from "./util/utils"; /** - * @internal - * @ignore * Options to use with ServiceBusAtomManagementClient creation */ export interface ServiceBusAtomManagementClientOptions { @@ -71,8 +71,6 @@ export interface ServiceBusAtomManagementClientOptions { } /** - * @internal - * @ignore * Request options for list() operations */ export interface ListRequestOptions { @@ -88,11 +86,29 @@ export interface ListRequestOptions { } /** - * @internal - * @ignore * Represents result of create, get, update and delete operations on queue. */ -export interface QueueResponse extends QueueDetails { +export interface GetQueueMetricsResponse extends QueueMetrics { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + +/** + * Represents result of create, get, update and delete operations on queue. + */ +export interface GetQueuesMetricsResponse extends Array { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + +/** + * Represents result of create, get, update and delete operations on queue. + */ +export interface QueueResponse extends QueueProperties { /** * The underlying HTTP response. */ @@ -100,11 +116,9 @@ export interface QueueResponse extends QueueDetails { } /** - * @internal - * @ignore * Create Queue response */ -export interface CreateQueueResponse extends QueueDetails { +export interface CreateQueueResponse extends QueueProperties { /** * The underlying HTTP response. */ @@ -112,11 +126,9 @@ export interface CreateQueueResponse extends QueueDetails { } /** - * @internal - * @ignore * Get Queue response */ -export interface GetQueueResponse extends QueueDetails { +export interface GetQueueResponse extends QueueProperties { /** * The underlying HTTP response. */ @@ -124,11 +136,9 @@ export interface GetQueueResponse extends QueueDetails { } /** - * @internal - * @ignore * Update Queue response */ -export interface UpdateQueueResponse extends QueueDetails { +export interface UpdateQueueResponse extends QueueProperties { /** * The underlying HTTP response. */ @@ -136,8 +146,6 @@ export interface UpdateQueueResponse extends QueueDetails { } /** - * @internal - * @ignore * Delete Queue response */ export interface DeleteQueueResponse { @@ -148,11 +156,9 @@ export interface DeleteQueueResponse { } /** - * @internal - * @ignore * Represents result of list operation on queues. */ -export interface ListQueuesResponse extends Array { +export interface GetQueuesResponse extends Array { /** * The underlying HTTP response. */ @@ -160,8 +166,6 @@ export interface ListQueuesResponse extends Array { } /** - * @internal - * @ignore * Represents result of create, get, update and delete operations on topic. */ export interface TopicResponse extends TopicDetails { @@ -172,8 +176,6 @@ export interface TopicResponse extends TopicDetails { } /** - * @internal - * @ignore * Create Topic response */ export interface CreateTopicResponse extends TopicDetails { @@ -184,8 +186,6 @@ export interface CreateTopicResponse extends TopicDetails { } /** - * @internal - * @ignore * Get Topic response */ export interface GetTopicResponse extends TopicDetails { @@ -196,8 +196,6 @@ export interface GetTopicResponse extends TopicDetails { } /** - * @internal - * @ignore * Update Topic response */ export interface UpdateTopicResponse extends TopicDetails { @@ -208,8 +206,6 @@ export interface UpdateTopicResponse extends TopicDetails { } /** - * @internal - * @ignore * Delete Topic response */ export interface DeleteTopicResponse { @@ -220,8 +216,6 @@ export interface DeleteTopicResponse { } /** - * @internal - * @ignore * Represents result of list operation on topics. */ export interface ListTopicsResponse extends Array { @@ -232,8 +226,6 @@ export interface ListTopicsResponse extends Array { } /** - * @internal - * @ignore * Represents result of create, get, update and delete operations on subscription. */ export interface SubscriptionResponse extends SubscriptionDetails { @@ -244,8 +236,6 @@ export interface SubscriptionResponse extends SubscriptionDetails { } /** - * @internal - * @ignore * Create Subscription response */ export interface CreateSubscriptionResponse extends SubscriptionDetails { @@ -256,8 +246,6 @@ export interface CreateSubscriptionResponse extends SubscriptionDetails { } /** - * @internal - * @ignore * Get Subscription response */ export interface GetSubscriptionResponse extends SubscriptionDetails { @@ -268,8 +256,6 @@ export interface GetSubscriptionResponse extends SubscriptionDetails { } /** - * @internal - * @ignore * Update Subscription response */ export interface UpdateSubscriptionResponse extends SubscriptionDetails { @@ -280,8 +266,6 @@ export interface UpdateSubscriptionResponse extends SubscriptionDetails { } /** - * @internal - * @ignore * Delete Subscription response */ export interface DeleteSubscriptionResponse { @@ -292,8 +276,6 @@ export interface DeleteSubscriptionResponse { } /** - * @internal - * @ignore * Represents result of list operation on subscriptions. */ export interface ListSubscriptionsResponse extends Array { @@ -304,8 +286,6 @@ export interface ListSubscriptionsResponse extends Array { } /** - * @internal - * @ignore * Represents result of create, get, update and delete operations on rule. */ export interface RuleResponse extends RuleDetails { @@ -316,8 +296,6 @@ export interface RuleResponse extends RuleDetails { } /** - * @internal - * @ignore * Create Rule response */ export interface CreateRuleResponse extends RuleDetails { @@ -328,8 +306,6 @@ export interface CreateRuleResponse extends RuleDetails { } /** - * @internal - * @ignore * Get Rule response */ export interface GetRuleResponse extends RuleDetails { @@ -340,8 +316,6 @@ export interface GetRuleResponse extends RuleDetails { } /** - * @internal - * @ignore * Update Rule response */ export interface UpdateRuleResponse extends RuleDetails { @@ -352,8 +326,6 @@ export interface UpdateRuleResponse extends RuleDetails { } /** - * @internal - * @ignore * Delete Rule response */ export interface DeleteRuleResponse { @@ -364,8 +336,6 @@ export interface DeleteRuleResponse { } /** - * @internal - * @ignore * Represents result of list operation on rules. */ export interface ListRulesResponse extends Array { @@ -376,8 +346,6 @@ export interface ListRulesResponse extends Array { } /** - * @internal - * @ignore * All operations return promises that resolve to an object that has the relevant output. * These objects also have a property called `_response` that you can use if you want to * access the direct response from the service. @@ -450,6 +418,21 @@ export class ServiceBusAtomManagementClient extends ServiceClient { /** * Creates a queue with given name, configured using the given options * @param queueName + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityAlreadyExistsError` when requested messaging entity already exists, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `QuotaExceededError` when requested operation fails due to quote limits exceeding from service side, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async createQueue(queueName: string): Promise; + /** + * Creates a queue configured using the given options * @param queueOptions Options to configure the Queue being created. * For example, you can configure a queue to support partitions or sessions. * @@ -464,15 +447,54 @@ export class ServiceBusAtomManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async createQueue(queueName: string, queueOptions?: QueueOptions): Promise { - log.httpAtomXml( - `Performing management operation - createQueue() for "${queueName}" with options: ${queueOptions}` - ); - const response: HttpOperationResponse = await this.putResource( + async createQueue(queueOptions: QueueOptions): Promise; + async createQueue(queueNameOrOptions: string | QueueOptions): Promise { + if (typeof queueNameOrOptions == "string") { + log.httpAtomXml( + `Performing management operation - createQueue() for "${queueNameOrOptions}"` + ); + const response: HttpOperationResponse = await this.putResource( + queueNameOrOptions, + buildQueueOptions({ queueName: queueNameOrOptions }), + this.queueResourceSerializer, + false + ); + + return this.buildQueueResponse(response); + } else { + log.httpAtomXml( + `Performing management operation - createQueue() for "${queueNameOrOptions.queueName}" with options: ${queueNameOrOptions}` + ); + const response: HttpOperationResponse = await this.putResource( + queueNameOrOptions.queueName, + buildQueueOptions(queueNameOrOptions || {}), + this.queueResourceSerializer, + false + ); + + return this.buildQueueResponse(response); + } + } + + /** + * Returns an object representing the Queue with the given name along with all its properties + * @param queueName + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityNotFoundError` when requested messaging entity does not exist, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async getQueue(queueName: string): Promise { + log.httpAtomXml(`Performing management operation - getQueue() for "${queueName}"`); + const response: HttpOperationResponse = await this.getResource( queueName, - buildQueueOptions(queueOptions || {}), - this.queueResourceSerializer, - false + this.queueResourceSerializer ); return this.buildQueueResponse(response); @@ -492,14 +514,14 @@ export class ServiceBusAtomManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async getQueueDetails(queueName: string): Promise { + async getQueueMetrics(queueName: string): Promise { log.httpAtomXml(`Performing management operation - getQueue() for "${queueName}"`); const response: HttpOperationResponse = await this.getResource( queueName, this.queueResourceSerializer ); - return this.buildQueueResponse(response); + return this.buildQueueMetricsResponse(response); } /** @@ -515,7 +537,7 @@ export class ServiceBusAtomManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async listQueues(listRequestOptions?: ListRequestOptions): Promise { + async getQueues(listRequestOptions?: ListRequestOptions): Promise { log.httpAtomXml( `Performing management operation - listQueues() with options: ${listRequestOptions}` ); @@ -528,9 +550,51 @@ export class ServiceBusAtomManagementClient extends ServiceClient { return this.buildListQueuesResponse(response); } + /** + * Lists existing queues. + * @param listRequestOptions + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async getQueuesMetrics( + listRequestOptions?: ListRequestOptions + ): Promise { + log.httpAtomXml( + `Performing management operation - listQueues() with options: ${listRequestOptions}` + ); + const response: HttpOperationResponse = await this.listResources( + "$Resources/Queues", + listRequestOptions, + this.queueResourceSerializer + ); + + return this.buildListQueuesMetricsResponse(response); + } + /** * Updates properties on the Queue by the given name based on the given options * @param queueName + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityNotFoundError` when requested messaging entity does not exist, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async updateQueue(queueName: string): Promise; + /** + * Updates properties on the Queue by the given name based on the given options * @param queueOptions Options to configure the Queue being updated. * For example, you can configure a queue to support partitions or sessions. * @@ -544,29 +608,49 @@ export class ServiceBusAtomManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async updateQueue(queueName: string, queueOptions: QueueOptions): Promise { - log.httpAtomXml( - `Performing management operation - updateQueue() for "${queueName}" with options: ${queueOptions}` - ); + async updateQueue(queueOptions: QueueOptions): Promise; + async updateQueue(queueNameOrOptions: string | QueueOptions): Promise { + if (typeof queueNameOrOptions == "string") { + log.httpAtomXml( + `Performing management operation - updateQueue() for "${queueNameOrOptions}"` + ); - if (!isJSONLikeObject(queueOptions) || queueOptions === null) { - throw new TypeError( - `Parameter "queueOptions" must be an object of type "QueueOptions" and cannot be undefined or null.` + const finalQueueOptions: QueueOptions = { queueName: queueNameOrOptions }; + const getQueueResult = await this.getQueue(queueNameOrOptions); + Object.assign(finalQueueOptions, getQueueResult); + + const response: HttpOperationResponse = await this.putResource( + queueNameOrOptions, + buildQueueOptions(finalQueueOptions), + this.queueResourceSerializer, + true ); - } - const finalQueueOptions: QueueOptions = {}; - const getQueueResult = await this.getQueueDetails(queueName); - Object.assign(finalQueueOptions, getQueueResult, queueOptions); + return this.buildQueueResponse(response); + } else { + log.httpAtomXml( + `Performing management operation - updateQueue() for "${queueNameOrOptions.queueName}" with options: ${queueNameOrOptions}` + ); - const response: HttpOperationResponse = await this.putResource( - queueName, - buildQueueOptions(finalQueueOptions), - this.queueResourceSerializer, - true - ); + if (!isJSONLikeObject(queueNameOrOptions) || queueNameOrOptions === null) { + throw new TypeError( + `Parameter "queueOptions" must be an object of type "QueueOptions" and cannot be undefined or null.` + ); + } - return this.buildQueueResponse(response); + const finalQueueOptions: QueueOptions = { queueName: queueNameOrOptions.queueName }; + const getQueueResult = await this.getQueue(queueNameOrOptions.queueName); + Object.assign(finalQueueOptions, getQueueResult, queueNameOrOptions); + + const response: HttpOperationResponse = await this.putResource( + queueNameOrOptions.queueName, + buildQueueOptions(finalQueueOptions), + this.queueResourceSerializer, + true + ); + + return this.buildQueueResponse(response); + } } /** @@ -1237,9 +1321,9 @@ export class ServiceBusAtomManagementClient extends ServiceClient { return topicName + "/Subscriptions/" + subscriptionName + "/Rules/" + ruleName; } - private buildListQueuesResponse(response: HttpOperationResponse): ListQueuesResponse { + private buildListQueuesResponse(response: HttpOperationResponse): GetQueuesResponse { try { - const queues: QueueDetails[] = []; + const queues: QueueProperties[] = []; if (!Array.isArray(response.parsedBody)) { throw new TypeError(`${response.parsedBody} was expected to be of type Array`); } @@ -1250,7 +1334,38 @@ export class ServiceBusAtomManagementClient extends ServiceClient { queues.push(queue); } } - const listQueuesResponse: ListQueuesResponse = Object.assign(queues, { + const listQueuesResponse: GetQueuesResponse = Object.assign(queues, { + _response: response + }); + return listQueuesResponse; + } catch (err) { + log.warning("Failure parsing response from service - %0 ", err); + throw new RestError( + `Error occurred while parsing the response body - cannot form a list of queues using the response from the service.`, + RestError.PARSE_ERROR, + response.status, + stripRequest(response.request), + stripResponse(response) + ); + } + } + + private buildListQueuesMetricsResponse( + response: HttpOperationResponse + ): GetQueuesMetricsResponse { + try { + const queues: QueueMetrics[] = []; + if (!Array.isArray(response.parsedBody)) { + throw new TypeError(`${response.parsedBody} was expected to be of type Array`); + } + const rawQueueArray: any = response.parsedBody; + for (let i = 0; i < rawQueueArray.length; i++) { + const queue = buildQueueMetrics(rawQueueArray[i]); + if (queue) { + queues.push(queue); + } + } + const listQueuesResponse: GetQueuesMetricsResponse = Object.assign(queues, { _response: response }); return listQueuesResponse; @@ -1285,6 +1400,25 @@ export class ServiceBusAtomManagementClient extends ServiceClient { } } + private buildQueueMetricsResponse(response: HttpOperationResponse): GetQueueMetricsResponse { + try { + const queue = buildQueueMetrics(response.parsedBody); + const queueResponse: GetQueueMetricsResponse = Object.assign(queue || {}, { + _response: response + }); + return queueResponse; + } catch (err) { + log.warning("Failure parsing response from service - %0 ", err); + throw new RestError( + `Error occurred while parsing the response body - cannot form a queue object using the response from the service.`, + RestError.PARSE_ERROR, + response.status, + stripRequest(response.request), + stripResponse(response) + ); + } + } + private buildListTopicsResponse(response: HttpOperationResponse): ListTopicsResponse { try { const topics: TopicDetails[] = []; From ff97456324823d4e8ecf654f6f47b7b565c87b4f Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Tue, 26 May 2020 14:10:43 -0700 Subject: [PATCH 02/61] remove @internal @ignore tags wherever required and generate API report --- .../service-bus/review/service-bus.api.md | 133 ++++++++++++++++++ .../service-bus/src/core/managementClient.ts | 5 - sdk/servicebus/service-bus/src/index.ts | 6 + .../serializers/queueResourceSerializer.ts | 6 - .../src/serializers/ruleResourceSerializer.ts | 12 -- .../subscriptionResourceSerializer.ts | 4 - .../serializers/topicResourceSerializer.ts | 4 - .../src/serviceBusAtomManagementClient.ts | 2 +- sdk/servicebus/service-bus/src/util/utils.ts | 6 - 9 files changed, 140 insertions(+), 38 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 57222db7e05e..81921efc7a0f 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -8,15 +8,30 @@ import { AbortSignalLike } from '@azure/abort-controller'; import { AmqpMessage } from '@azure/core-amqp'; import { delay } from '@azure/core-amqp'; import { Delivery } from 'rhea-promise'; +import { HttpOperationResponse } from '@azure/core-http'; import Long from 'long'; import { MessagingError } from '@azure/core-amqp'; import { OperationTracingOptions } from '@azure/core-tracing'; +import { ProxySettings } from '@azure/core-http'; import { RetryOptions } from '@azure/core-amqp'; +import { ServiceClient } from '@azure/core-http'; import { TokenCredential } from '@azure/core-amqp'; import { TokenType } from '@azure/core-amqp'; import { WebSocketImpl } from 'rhea-promise'; import { WebSocketOptions } from '@azure/core-amqp'; +// @public +export type AuthorizationRule = { + claimType: string; + claimValue: string; + rights: { + accessRights?: string[]; + }; + keyName: string; + primaryKey?: string; + secondaryKey?: string; +}; + // @public export interface BrowseMessagesOptions extends OperationOptions { fromSequenceNumber?: Long; @@ -47,10 +62,22 @@ export { delay } export { Delivery } +// @public +export type EntityStatus = "Active" | "Creating" | "Deleting" | "ReceiveDisabled" | "SendDisabled" | "Disabled" | "Renaming" | "Restoring" | "Unknown"; + // @public export interface GetMessageIteratorOptions extends OperationOptions, WaitTimeOptions { } +// @public +export type MessageCountDetails = { + activeMessageCount: number; + deadLetterMessageCount: number; + scheduledMessageCount: number; + transferMessageCount: number; + transferDeadLetterMessageCount: number; +}; + // @public export interface MessageHandlerOptions { autoComplete?: boolean; @@ -72,6 +99,27 @@ export interface OperationOptions { tracingOptions?: OperationTracingOptions; } +// @public +export interface QueueOptions { + authorizationRules?: AuthorizationRule[]; + autoDeleteOnIdle?: string; + deadLetteringOnMessageExpiration?: boolean; + defaultMessageTtl?: string; + duplicateDetectionHistoryTimeWindow?: string; + enableBatchedOperations?: boolean; + enablePartitioning?: boolean; + forwardDeadLetteredMessagesTo?: string; + forwardTo?: string; + lockDuration?: string; + maxDeliveryCount?: number; + maxSizeInMegabytes?: number; + queueName: string; + requiresDuplicateDetection?: boolean; + requiresSession?: boolean; + status?: EntityStatus; + userMetadata?: string; +} + // @public export interface ReceiveBatchOptions extends OperationOptions, WaitTimeOptions { } @@ -163,6 +211,60 @@ export interface ServiceBusClientOptions { webSocketOptions?: WebSocketOptions; } +// @public +export class ServiceBusManagementClient extends ServiceClient { + // Warning: (ae-forgotten-export) The symbol "ServiceBusAtomManagementClientOptions" needs to be exported by the entry point index.d.ts + constructor(connectionString: string, options?: ServiceBusAtomManagementClientOptions); + // Warning: (ae-forgotten-export) The symbol "CreateQueueResponse" needs to be exported by the entry point index.d.ts + createQueue(queueName: string): Promise; + createQueue(queueOptions: QueueOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "RuleOptions" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "CreateRuleResponse" needs to be exported by the entry point index.d.ts + createRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions?: RuleOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "CreateSubscriptionResponse" needs to be exported by the entry point index.d.ts + createSubscription(topicName: string, subscriptionName: string, subscriptionOptions?: SubscriptionOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "CreateTopicResponse" needs to be exported by the entry point index.d.ts + createTopic(topicName: string, topicOptions?: TopicOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "DeleteQueueResponse" needs to be exported by the entry point index.d.ts + deleteQueue(queueName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "DeleteRuleResponse" needs to be exported by the entry point index.d.ts + deleteRule(topicName: string, subscriptionName: string, ruleName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "DeleteSubscriptionResponse" needs to be exported by the entry point index.d.ts + deleteSubscription(topicName: string, subscriptionName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "DeleteTopicResponse" needs to be exported by the entry point index.d.ts + deleteTopic(topicName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetQueueResponse" needs to be exported by the entry point index.d.ts + getQueue(queueName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetQueueMetricsResponse" needs to be exported by the entry point index.d.ts + getQueueMetrics(queueName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "ListRequestOptions" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "GetQueuesResponse" needs to be exported by the entry point index.d.ts + getQueues(listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "GetQueuesMetricsResponse" needs to be exported by the entry point index.d.ts + getQueuesMetrics(listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "GetRuleResponse" needs to be exported by the entry point index.d.ts + getRuleDetails(topicName: string, subscriptioName: string, ruleName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetSubscriptionResponse" needs to be exported by the entry point index.d.ts + getSubscriptionDetails(topicName: string, subscriptionName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetTopicResponse" needs to be exported by the entry point index.d.ts + getTopicDetails(topicName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "ListRulesResponse" needs to be exported by the entry point index.d.ts + listRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "ListSubscriptionsResponse" needs to be exported by the entry point index.d.ts + listSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "ListTopicsResponse" needs to be exported by the entry point index.d.ts + listTopics(listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "UpdateQueueResponse" needs to be exported by the entry point index.d.ts + updateQueue(queueName: string): Promise; + updateQueue(queueOptions: QueueOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "UpdateRuleResponse" needs to be exported by the entry point index.d.ts + updateRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions: RuleOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "UpdateSubscriptionResponse" needs to be exported by the entry point index.d.ts + updateSubscription(topicName: string, subscriptionName: string, subscriptionOptions: SubscriptionOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "UpdateTopicResponse" needs to be exported by the entry point index.d.ts + updateTopic(topicName: string, topicOptions: TopicOptions): Promise; +} + // @public export interface ServiceBusMessage { body: any; @@ -216,10 +318,41 @@ export interface SessionReceiverOptions { export interface SubscribeOptions extends OperationOptions, MessageHandlerOptions { } +// @public +export interface SubscriptionOptions { + autoDeleteOnIdle?: string; + deadLetteringOnFilterEvaluationExceptions?: boolean; + deadLetteringOnMessageExpiration?: boolean; + defaultMessageTtl?: string; + enableBatchedOperations?: boolean; + forwardDeadLetteredMessagesTo?: string; + forwardTo?: string; + lockDuration?: string; + maxDeliveryCount?: number; + requiresSession?: boolean; + status?: EntityStatus; + userMetadata?: string; +} + export { TokenCredential } export { TokenType } +// @public +export interface TopicOptions { + authorizationRules?: AuthorizationRule[]; + autoDeleteOnIdle?: string; + defaultMessageTtl?: string; + duplicateDetectionHistoryTimeWindow?: string; + enableBatchedOperations?: boolean; + enablePartitioning?: boolean; + maxSizeInMegabytes?: number; + requiresDuplicateDetection?: boolean; + status?: EntityStatus; + supportOrdering?: boolean; + userMetadata?: string; +} + // @public export interface WaitTimeOptions { maxWaitTimeInMs: number; diff --git a/sdk/servicebus/service-bus/src/core/managementClient.ts b/sdk/servicebus/service-bus/src/core/managementClient.ts index acb172251d98..8d53950264a3 100644 --- a/sdk/servicebus/service-bus/src/core/managementClient.ts +++ b/sdk/servicebus/service-bus/src/core/managementClient.ts @@ -50,8 +50,6 @@ import { OperationOptions } from "../modelsToBeSharedWithEventHubs"; import { AbortError } from "@azure/abort-controller"; /** - * @internal - * @ignore * Represents a Rule on a Subscription that is used to filter the incoming message from the * Subscription. */ @@ -75,9 +73,6 @@ export interface RuleDescription { } /** - * @internal - * @ignore - * * Represents the correlation filter expression. * A CorrelationFilter holds a set of conditions that are matched against user and system properties * of incoming messages from a Subscription. diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index e533d8f75afb..830b0f052f7f 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -44,3 +44,9 @@ export { Receiver } from "./receivers/receiver"; export { SessionReceiver } from "./receivers/sessionReceiver"; export { Sender } from "./sender"; export { ServiceBusClient } from "./serviceBusClient"; + +export { QueueOptions } from "./serializers/queueResourceSerializer"; +export { TopicOptions } from "./serializers/topicResourceSerializer"; +export { SubscriptionOptions } from "./serializers/subscriptionResourceSerializer"; +export { ServiceBusManagementClient } from "./serviceBusAtomManagementClient"; +export { MessageCountDetails, AuthorizationRule, EntityStatus } from "./util/utils"; diff --git a/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts index 3cecd522fbda..e5ee89d5628a 100644 --- a/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts @@ -134,8 +134,6 @@ export function buildQueueMetrics(rawQueue: any): QueueMetrics { } /** - * @internal - * @ignore * Represents settable options on a queue */ export interface QueueOptions { @@ -378,8 +376,6 @@ export interface InternalQueueOptions { } /** - * @internal - * @ignore * Represents all attributes of a queue entity */ export interface QueueProperties { @@ -522,8 +518,6 @@ export interface QueueProperties { status?: EntityStatus; } /** - * @internal - * @ignore * Represents all attributes of a queue entity */ export interface QueueMetrics { diff --git a/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts index 74e107ce00c3..e0dc00176ce9 100644 --- a/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts @@ -103,14 +103,10 @@ function getRuleActionOrUndefined(value: any): SqlAction | undefined { } /** - * @internal - * @ignore * Represents settable options on a rule */ export interface RuleOptions { /** - * @internal - * @ignore * Defines the filter expression that the rule evaluates. For `SqlFilter` input, * the expression string is interpreted as a SQL92 expression which must * evaluate to True or False. Only one between a `CorrelationFilter` or @@ -119,8 +115,6 @@ export interface RuleOptions { filter?: SqlFilter | CorrelationFilter; /** - * @internal - * @ignore * The SQL like expression that can be executed on the message should the * associated filter apply. */ @@ -142,8 +136,6 @@ export interface InternalRuleOptions extends RuleOptions { } /** - * @internal - * @ignore * Represents all attributes of a rule entity */ export interface RuleDetails { @@ -195,15 +187,11 @@ export interface RuleDetails { } /** - * @internal - * @ignore * Represents all possible fields on SqlAction */ export type SqlAction = SqlFilter; /** - * @internal - * @ignore * Represents all possible fields on SqlFilter */ export interface SqlFilter { diff --git a/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts index b1fc058b4aba..9dc660ee9a34 100644 --- a/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts @@ -115,8 +115,6 @@ export function buildSubscription(rawSubscription: any): SubscriptionDetails { } /** - * @internal - * @ignore * Represents settable options on a subscription */ export interface SubscriptionOptions { @@ -309,8 +307,6 @@ export interface InternalSubscriptionOptions { } /** - * @internal - * @ignore * Represents all attributes of a subscription entity */ export interface SubscriptionDetails { diff --git a/sdk/servicebus/service-bus/src/serializers/topicResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/topicResourceSerializer.ts index 3be0839cb173..abbcba2d31d2 100644 --- a/sdk/servicebus/service-bus/src/serializers/topicResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/topicResourceSerializer.ts @@ -109,8 +109,6 @@ export function buildTopic(rawTopic: any): TopicDetails { } /** - * @internal - * @ignore * Represents settable options on a topic */ export interface TopicOptions { @@ -272,8 +270,6 @@ export interface InternalTopicOptions { } /** - * @internal - * @ignore * Represents all attributes of a topic entity */ export interface TopicDetails { diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index e3f433ad158f..8b24ba4e8f8b 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -350,7 +350,7 @@ export interface ListRulesResponse extends Array { * These objects also have a property called `_response` that you can use if you want to * access the direct response from the service. */ -export class ServiceBusAtomManagementClient extends ServiceClient { +export class ServiceBusManagementClient extends ServiceClient { /** * Reference to the endpoint as extracted from input connection string. */ diff --git a/sdk/servicebus/service-bus/src/util/utils.ts b/sdk/servicebus/service-bus/src/util/utils.ts index 26be40bac87f..15cb8c1de73b 100644 --- a/sdk/servicebus/service-bus/src/util/utils.ts +++ b/sdk/servicebus/service-bus/src/util/utils.ts @@ -308,8 +308,6 @@ export function getCountDetailsOrUndefined(value: any): MessageCountDetails | un } /** - * @internal - * @ignore * Represents type of message count details in ATOM based management operations. */ export type MessageCountDetails = { @@ -321,8 +319,6 @@ export type MessageCountDetails = { }; /** - * @internal - * @ignore * Represents type of `AuthorizationRule` in ATOM based management operations. */ export type AuthorizationRule = { @@ -471,8 +467,6 @@ export function isAbsoluteUrl(url: string) { } /** - * @internal - * @ignore * Possible values for `status` of the Service Bus messaging entities. */ export type EntityStatus = From ac287ab38dc71fef1c52745dbbb49644d7ef25a3 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Tue, 26 May 2020 14:19:42 -0700 Subject: [PATCH 03/61] more exports --- .../service-bus/review/service-bus.api.md | 167 +++++++++++++++--- sdk/servicebus/service-bus/src/index.ts | 29 ++- .../src/serviceBusAtomManagementClient.ts | 6 +- 3 files changed, 172 insertions(+), 30 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 81921efc7a0f..cb12301b93f7 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -43,6 +43,20 @@ export interface CreateBatchOptions extends OperationOptions { maxSizeInBytes?: number; } +// Warning: (ae-forgotten-export) The symbol "QueueProperties" needs to be exported by the entry point index.d.ts +// +// @public +export interface CreateQueueResponse extends QueueProperties { + _response: HttpOperationResponse; +} + +// Warning: (ae-forgotten-export) The symbol "RuleDetails" needs to be exported by the entry point index.d.ts +// +// @public +export interface CreateRuleResponse extends RuleDetails { + _response: HttpOperationResponse; +} + // @public export interface CreateSenderOptions { abortSignal?: AbortSignalLike; @@ -52,6 +66,20 @@ export interface CreateSenderOptions { export interface CreateSessionReceiverOptions extends SessionReceiverOptions, OperationOptions { } +// Warning: (ae-forgotten-export) The symbol "SubscriptionDetails" needs to be exported by the entry point index.d.ts +// +// @public +export interface CreateSubscriptionResponse extends SubscriptionDetails { + _response: HttpOperationResponse; +} + +// Warning: (ae-forgotten-export) The symbol "TopicDetails" needs to be exported by the entry point index.d.ts +// +// @public +export interface CreateTopicResponse extends TopicDetails { + _response: HttpOperationResponse; +} + // @public export interface DeadLetterOptions { deadLetterErrorDescription: string; @@ -60,6 +88,26 @@ export interface DeadLetterOptions { export { delay } +// @public +export interface DeleteQueueResponse { + _response: HttpOperationResponse; +} + +// @public +export interface DeleteRuleResponse { + _response: HttpOperationResponse; +} + +// @public +export interface DeleteSubscriptionResponse { + _response: HttpOperationResponse; +} + +// @public +export interface DeleteTopicResponse { + _response: HttpOperationResponse; +} + export { Delivery } // @public @@ -69,6 +117,64 @@ export type EntityStatus = "Active" | "Creating" | "Deleting" | "ReceiveDisabled export interface GetMessageIteratorOptions extends OperationOptions, WaitTimeOptions { } +// Warning: (ae-forgotten-export) The symbol "QueueMetrics" needs to be exported by the entry point index.d.ts +// +// @public +export interface GetQueueMetricsResponse extends QueueMetrics { + _response: HttpOperationResponse; +} + +// @public +export interface GetQueueResponse extends QueueProperties { + _response: HttpOperationResponse; +} + +// @public +export interface GetQueuesMetricsResponse extends Array { + _response: HttpOperationResponse; +} + +// @public +export interface GetQueuesResponse extends Array { + _response: HttpOperationResponse; +} + +// @public +export interface GetRuleResponse extends RuleDetails { + _response: HttpOperationResponse; +} + +// @public +export interface GetSubscriptionResponse extends SubscriptionDetails { + _response: HttpOperationResponse; +} + +// @public +export interface GetTopicResponse extends TopicDetails { + _response: HttpOperationResponse; +} + +// @public +export interface ListRequestOptions { + skip?: number; + top?: number; +} + +// @public +export interface ListRulesResponse extends Array { + _response: HttpOperationResponse; +} + +// @public +export interface ListSubscriptionsResponse extends Array { + _response: HttpOperationResponse; +} + +// @public +export interface ListTopicsResponse extends Array { + _response: HttpOperationResponse; +} + // @public export type MessageCountDetails = { activeMessageCount: number; @@ -169,6 +275,15 @@ export interface Receiver { export { RetryOptions } +// @public +export interface RuleOptions { + // Warning: (ae-forgotten-export) The symbol "SqlAction" needs to be exported by the entry point index.d.ts + action?: SqlAction; + // Warning: (ae-forgotten-export) The symbol "SqlFilter" needs to be exported by the entry point index.d.ts + // Warning: (ae-forgotten-export) The symbol "CorrelationFilter" needs to be exported by the entry point index.d.ts + filter?: SqlFilter | CorrelationFilter; +} + // @public export interface Sender { cancelScheduledMessage(sequenceNumber: Long, options?: OperationOptions): Promise; @@ -213,58 +328,38 @@ export interface ServiceBusClientOptions { // @public export class ServiceBusManagementClient extends ServiceClient { - // Warning: (ae-forgotten-export) The symbol "ServiceBusAtomManagementClientOptions" needs to be exported by the entry point index.d.ts - constructor(connectionString: string, options?: ServiceBusAtomManagementClientOptions); - // Warning: (ae-forgotten-export) The symbol "CreateQueueResponse" needs to be exported by the entry point index.d.ts + constructor(connectionString: string, options?: ServiceBusManagementClientOptions); createQueue(queueName: string): Promise; createQueue(queueOptions: QueueOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "RuleOptions" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "CreateRuleResponse" needs to be exported by the entry point index.d.ts createRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions?: RuleOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "CreateSubscriptionResponse" needs to be exported by the entry point index.d.ts createSubscription(topicName: string, subscriptionName: string, subscriptionOptions?: SubscriptionOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "CreateTopicResponse" needs to be exported by the entry point index.d.ts createTopic(topicName: string, topicOptions?: TopicOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "DeleteQueueResponse" needs to be exported by the entry point index.d.ts deleteQueue(queueName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "DeleteRuleResponse" needs to be exported by the entry point index.d.ts deleteRule(topicName: string, subscriptionName: string, ruleName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "DeleteSubscriptionResponse" needs to be exported by the entry point index.d.ts deleteSubscription(topicName: string, subscriptionName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "DeleteTopicResponse" needs to be exported by the entry point index.d.ts deleteTopic(topicName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetQueueResponse" needs to be exported by the entry point index.d.ts getQueue(queueName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetQueueMetricsResponse" needs to be exported by the entry point index.d.ts getQueueMetrics(queueName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "ListRequestOptions" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "GetQueuesResponse" needs to be exported by the entry point index.d.ts getQueues(listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "GetQueuesMetricsResponse" needs to be exported by the entry point index.d.ts getQueuesMetrics(listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "GetRuleResponse" needs to be exported by the entry point index.d.ts getRuleDetails(topicName: string, subscriptioName: string, ruleName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetSubscriptionResponse" needs to be exported by the entry point index.d.ts getSubscriptionDetails(topicName: string, subscriptionName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetTopicResponse" needs to be exported by the entry point index.d.ts getTopicDetails(topicName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "ListRulesResponse" needs to be exported by the entry point index.d.ts listRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "ListSubscriptionsResponse" needs to be exported by the entry point index.d.ts listSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "ListTopicsResponse" needs to be exported by the entry point index.d.ts listTopics(listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "UpdateQueueResponse" needs to be exported by the entry point index.d.ts updateQueue(queueName: string): Promise; updateQueue(queueOptions: QueueOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "UpdateRuleResponse" needs to be exported by the entry point index.d.ts updateRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions: RuleOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "UpdateSubscriptionResponse" needs to be exported by the entry point index.d.ts updateSubscription(topicName: string, subscriptionName: string, subscriptionOptions: SubscriptionOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "UpdateTopicResponse" needs to be exported by the entry point index.d.ts updateTopic(topicName: string, topicOptions: TopicOptions): Promise; } +// @public +export interface ServiceBusManagementClientOptions { + proxySettings?: ProxySettings; +} + // @public export interface ServiceBusMessage { body: any; @@ -353,6 +448,26 @@ export interface TopicOptions { userMetadata?: string; } +// @public +export interface UpdateQueueResponse extends QueueProperties { + _response: HttpOperationResponse; +} + +// @public +export interface UpdateRuleResponse extends RuleDetails { + _response: HttpOperationResponse; +} + +// @public +export interface UpdateSubscriptionResponse extends SubscriptionDetails { + _response: HttpOperationResponse; +} + +// @public +export interface UpdateTopicResponse extends TopicDetails { + _response: HttpOperationResponse; +} + // @public export interface WaitTimeOptions { maxWaitTimeInMs: number; diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index 830b0f052f7f..737c1deb1737 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -48,5 +48,32 @@ export { ServiceBusClient } from "./serviceBusClient"; export { QueueOptions } from "./serializers/queueResourceSerializer"; export { TopicOptions } from "./serializers/topicResourceSerializer"; export { SubscriptionOptions } from "./serializers/subscriptionResourceSerializer"; -export { ServiceBusManagementClient } from "./serviceBusAtomManagementClient"; +export { RuleOptions } from "./serializers/ruleResourceSerializer"; +export { + ServiceBusManagementClient, + ServiceBusManagementClientOptions, + CreateQueueResponse, + CreateRuleResponse, + CreateSubscriptionResponse, + CreateTopicResponse, + DeleteQueueResponse, + DeleteRuleResponse, + DeleteTopicResponse, + DeleteSubscriptionResponse, + GetQueueResponse, + GetQueueMetricsResponse, + GetQueuesResponse, + GetQueuesMetricsResponse, + ListRequestOptions, + GetRuleResponse, + GetSubscriptionResponse, + GetTopicResponse, + ListRulesResponse, + ListSubscriptionsResponse, + ListTopicsResponse, + UpdateQueueResponse, + UpdateRuleResponse, + UpdateSubscriptionResponse, + UpdateTopicResponse +} from "./serviceBusAtomManagementClient"; export { MessageCountDetails, AuthorizationRule, EntityStatus } from "./util/utils"; diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 8b24ba4e8f8b..5ebf66bde607 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -61,9 +61,9 @@ import { import { isJSONLikeObject, isAbsoluteUrl } from "./util/utils"; /** - * Options to use with ServiceBusAtomManagementClient creation + * Options to use with ServiceBusManagementClient creation */ -export interface ServiceBusAtomManagementClientOptions { +export interface ServiceBusManagementClientOptions { /** * Proxy related settings */ @@ -379,7 +379,7 @@ export class ServiceBusManagementClient extends ServiceClient { * @param connectionString The connection string needed for the client to connect to Azure. * @param options ServiceBusAtomManagementClientOptions */ - constructor(connectionString: string, options?: ServiceBusAtomManagementClientOptions) { + constructor(connectionString: string, options?: ServiceBusManagementClientOptions) { const connectionStringObj: any = parseConnectionString(connectionString); if (connectionStringObj.Endpoint == undefined) { From 4c245833a96fc8b980cf5e7b2ac848ccf2028ad2 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Tue, 26 May 2020 14:25:39 -0700 Subject: [PATCH 04/61] more and more exports --- .../service-bus/review/service-bus.api.md | 131 ++++++++++++++++-- sdk/servicebus/service-bus/src/index.ts | 17 ++- 2 files changed, 131 insertions(+), 17 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index cb12301b93f7..545a78a56525 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -38,20 +38,29 @@ export interface BrowseMessagesOptions extends OperationOptions { maxMessageCount?: number; } +// @public +export interface CorrelationFilter { + contentType?: string; + correlationId?: string; + label?: string; + messageId?: string; + replyTo?: string; + replyToSessionId?: string; + sessionId?: string; + to?: string; + userProperties?: any; +} + // @public export interface CreateBatchOptions extends OperationOptions { maxSizeInBytes?: number; } -// Warning: (ae-forgotten-export) The symbol "QueueProperties" needs to be exported by the entry point index.d.ts -// // @public export interface CreateQueueResponse extends QueueProperties { _response: HttpOperationResponse; } -// Warning: (ae-forgotten-export) The symbol "RuleDetails" needs to be exported by the entry point index.d.ts -// // @public export interface CreateRuleResponse extends RuleDetails { _response: HttpOperationResponse; @@ -66,15 +75,11 @@ export interface CreateSenderOptions { export interface CreateSessionReceiverOptions extends SessionReceiverOptions, OperationOptions { } -// Warning: (ae-forgotten-export) The symbol "SubscriptionDetails" needs to be exported by the entry point index.d.ts -// // @public export interface CreateSubscriptionResponse extends SubscriptionDetails { _response: HttpOperationResponse; } -// Warning: (ae-forgotten-export) The symbol "TopicDetails" needs to be exported by the entry point index.d.ts -// // @public export interface CreateTopicResponse extends TopicDetails { _response: HttpOperationResponse; @@ -117,8 +122,6 @@ export type EntityStatus = "Active" | "Creating" | "Deleting" | "ReceiveDisabled export interface GetMessageIteratorOptions extends OperationOptions, WaitTimeOptions { } -// Warning: (ae-forgotten-export) The symbol "QueueMetrics" needs to be exported by the entry point index.d.ts -// // @public export interface GetQueueMetricsResponse extends QueueMetrics { _response: HttpOperationResponse; @@ -205,6 +208,17 @@ export interface OperationOptions { tracingOptions?: OperationTracingOptions; } +// @public +export interface QueueMetrics { + accessedOn?: string; + createdOn?: string; + messageCount?: number; + messageCountDetails?: MessageCountDetails; + queueName: string; + sizeInBytes?: number; + updatedOn?: string; +} + // @public export interface QueueOptions { authorizationRules?: AuthorizationRule[]; @@ -226,6 +240,31 @@ export interface QueueOptions { userMetadata?: string; } +// @public +export interface QueueProperties { + authorizationRules?: AuthorizationRule[]; + autoDeleteOnIdle: string; + deadLetteringOnMessageExpiration: boolean; + defaultMessageTtl: string; + duplicateDetectionHistoryTimeWindow: string; + enableBatchedOperations: boolean; + enableExpress?: boolean; + enablePartitioning: boolean; + entityAvailabilityStatus?: string; + forwardDeadLetteredMessagesTo?: string; + forwardTo?: string; + isAnonymousAccessible?: boolean; + lockDuration: string; + maxDeliveryCount: number; + maxSizeInMegabytes: number; + queueName: string; + requiresDuplicateDetection: boolean; + requiresSession: boolean; + status?: EntityStatus; + supportOrdering?: boolean; + userMetadata?: string; +} + // @public export interface ReceiveBatchOptions extends OperationOptions, WaitTimeOptions { } @@ -275,12 +314,13 @@ export interface Receiver { export { RetryOptions } +// @public +export interface RuleDetails { +} + // @public export interface RuleOptions { - // Warning: (ae-forgotten-export) The symbol "SqlAction" needs to be exported by the entry point index.d.ts action?: SqlAction; - // Warning: (ae-forgotten-export) The symbol "SqlFilter" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "CorrelationFilter" needs to be exported by the entry point index.d.ts filter?: SqlFilter | CorrelationFilter; } @@ -409,10 +449,45 @@ export interface SessionReceiverOptions { sessionId?: string; } +// @public +export type SqlAction = SqlFilter; + +// @public +export interface SqlFilter { +} + // @public export interface SubscribeOptions extends OperationOptions, MessageHandlerOptions { } +// @public +export interface SubscriptionDetails { + accessedOn?: string; + autoDeleteOnIdle: string; + createdOn: string; + deadLetteringOnFilterEvaluationExceptions: boolean; + deadLetteringOnMessageExpiration: boolean; + defaultMessageTtl?: string; + defaultRuleDescription?: any; + enableBatchedOperations: boolean; + enablePartitioning?: boolean; + entityAvailabilityStatus: string; + forwardDeadLetteredMessagesTo?: string; + forwardTo?: string; + lockDuration: string; + maxDeliveryCount: number; + maxSizeInMegabytes?: number; + messageCount: number; + messageCountDetails?: MessageCountDetails; + requiresSession: boolean; + sizeInBytes?: number; + status?: EntityStatus; + subscriptionName: string; + topicName: string; + updatedOn: string; + userMetadata?: string; +} + // @public export interface SubscriptionOptions { autoDeleteOnIdle?: string; @@ -433,6 +508,36 @@ export { TokenCredential } export { TokenType } +// @public +export interface TopicDetails { + accessedOn?: string; + authorizationRules?: AuthorizationRule[]; + autoDeleteOnIdle?: string; + createdOn?: string; + defaultMessageTtl: string; + duplicateDetectionHistoryTimeWindow: string; + enableBatchedOperations: boolean; + enableExpress?: boolean; + enablePartitioning: boolean; + enableSubscriptionPartitioning?: boolean; + entityAvailabilityStatus?: string; + filteringMessagesBeforePublishing?: boolean; + isAnonymousAccessible?: boolean; + isExpress?: boolean; + maxDeliveryCount?: number; + maxSizeInMegabytes: number; + messageCount?: number; + messageCountDetails?: MessageCountDetails; + requiresDuplicateDetection: boolean; + sizeInBytes?: number; + status?: EntityStatus; + subscriptionCount?: number; + supportOrdering: boolean; + topicName: string; + updatedOn?: string; + userMetadata?: string; +} + // @public export interface TopicOptions { authorizationRules?: AuthorizationRule[]; diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index 737c1deb1737..27a09393b35e 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -45,10 +45,19 @@ export { SessionReceiver } from "./receivers/sessionReceiver"; export { Sender } from "./sender"; export { ServiceBusClient } from "./serviceBusClient"; -export { QueueOptions } from "./serializers/queueResourceSerializer"; -export { TopicOptions } from "./serializers/topicResourceSerializer"; -export { SubscriptionOptions } from "./serializers/subscriptionResourceSerializer"; -export { RuleOptions } from "./serializers/ruleResourceSerializer"; +export { QueueOptions, QueueProperties, QueueMetrics } from "./serializers/queueResourceSerializer"; +export { TopicOptions, TopicDetails } from "./serializers/topicResourceSerializer"; +export { + SubscriptionOptions, + SubscriptionDetails +} from "./serializers/subscriptionResourceSerializer"; +export { + RuleOptions, + RuleDetails, + SqlAction, + SqlFilter +} from "./serializers/ruleResourceSerializer"; +export { CorrelationFilter } from "./core/managementClient"; export { ServiceBusManagementClient, ServiceBusManagementClientOptions, From 681430ff655f69fcd7b9dc776899c56b98816171 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 27 May 2020 13:22:59 -0700 Subject: [PATCH 05/61] Add token credential constructor overlaod --- .../service-bus/review/service-bus.api.md | 1 + .../src/serviceBusAtomManagementClient.ts | 100 +++++++++++++----- 2 files changed, 72 insertions(+), 29 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 545a78a56525..f06acc0c1215 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -369,6 +369,7 @@ export interface ServiceBusClientOptions { // @public export class ServiceBusManagementClient extends ServiceClient { constructor(connectionString: string, options?: ServiceBusManagementClientOptions); + constructor(fullyQualifiedNamespace: string, credential: TokenCredential, options?: ServiceBusManagementClientOptions); createQueue(queueName: string): Promise; createQueue(queueOptions: QueueOptions): Promise; createRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions?: RuleOptions): Promise; diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 5ebf66bde607..453c6f6bbf74 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -16,7 +16,12 @@ import { RestError } from "@azure/core-http"; -import { parseConnectionString, SharedKeyCredential } from "@azure/core-amqp"; +import { + parseConnectionString, + SharedKeyCredential, + TokenCredential, + isTokenCredential +} from "@azure/core-amqp"; import { AtomXmlSerializer, executeAtomXmlOperation } from "./util/atomXmlHelper"; @@ -372,47 +377,84 @@ export class ServiceBusManagementClient extends ServiceClient { /** * SAS token provider used to generate tokens as required for the various operations. */ - private sasTokenProvider: SharedKeyCredential; + private sasTokenProvider: SharedKeyCredential | TokenCredential; /** * Initializes a new instance of the ServiceBusManagementClient class. * @param connectionString The connection string needed for the client to connect to Azure. - * @param options ServiceBusAtomManagementClientOptions + * @param options ServiceBusManagementClientOptions */ - constructor(connectionString: string, options?: ServiceBusManagementClientOptions) { - const connectionStringObj: any = parseConnectionString(connectionString); + constructor(connectionString: string, options?: ServiceBusManagementClientOptions); + /** + * + * @param fullyQualifiedNamespace The full namespace of your Service Bus instance which is + * likely to be similar to .servicebus.windows.net. + * @param credential A credential object used by the client to get the token to authenticate the connection + * with the Azure Service Bus. See @azure/identity for creating the credentials. + * If you're using an own implementation of the `TokenCredential` interface against AAD, then set the "scopes" for service-bus + * to be `["https://servicebus.azure.net//user_impersonation"]` to get the appropriate token. + * @param options ServiceBusManagementClientOptions + */ + constructor( + fullyQualifiedNamespace: string, + credential: TokenCredential, + options?: ServiceBusManagementClientOptions + ); + + constructor( + fullyQualifiedNamespaceOrConnectionString1: string, + credentialOrOptions2?: TokenCredential | ServiceBusManagementClientOptions, + options3?: ServiceBusManagementClientOptions + ) { + if (isTokenCredential(credentialOrOptions2)) { + const requestPolicyFactories: RequestPolicyFactory[] = []; + if (options3 && options3.proxySettings) { + requestPolicyFactories.push(proxyPolicy(options3.proxySettings)); + } + const serviceClientOptions: ServiceClientOptions = { + requestPolicyFactories: requestPolicyFactories + }; + super(credentialOrOptions2, serviceClientOptions); + this.sasTokenProvider = credentialOrOptions2; + this.endpoint = fullyQualifiedNamespaceOrConnectionString1; + this.endpointWithProtocol = "sb://" + fullyQualifiedNamespaceOrConnectionString1; + } else { + const connectionString = fullyQualifiedNamespaceOrConnectionString1; + const options = credentialOrOptions2; + const connectionStringObj: any = parseConnectionString(connectionString); - if (connectionStringObj.Endpoint == undefined) { - throw new Error("Missing Endpoint in connection string."); - } + if (connectionStringObj.Endpoint == undefined) { + throw new Error("Missing Endpoint in connection string."); + } - const credentials = new SasServiceClientCredentials( - connectionStringObj.SharedAccessKeyName, - connectionStringObj.SharedAccessKey - ); + const credentials = new SasServiceClientCredentials( + connectionStringObj.SharedAccessKeyName, + connectionStringObj.SharedAccessKey + ); - const requestPolicyFactories: RequestPolicyFactory[] = []; - requestPolicyFactories.push(signingPolicy(credentials)); + const requestPolicyFactories: RequestPolicyFactory[] = []; + requestPolicyFactories.push(signingPolicy(credentials)); - if (options && options.proxySettings) { - requestPolicyFactories.push(proxyPolicy(options.proxySettings)); - } - const serviceClientOptions: ServiceClientOptions = { - requestPolicyFactories: requestPolicyFactories - }; + if (options && options.proxySettings) { + requestPolicyFactories.push(proxyPolicy(options.proxySettings)); + } + const serviceClientOptions: ServiceClientOptions = { + requestPolicyFactories: requestPolicyFactories + }; + + super(credentials, serviceClientOptions); + this.endpoint = (connectionString.match("Endpoint=.*://(.*)/;") || "")[1]; + this.endpointWithProtocol = connectionStringObj.Endpoint; - super(credentials, serviceClientOptions); + this.sasTokenProvider = new SharedKeyCredential( + connectionStringObj.SharedAccessKeyName, + connectionStringObj.SharedAccessKey + ); + } this.queueResourceSerializer = new QueueResourceSerializer(); this.topicResourceSerializer = new TopicResourceSerializer(); this.subscriptionResourceSerializer = new SubscriptionResourceSerializer(); this.ruleResourceSerializer = new RuleResourceSerializer(); - this.endpoint = (connectionString.match("Endpoint=.*://(.*)/;") || "")[1]; - this.endpointWithProtocol = connectionStringObj.Endpoint; - - this.sasTokenProvider = new SharedKeyCredential( - connectionStringObj.SharedAccessKeyName, - connectionStringObj.SharedAccessKey - ); } /** @@ -1207,7 +1249,7 @@ export class ServiceBusManagementClient extends ServiceClient { queueOrSubscriptionFields.ForwardTo || queueOrSubscriptionFields.ForwardDeadLetteredMessagesTo ) { - const token = (await this.sasTokenProvider.getToken(this.endpoint)).token; + const token = (await this.sasTokenProvider.getToken(this.endpoint))!.token; if (queueOrSubscriptionFields.ForwardTo) { webResource.headers.set("ServiceBusSupplementaryAuthorization", token); if (!isAbsoluteUrl(queueOrSubscriptionFields.ForwardTo)) { From 6d0ef776aba9babf0d11df9e1d3831f5c34a1e5e Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 27 May 2020 14:39:01 -0700 Subject: [PATCH 06/61] doesExist() for queue, topic and subscription --- .../src/serviceBusAtomManagementClient.ts | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 453c6f6bbf74..a4b935ce4980 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -719,6 +719,22 @@ export class ServiceBusManagementClient extends ServiceClient { return { _response: response }; } + /** + * Checks whether a given queue exists or not. + * @param queueName + */ + async queueExists(queueName: string): Promise { + log.httpAtomXml(`Performing management operation - queueExists() for "${queueName}"`); + try { + await this.getQueue(queueName); + } catch (error) { + if (error.code == "MessageEntityNotFoundError") { + return false; + } + } + return true; + } + /** * Creates a topic with given name, configured using the given options * @param topicName @@ -865,6 +881,22 @@ export class ServiceBusManagementClient extends ServiceClient { return { _response: response }; } + /** + * Checks whether a given topic exists or not. + * @param topicName + */ + async topicExists(topicName: string): Promise { + log.httpAtomXml(`Performing management operation - topicExists() for "${topicName}"`); + try { + await this.getTopicDetails(topicName); + } catch (error) { + if (error.code == "MessageEntityNotFoundError") { + return false; + } + } + return true; + } + /** * Creates a subscription with given name, configured using the given options * @param topicName @@ -1042,6 +1074,26 @@ export class ServiceBusManagementClient extends ServiceClient { return { _response: response }; } + /** + * Checks whether a given subscription exists in the topic or not. + * @param topicName + * @param subscriptionName + * + */ + async subscriptionExists(topicName: string, subscriptionName: string): Promise { + log.httpAtomXml( + `Performing management operation - subscriptionExists() for "${topicName}" and "${subscriptionName}"` + ); + try { + await this.getSubscriptionDetails(topicName, subscriptionName); + } catch (error) { + if (error.code == "MessageEntityNotFoundError") { + return false; + } + } + return true; + } + /** * Creates a rule with given name, configured using the given options. * @param topicName From 402e988da90fb71019485cbcb266121295d00d96 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 27 May 2020 14:39:35 -0700 Subject: [PATCH 07/61] generate API report --- sdk/servicebus/service-bus/review/service-bus.api.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index f06acc0c1215..38149903ce7c 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -389,6 +389,9 @@ export class ServiceBusManagementClient extends ServiceClient { listRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; listSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; listTopics(listRequestOptions?: ListRequestOptions): Promise; + queueExists(queueName: string): Promise; + subscriptionExists(topicName: string, subscriptionName: string): Promise; + topicExists(topicName: string): Promise; updateQueue(queueName: string): Promise; updateQueue(queueOptions: QueueOptions): Promise; updateRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions: RuleOptions): Promise; From 0f0dad4e570e7aebd1999315afdb1abb5863d82f Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 27 May 2020 15:36:39 -0700 Subject: [PATCH 08/61] api extractor and ts-config (TO BE REVERTED) --- sdk/servicebus/service-bus/api-extractor.json | 2 +- sdk/servicebus/service-bus/tsconfig.json | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sdk/servicebus/service-bus/api-extractor.json b/sdk/servicebus/service-bus/api-extractor.json index 6ac2256f2fa6..d6c0f01f412b 100644 --- a/sdk/servicebus/service-bus/api-extractor.json +++ b/sdk/servicebus/service-bus/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/src/index.d.ts", + "mainEntryPointFilePath": "types/index.d.ts", "docModel": { "enabled": false }, diff --git a/sdk/servicebus/service-bus/tsconfig.json b/sdk/servicebus/service-bus/tsconfig.json index 8a4cfb29135e..798bd39a7724 100644 --- a/sdk/servicebus/service-bus/tsconfig.json +++ b/sdk/servicebus/service-bus/tsconfig.json @@ -34,5 +34,8 @@ }, "compileOnSave": true, "exclude": ["node_modules", "types/**", "./samples/**/*.ts", "test/perf/*", "test/stress/*"], - "include": ["./src/**/*.ts", "./test/**/*.ts"] + "include": [ + "./src/**/*.ts" + //"./test/**/*.ts" + ] } From ce8e83e34f3bd8df8d02bede5baf5ffcd935da22 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 08:34:21 -0700 Subject: [PATCH 09/61] feedback from the service team --- .../serializers/queueResourceSerializer.ts | 161 +----------------- .../src/serviceBusAtomManagementClient.ts | 69 ++++---- 2 files changed, 41 insertions(+), 189 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts index e5ee89d5628a..af26f7f9a4f2 100644 --- a/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts @@ -18,7 +18,6 @@ import { getInteger, getBoolean, getString, - getBooleanOrUndefined, getIntegerOrUndefined, EntityStatus } from "../util/utils"; @@ -31,7 +30,7 @@ import { * converts values to string and ensures the right order as expected by the service * @param queueOptions */ -export function buildQueueOptions(queueOptions: QueueOptions): InternalQueueOptions { +export function buildQueueOptions(queueOptions: QueueDescription): InternalQueueOptions { return { LockDuration: queueOptions.lockDuration, MaxSizeInMegabytes: getStringOrUndefined(queueOptions.maxSizeInMegabytes), @@ -61,7 +60,7 @@ export function buildQueueOptions(queueOptions: QueueOptions): InternalQueueOpti * response from the service * @param rawQueue */ -export function buildQueue(rawQueue: any): QueueProperties { +export function buildQueue(rawQueue: any): QueueDescription { return { queueName: getString(rawQueue[Constants.QUEUE_NAME], "queueName"), @@ -102,13 +101,7 @@ export function buildQueue(rawQueue: any): QueueProperties { rawQueue[Constants.FORWARD_DEADLETTERED_MESSAGES_TO] ), - supportOrdering: getBooleanOrUndefined(rawQueue[Constants.SUPPORT_ORDERING]), - enableExpress: getBooleanOrUndefined(rawQueue[Constants.ENABLE_EXPRESS]), - authorizationRules: getAuthorizationRulesOrUndefined(rawQueue[Constants.AUTHORIZATION_RULES]), - isAnonymousAccessible: getBooleanOrUndefined(rawQueue[Constants.IS_ANONYMOUS_ACCESSIBLE]), - - entityAvailabilityStatus: rawQueue[Constants.ENTITY_AVAILABILITY_STATUS], status: rawQueue[Constants.STATUS] }; @@ -121,7 +114,7 @@ export function buildQueue(rawQueue: any): QueueProperties { * response from the service * @param rawQueue */ -export function buildQueueMetrics(rawQueue: any): QueueMetrics { +export function buildQueueRuntimeInfo(rawQueue: any): QueueRuntimeInfo { return { queueName: getString(rawQueue[Constants.QUEUE_NAME], "queueName"), sizeInBytes: getIntegerOrUndefined(rawQueue[Constants.SIZE_IN_BYTES]), @@ -136,7 +129,7 @@ export function buildQueueMetrics(rawQueue: any): QueueMetrics { /** * Represents settable options on a queue */ -export interface QueueOptions { +export interface QueueDescription { /** * Name of the queue */ @@ -376,151 +369,9 @@ export interface InternalQueueOptions { } /** - * Represents all attributes of a queue entity - */ -export interface QueueProperties { - /** - * Name of the queue - */ - queueName: string; - - /** - * Determines the amount of time in seconds in which a message should be locked - * for processing by a receiver. After this period, the message is unlocked and - * can be consumed by the next receiver. - * Settable only at queue creation time. - * This is specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - lockDuration: string; - - /** - * Specifies the maximum queue size in megabytes. Any attempt to enqueue - * a message that will cause the queue to exceed this value will fail. - */ - maxSizeInMegabytes: number; - - /** - * Depending on whether DeadLettering is enabled, a message is automatically - * moved to the DeadLetterQueue or deleted if it has been stored in the queue - * for longer than the specified time. This value is overwritten by a TTL - * specified on the message if and only if the message TTL is smaller than - * the TTL set on the queue. - * This value is immutable after the Queue has been created. - * This is to be specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - defaultMessageTtl: string; - - /** - * Specifies the time span during which the Service Bus detects message duplication. - * This is to be specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - duplicateDetectionHistoryTimeWindow: string; - - /** - * Absolute URL or the name of the queue or topic the dead-lettered - * messages are to be forwarded to. - * For example, an absolute URL input would be of the form - * `sb:///` - */ - forwardDeadLetteredMessagesTo?: string; - - /** - * Max idle time before entity is deleted. - * This is specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - autoDeleteOnIdle: string; - - /** - * The maximum delivery count of messages after which if it is still not settled, - * gets moved to the dead-letter sub-queue. - * - */ - maxDeliveryCount: number; - - /** - * If set to true, the queue will be session-aware and only SessionReceiver - * will be supported. Session-aware queues are not supported through REST. - * Settable only at queue creation time. - */ - requiresSession: boolean; - - /** - * Specifies if batched operations should be allowed. - */ - enableBatchedOperations: boolean; - - /** - * If enabled, the topic will detect duplicate messages within the time - * span specified by the DuplicateDetectionHistoryTimeWindow property. - * Settable only at queue creation time. - */ - requiresDuplicateDetection: boolean; - - /** - * If it is enabled and a message expires, the Service Bus moves the message - * from the queue into the queue’s dead-letter sub-queue. If disabled, message - * will be permanently deleted from the queue. Settable only at queue creation time. - */ - deadLetteringOnMessageExpiration: boolean; - - /** - * Absolute URL or the name of the queue or topic the - * messages are to be forwarded to. - * For example, an absolute URL input would be of the form - * `sb:///` - */ - forwardTo?: string; - - /** - * The user provided metadata information associated with the queue description. - * Used to specify textual content such as tags, labels, etc. - * Value must not exceed 1024 bytes encoded in utf-8. - */ - userMetadata?: string; - - /** - * Specifies whether the queue should be partitioned. - */ - enablePartitioning: boolean; - - /** - * Authorization rules on the queue - */ - authorizationRules?: AuthorizationRule[]; - - /** - * Ordering support for messages - */ - supportOrdering?: boolean; - - /** - * Enable express option - */ - enableExpress?: boolean; - - /** - * Is anonymous accessible queue option - */ - isAnonymousAccessible?: boolean; - - /** - * Entity availability status - */ - entityAvailabilityStatus?: string; - - /** - * Status of the messaging entity. - */ - status?: EntityStatus; -} -/** - * Represents all attributes of a queue entity + * Represents runtime info attributes of a queue entity */ -export interface QueueMetrics { +export interface QueueRuntimeInfo { /** * Name of the queue */ diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index a4b935ce4980..51fc8e519f7e 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -32,12 +32,11 @@ import * as Constants from "./util/constants"; import { QueueResourceSerializer, InternalQueueOptions, - QueueOptions, + QueueDescription, buildQueueOptions, buildQueue, - QueueProperties, - buildQueueMetrics, - QueueMetrics + buildQueueRuntimeInfo, + QueueRuntimeInfo } from "./serializers/queueResourceSerializer"; import { TopicResourceSerializer, @@ -93,7 +92,7 @@ export interface ListRequestOptions { /** * Represents result of create, get, update and delete operations on queue. */ -export interface GetQueueMetricsResponse extends QueueMetrics { +export interface GetQueueRuntimeInfoResponse extends QueueRuntimeInfo { /** * The underlying HTTP response. */ @@ -103,7 +102,7 @@ export interface GetQueueMetricsResponse extends QueueMetrics { /** * Represents result of create, get, update and delete operations on queue. */ -export interface GetQueuesMetricsResponse extends Array { +export interface GetQueuesRuntimeInfoResponse extends Array { /** * The underlying HTTP response. */ @@ -113,7 +112,7 @@ export interface GetQueuesMetricsResponse extends Array { /** * Represents result of create, get, update and delete operations on queue. */ -export interface QueueResponse extends QueueProperties { +export interface QueueResponse extends QueueDescription { /** * The underlying HTTP response. */ @@ -123,7 +122,7 @@ export interface QueueResponse extends QueueProperties { /** * Create Queue response */ -export interface CreateQueueResponse extends QueueProperties { +export interface CreateQueueResponse extends QueueDescription { /** * The underlying HTTP response. */ @@ -133,7 +132,7 @@ export interface CreateQueueResponse extends QueueProperties { /** * Get Queue response */ -export interface GetQueueResponse extends QueueProperties { +export interface GetQueueResponse extends QueueDescription { /** * The underlying HTTP response. */ @@ -143,7 +142,7 @@ export interface GetQueueResponse extends QueueProperties { /** * Update Queue response */ -export interface UpdateQueueResponse extends QueueProperties { +export interface UpdateQueueResponse extends QueueDescription { /** * The underlying HTTP response. */ @@ -163,7 +162,7 @@ export interface DeleteQueueResponse { /** * Represents result of list operation on queues. */ -export interface GetQueuesResponse extends Array { +export interface GetQueuesResponse extends Array { /** * The underlying HTTP response. */ @@ -475,7 +474,7 @@ export class ServiceBusManagementClient extends ServiceClient { async createQueue(queueName: string): Promise; /** * Creates a queue configured using the given options - * @param queueOptions Options to configure the Queue being created. + * @param queue Options to configure the Queue being created. * For example, you can configure a queue to support partitions or sessions. * * Following are errors that can be expected from this operation @@ -489,8 +488,8 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async createQueue(queueOptions: QueueOptions): Promise; - async createQueue(queueNameOrOptions: string | QueueOptions): Promise { + async createQueue(queue: QueueDescription): Promise; + async createQueue(queueNameOrOptions: string | QueueDescription): Promise { if (typeof queueNameOrOptions == "string") { log.httpAtomXml( `Performing management operation - createQueue() for "${queueNameOrOptions}"` @@ -556,14 +555,14 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async getQueueMetrics(queueName: string): Promise { + async getQueueRuntimeInfo(queueName: string): Promise { log.httpAtomXml(`Performing management operation - getQueue() for "${queueName}"`); const response: HttpOperationResponse = await this.getResource( queueName, this.queueResourceSerializer ); - return this.buildQueueMetricsResponse(response); + return this.buildQueueRuntimeInfoResponse(response); } /** @@ -605,9 +604,9 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async getQueuesMetrics( + async getQueuesRuntimeInfo( listRequestOptions?: ListRequestOptions - ): Promise { + ): Promise { log.httpAtomXml( `Performing management operation - listQueues() with options: ${listRequestOptions}` ); @@ -617,7 +616,7 @@ export class ServiceBusManagementClient extends ServiceClient { this.queueResourceSerializer ); - return this.buildListQueuesMetricsResponse(response); + return this.buildListQueuesRuntimeInfoResponse(response); } /** @@ -637,7 +636,7 @@ export class ServiceBusManagementClient extends ServiceClient { async updateQueue(queueName: string): Promise; /** * Updates properties on the Queue by the given name based on the given options - * @param queueOptions Options to configure the Queue being updated. + * @param queue Options to configure the Queue being updated. * For example, you can configure a queue to support partitions or sessions. * * Following are errors that can be expected from this operation @@ -650,14 +649,14 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async updateQueue(queueOptions: QueueOptions): Promise; - async updateQueue(queueNameOrOptions: string | QueueOptions): Promise { + async updateQueue(queue: QueueDescription): Promise; + async updateQueue(queueNameOrOptions: string | QueueDescription): Promise { if (typeof queueNameOrOptions == "string") { log.httpAtomXml( `Performing management operation - updateQueue() for "${queueNameOrOptions}"` ); - const finalQueueOptions: QueueOptions = { queueName: queueNameOrOptions }; + const finalQueueOptions: QueueDescription = { queueName: queueNameOrOptions }; const getQueueResult = await this.getQueue(queueNameOrOptions); Object.assign(finalQueueOptions, getQueueResult); @@ -676,11 +675,11 @@ export class ServiceBusManagementClient extends ServiceClient { if (!isJSONLikeObject(queueNameOrOptions) || queueNameOrOptions === null) { throw new TypeError( - `Parameter "queueOptions" must be an object of type "QueueOptions" and cannot be undefined or null.` + `Parameter "queue" must be an object of type "QueueOptions" and cannot be undefined or null.` ); } - const finalQueueOptions: QueueOptions = { queueName: queueNameOrOptions.queueName }; + const finalQueueOptions: QueueDescription = { queueName: queueNameOrOptions.queueName }; const getQueueResult = await this.getQueue(queueNameOrOptions.queueName); Object.assign(finalQueueOptions, getQueueResult, queueNameOrOptions); @@ -1417,7 +1416,7 @@ export class ServiceBusManagementClient extends ServiceClient { private buildListQueuesResponse(response: HttpOperationResponse): GetQueuesResponse { try { - const queues: QueueProperties[] = []; + const queues: QueueDescription[] = []; if (!Array.isArray(response.parsedBody)) { throw new TypeError(`${response.parsedBody} was expected to be of type Array`); } @@ -1444,22 +1443,22 @@ export class ServiceBusManagementClient extends ServiceClient { } } - private buildListQueuesMetricsResponse( + private buildListQueuesRuntimeInfoResponse( response: HttpOperationResponse - ): GetQueuesMetricsResponse { + ): GetQueuesRuntimeInfoResponse { try { - const queues: QueueMetrics[] = []; + const queues: QueueRuntimeInfo[] = []; if (!Array.isArray(response.parsedBody)) { throw new TypeError(`${response.parsedBody} was expected to be of type Array`); } const rawQueueArray: any = response.parsedBody; for (let i = 0; i < rawQueueArray.length; i++) { - const queue = buildQueueMetrics(rawQueueArray[i]); + const queue = buildQueueRuntimeInfo(rawQueueArray[i]); if (queue) { queues.push(queue); } } - const listQueuesResponse: GetQueuesMetricsResponse = Object.assign(queues, { + const listQueuesResponse: GetQueuesRuntimeInfoResponse = Object.assign(queues, { _response: response }); return listQueuesResponse; @@ -1494,10 +1493,12 @@ export class ServiceBusManagementClient extends ServiceClient { } } - private buildQueueMetricsResponse(response: HttpOperationResponse): GetQueueMetricsResponse { + private buildQueueRuntimeInfoResponse( + response: HttpOperationResponse + ): GetQueueRuntimeInfoResponse { try { - const queue = buildQueueMetrics(response.parsedBody); - const queueResponse: GetQueueMetricsResponse = Object.assign(queue || {}, { + const queue = buildQueueRuntimeInfo(response.parsedBody); + const queueResponse: GetQueueRuntimeInfoResponse = Object.assign(queue || {}, { _response: response }); return queueResponse; From 0d66b3774633b2c5c3c7141eed2cb03fc4418810 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 08:37:25 -0700 Subject: [PATCH 10/61] update index.ts --- sdk/servicebus/service-bus/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index 27a09393b35e..1b4625f99dd1 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -45,7 +45,7 @@ export { SessionReceiver } from "./receivers/sessionReceiver"; export { Sender } from "./sender"; export { ServiceBusClient } from "./serviceBusClient"; -export { QueueOptions, QueueProperties, QueueMetrics } from "./serializers/queueResourceSerializer"; +export { QueueDescription, QueueRuntimeInfo } from "./serializers/queueResourceSerializer"; export { TopicOptions, TopicDetails } from "./serializers/topicResourceSerializer"; export { SubscriptionOptions, @@ -70,9 +70,9 @@ export { DeleteTopicResponse, DeleteSubscriptionResponse, GetQueueResponse, - GetQueueMetricsResponse, + GetQueueRuntimeInfoResponse, GetQueuesResponse, - GetQueuesMetricsResponse, + GetQueuesRuntimeInfoResponse, ListRequestOptions, GetRuleResponse, GetSubscriptionResponse, From 3eaaf9bb2d85abcf3d9898434eb109ed40ea84f3 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 08:38:59 -0700 Subject: [PATCH 11/61] update API report --- .../service-bus/review/service-bus.api.md | 61 ++++++------------- 1 file changed, 18 insertions(+), 43 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 38149903ce7c..532831c6ab68 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -57,7 +57,7 @@ export interface CreateBatchOptions extends OperationOptions { } // @public -export interface CreateQueueResponse extends QueueProperties { +export interface CreateQueueResponse extends QueueDescription { _response: HttpOperationResponse; } @@ -123,22 +123,22 @@ export interface GetMessageIteratorOptions extends OperationOptions, WaitTimeOpt } // @public -export interface GetQueueMetricsResponse extends QueueMetrics { +export interface GetQueueResponse extends QueueDescription { _response: HttpOperationResponse; } // @public -export interface GetQueueResponse extends QueueProperties { +export interface GetQueueRuntimeInfoResponse extends QueueRuntimeInfo { _response: HttpOperationResponse; } // @public -export interface GetQueuesMetricsResponse extends Array { +export interface GetQueuesResponse extends Array { _response: HttpOperationResponse; } // @public -export interface GetQueuesResponse extends Array { +export interface GetQueuesRuntimeInfoResponse extends Array { _response: HttpOperationResponse; } @@ -209,18 +209,7 @@ export interface OperationOptions { } // @public -export interface QueueMetrics { - accessedOn?: string; - createdOn?: string; - messageCount?: number; - messageCountDetails?: MessageCountDetails; - queueName: string; - sizeInBytes?: number; - updatedOn?: string; -} - -// @public -export interface QueueOptions { +export interface QueueDescription { authorizationRules?: AuthorizationRule[]; autoDeleteOnIdle?: string; deadLetteringOnMessageExpiration?: boolean; @@ -241,28 +230,14 @@ export interface QueueOptions { } // @public -export interface QueueProperties { - authorizationRules?: AuthorizationRule[]; - autoDeleteOnIdle: string; - deadLetteringOnMessageExpiration: boolean; - defaultMessageTtl: string; - duplicateDetectionHistoryTimeWindow: string; - enableBatchedOperations: boolean; - enableExpress?: boolean; - enablePartitioning: boolean; - entityAvailabilityStatus?: string; - forwardDeadLetteredMessagesTo?: string; - forwardTo?: string; - isAnonymousAccessible?: boolean; - lockDuration: string; - maxDeliveryCount: number; - maxSizeInMegabytes: number; +export interface QueueRuntimeInfo { + accessedOn?: string; + createdOn?: string; + messageCount?: number; + messageCountDetails?: MessageCountDetails; queueName: string; - requiresDuplicateDetection: boolean; - requiresSession: boolean; - status?: EntityStatus; - supportOrdering?: boolean; - userMetadata?: string; + sizeInBytes?: number; + updatedOn?: string; } // @public @@ -371,7 +346,7 @@ export class ServiceBusManagementClient extends ServiceClient { constructor(connectionString: string, options?: ServiceBusManagementClientOptions); constructor(fullyQualifiedNamespace: string, credential: TokenCredential, options?: ServiceBusManagementClientOptions); createQueue(queueName: string): Promise; - createQueue(queueOptions: QueueOptions): Promise; + createQueue(queue: QueueDescription): Promise; createRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions?: RuleOptions): Promise; createSubscription(topicName: string, subscriptionName: string, subscriptionOptions?: SubscriptionOptions): Promise; createTopic(topicName: string, topicOptions?: TopicOptions): Promise; @@ -380,9 +355,9 @@ export class ServiceBusManagementClient extends ServiceClient { deleteSubscription(topicName: string, subscriptionName: string): Promise; deleteTopic(topicName: string): Promise; getQueue(queueName: string): Promise; - getQueueMetrics(queueName: string): Promise; + getQueueRuntimeInfo(queueName: string): Promise; getQueues(listRequestOptions?: ListRequestOptions): Promise; - getQueuesMetrics(listRequestOptions?: ListRequestOptions): Promise; + getQueuesRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; getRuleDetails(topicName: string, subscriptioName: string, ruleName: string): Promise; getSubscriptionDetails(topicName: string, subscriptionName: string): Promise; getTopicDetails(topicName: string): Promise; @@ -393,7 +368,7 @@ export class ServiceBusManagementClient extends ServiceClient { subscriptionExists(topicName: string, subscriptionName: string): Promise; topicExists(topicName: string): Promise; updateQueue(queueName: string): Promise; - updateQueue(queueOptions: QueueOptions): Promise; + updateQueue(queue: QueueDescription): Promise; updateRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions: RuleOptions): Promise; updateSubscription(topicName: string, subscriptionName: string, subscriptionOptions: SubscriptionOptions): Promise; updateTopic(topicName: string, topicOptions: TopicOptions): Promise; @@ -558,7 +533,7 @@ export interface TopicOptions { } // @public -export interface UpdateQueueResponse extends QueueProperties { +export interface UpdateQueueResponse extends QueueDescription { _response: HttpOperationResponse; } From f77d450ba35b1b26ab872b4f7be5663a5d88382b Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 08:41:59 -0700 Subject: [PATCH 12/61] Update queue related imports in tests --- .../service-bus/test/utils/managementUtils.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/sdk/servicebus/service-bus/test/utils/managementUtils.ts b/sdk/servicebus/service-bus/test/utils/managementUtils.ts index 05039590d8cd..98047068d1da 100644 --- a/sdk/servicebus/service-bus/test/utils/managementUtils.ts +++ b/sdk/servicebus/service-bus/test/utils/managementUtils.ts @@ -2,16 +2,16 @@ // Licensed under the MIT license. import { delay } from "../../src"; -import { QueueOptions } from "../../src/serializers/queueResourceSerializer"; +import { QueueDescription } from "../../src/serializers/queueResourceSerializer"; import { TopicOptions } from "../../src/serializers/topicResourceSerializer"; import { SubscriptionOptions } from "../../src/serializers/subscriptionResourceSerializer"; -import { ServiceBusAtomManagementClient } from "../../src/serviceBusAtomManagementClient"; +import { ServiceBusManagementClient } from "../../src/serviceBusAtomManagementClient"; import { EnvVarNames, getEnvVars } from "./envVarUtils"; import chai from "chai"; const should = chai.should(); -let client: ServiceBusAtomManagementClient; +let client: ServiceBusManagementClient; /** * Utility to fetch cached instance of `ServiceBusAtomManagementClient` else creates and returns @@ -20,7 +20,7 @@ let client: ServiceBusAtomManagementClient; async function getManagementClient() { if (client == undefined) { const env = getEnvVars(); - client = new ServiceBusAtomManagementClient(env[EnvVarNames.SERVICEBUS_CONNECTION_STRING]); + client = new ServiceBusManagementClient(env[EnvVarNames.SERVICEBUS_CONNECTION_STRING]); } return client; } @@ -76,7 +76,10 @@ async function retry( * @param queueName * @param parameters */ -export async function recreateQueue(queueName: string, parameters?: QueueOptions): Promise { +export async function recreateQueue( + queueName: string, + parameters?: Omit +): Promise { await getManagementClient(); const deleteQueueOperation = async () => { @@ -84,12 +87,12 @@ export async function recreateQueue(queueName: string, parameters?: QueueOptions }; const createQueueOperation = async () => { - await client.createQueue(queueName, parameters); + await client.createQueue({ queueName: queueName, ...parameters }); }; const checkIfQueueExistsOperation = async () => { try { - await client.getQueueDetails(queueName); + await client.getQueue(queueName); } catch (err) { return false; } @@ -198,7 +201,7 @@ export async function verifyMessageCount( await getManagementClient(); should.equal( queueName - ? (await client.getQueueDetails(queueName)).messageCount + ? (await client.getQueueRuntimeInfo(queueName)).messageCount : (await client.getSubscriptionDetails(topicName!, subscriptionName!)).messageCount, expectedMessageCount, `Unexpected number of messages are present in the entity.` From 7244666cd1119f19fd54dd06e1977094a06aec70 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 09:59:31 -0700 Subject: [PATCH 13/61] revert api-extractor and tsconfig changes to allow compiling tests --- sdk/servicebus/service-bus/api-extractor.json | 2 +- sdk/servicebus/service-bus/tsconfig.json | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/sdk/servicebus/service-bus/api-extractor.json b/sdk/servicebus/service-bus/api-extractor.json index d6c0f01f412b..6ac2256f2fa6 100644 --- a/sdk/servicebus/service-bus/api-extractor.json +++ b/sdk/servicebus/service-bus/api-extractor.json @@ -1,6 +1,6 @@ { "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", - "mainEntryPointFilePath": "types/index.d.ts", + "mainEntryPointFilePath": "types/src/index.d.ts", "docModel": { "enabled": false }, diff --git a/sdk/servicebus/service-bus/tsconfig.json b/sdk/servicebus/service-bus/tsconfig.json index 798bd39a7724..8a4cfb29135e 100644 --- a/sdk/servicebus/service-bus/tsconfig.json +++ b/sdk/servicebus/service-bus/tsconfig.json @@ -34,8 +34,5 @@ }, "compileOnSave": true, "exclude": ["node_modules", "types/**", "./samples/**/*.ts", "test/perf/*", "test/stress/*"], - "include": [ - "./src/**/*.ts" - //"./test/**/*.ts" - ] + "include": ["./src/**/*.ts", "./test/**/*.ts"] } From 54e738f98146379e05f25e677e4bd8fa84386f9c Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 10:00:02 -0700 Subject: [PATCH 14/61] fix build failures of ATOM API tests --- .../service-bus/test/atomManagement.spec.ts | 31 +++++++++---------- .../service-bus/test/atomXml.spec.ts | 21 +++++++++---- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index debcffe42e80..a7f5fe8a101c 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { QueueOptions } from "../src/serializers/queueResourceSerializer"; +import { QueueDescription } from "../src/serializers/queueResourceSerializer"; import { TopicOptions } from "../src/serializers/topicResourceSerializer"; import { SubscriptionOptions } from "../src/serializers/subscriptionResourceSerializer"; import { RuleOptions } from "../src/serializers/ruleResourceSerializer"; import { EntityStatus } from "../src/util/utils"; -import { ServiceBusAtomManagementClient } from "../src/serviceBusAtomManagementClient"; +import { ServiceBusManagementClient } from "../src/serviceBusAtomManagementClient"; import chai from "chai"; import chaiAsPromised from "chai-as-promised"; @@ -27,7 +27,7 @@ import { EntityNames } from "./utils/testUtils"; import { parseConnectionString } from "@azure/core-amqp"; import { recreateQueue, recreateTopic, recreateSubscription } from "./utils/managementUtils"; -const serviceBusAtomManagementClient: ServiceBusAtomManagementClient = new ServiceBusAtomManagementClient( +const serviceBusAtomManagementClient: ServiceBusManagementClient = new ServiceBusManagementClient( env[EnvVarNames.SERVICEBUS_CONNECTION_STRING] ); @@ -1919,7 +1919,7 @@ async function createEntity( topicPath?: string, subscriptionPath?: string, overrideOptions?: boolean, // If this is false, then the default options will be populated as used for basic testing. - queueOptions?: QueueOptions, + queueOptions?: Omit, topicOptions?: TopicOptions, subscriptionOptions?: SubscriptionOptions, ruleOptions?: RuleOptions @@ -1971,10 +1971,10 @@ async function createEntity( switch (testEntityType) { case EntityType.QUEUE: - const queueResponse = await serviceBusAtomManagementClient.createQueue( - entityPath, - queueOptions - ); + const queueResponse = await serviceBusAtomManagementClient.createQueue({ + queueName: entityPath, + ...queueOptions + }); return queueResponse; case EntityType.TOPIC: const topicResponse = await serviceBusAtomManagementClient.createTopic( @@ -2019,7 +2019,7 @@ async function getEntity( ): Promise { switch (testEntityType) { case EntityType.QUEUE: - const queueResponse = await serviceBusAtomManagementClient.getQueueDetails(entityPath); + const queueResponse = await serviceBusAtomManagementClient.getQueue(entityPath); return queueResponse; case EntityType.TOPIC: const topicResponse = await serviceBusAtomManagementClient.getTopicDetails(entityPath); @@ -2057,7 +2057,7 @@ async function updateEntity( topicPath?: string, subscriptionPath?: string, overrideOptions?: boolean, // If this is false, then the default options will be populated as used for basic testing. - queueOptions?: QueueOptions, + queueOptions?: Omit, topicOptions?: TopicOptions, subscriptionOptions?: SubscriptionOptions, ruleOptions?: RuleOptions @@ -2109,11 +2109,10 @@ async function updateEntity( switch (testEntityType) { case EntityType.QUEUE: - const queueResponse = await serviceBusAtomManagementClient.updateQueue( - entityPath, - // @ts-ignore - queueOptions - ); + const queueResponse = await serviceBusAtomManagementClient.updateQueue({ + queueName: entityPath, + ...queueOptions + }); return queueResponse; case EntityType.TOPIC: const topicResponse = await serviceBusAtomManagementClient.updateTopic( @@ -2202,7 +2201,7 @@ async function listEntities( ): Promise { switch (testEntityType) { case EntityType.QUEUE: - const queueResponse = await serviceBusAtomManagementClient.listQueues({ + const queueResponse = await serviceBusAtomManagementClient.getQueues({ skip: skip, top: top }); diff --git a/sdk/servicebus/service-bus/test/atomXml.spec.ts b/sdk/servicebus/service-bus/test/atomXml.spec.ts index a7fa094fc350..8b5f207a47f7 100644 --- a/sdk/servicebus/service-bus/test/atomXml.spec.ts +++ b/sdk/servicebus/service-bus/test/atomXml.spec.ts @@ -15,7 +15,7 @@ import { deserializeAtomXmlResponse } from "../src/util/atomXmlHelper"; import * as Constants from "../src/util/constants"; -import { ServiceBusAtomManagementClient } from "../src/serviceBusAtomManagementClient"; +import { ServiceBusManagementClient } from "../src/serviceBusAtomManagementClient"; import { QueueResourceSerializer } from "../src/serializers/queueResourceSerializer"; import { HttpOperationResponse, WebResource, HttpHeaders } from "@azure/core-http"; import { TopicResourceSerializer } from "../src/serializers/topicResourceSerializer"; @@ -71,7 +71,7 @@ const subscriptionProperties = [ const ruleProperties = ["Filter", "Action", "Name"]; -const mockServiceBusAtomManagementClient: ServiceBusAtomManagementClient = new ServiceBusAtomManagementClient( +const mockServiceBusAtomManagementClient: ServiceBusManagementClient = new ServiceBusManagementClient( "Endpoint=test/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=test" ); @@ -595,7 +595,10 @@ class MockSerializer implements AtomXmlSerializer { }; }; try { - await mockServiceBusAtomManagementClient.createQueue("test", testCase.input as any); + await mockServiceBusAtomManagementClient.createQueue({ + queueName: "test", + ...(testCase.input as any) + }); assert.fail("Error must be thrown"); } catch (err) { assert.equal( @@ -751,7 +754,10 @@ class MockSerializer implements AtomXmlSerializer { return response; }; try { - await mockServiceBusAtomManagementClient.createQueue("test", testCase.input as any); + await mockServiceBusAtomManagementClient.createQueue({ + queueName: "test", + ...(testCase.input as any) + }); assert.fail("Error must be thrown"); } catch (err) { assert.equal(err.code, testCase.output.errorCode, `Unexpected error code found.`); @@ -889,7 +895,10 @@ class MockSerializer implements AtomXmlSerializer { }; try { - await mockServiceBusAtomManagementClient.createQueue("test", testCase as any); + await mockServiceBusAtomManagementClient.createQueue({ + queueName: "test", + ...(testCase as any) + }); assert.fail("Error must be thrown"); } catch (err) { assert.equal(err.code, testCase.errorCode, `Unexpected error code found.`); @@ -932,7 +941,7 @@ describe(`Parse empty response for list() requests to return as empty array`, fu headers: new HttpHeaders({}) }; }; - const result = await mockServiceBusAtomManagementClient.listQueues(); + const result = await mockServiceBusAtomManagementClient.getQueues(); assertEmptyArray(result); }); From 572917a77298cb7413872a103491cd0840a69a5f Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 10:26:49 -0700 Subject: [PATCH 15/61] changes to rule options and interfaces --- .../service-bus/review/service-bus.api.md | 20 +++++------ .../service-bus/src/core/managementClient.ts | 12 +++---- sdk/servicebus/service-bus/src/index.ts | 6 ++-- .../src/receivers/subscriptionRuleManager.ts | 6 ++-- .../src/serializers/ruleResourceSerializer.ts | 36 +++++++++---------- .../src/serviceBusAtomManagementClient.ts | 16 ++++----- .../service-bus/test/atomManagement.spec.ts | 2 +- 7 files changed, 49 insertions(+), 49 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 532831c6ab68..946e9a9d5e07 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -39,7 +39,7 @@ export interface BrowseMessagesOptions extends OperationOptions { } // @public -export interface CorrelationFilter { +export interface CorrelationRuleFilter { contentType?: string; correlationId?: string; label?: string; @@ -62,7 +62,7 @@ export interface CreateQueueResponse extends QueueDescription { } // @public -export interface CreateRuleResponse extends RuleDetails { +export interface CreateRuleResponse extends RuleDescription { _response: HttpOperationResponse; } @@ -143,7 +143,7 @@ export interface GetQueuesRuntimeInfoResponse extends Array { } // @public -export interface GetRuleResponse extends RuleDetails { +export interface GetRuleResponse extends RuleDescription { _response: HttpOperationResponse; } @@ -164,7 +164,7 @@ export interface ListRequestOptions { } // @public -export interface ListRulesResponse extends Array { +export interface ListRulesResponse extends Array { _response: HttpOperationResponse; } @@ -290,13 +290,13 @@ export interface Receiver { export { RetryOptions } // @public -export interface RuleDetails { +export interface RuleDescription { } // @public export interface RuleOptions { action?: SqlAction; - filter?: SqlFilter | CorrelationFilter; + filter?: SqlRuleFilter | CorrelationRuleFilter; } // @public @@ -358,7 +358,7 @@ export class ServiceBusManagementClient extends ServiceClient { getQueueRuntimeInfo(queueName: string): Promise; getQueues(listRequestOptions?: ListRequestOptions): Promise; getQueuesRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; - getRuleDetails(topicName: string, subscriptioName: string, ruleName: string): Promise; + getRuleDescription(topicName: string, subscriptioName: string, ruleName: string): Promise; getSubscriptionDetails(topicName: string, subscriptionName: string): Promise; getTopicDetails(topicName: string): Promise; listRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; @@ -429,10 +429,10 @@ export interface SessionReceiverOptions { } // @public -export type SqlAction = SqlFilter; +export type SqlAction = SqlRuleFilter; // @public -export interface SqlFilter { +export interface SqlRuleFilter { } // @public @@ -538,7 +538,7 @@ export interface UpdateQueueResponse extends QueueDescription { } // @public -export interface UpdateRuleResponse extends RuleDetails { +export interface UpdateRuleResponse extends RuleDescription { _response: HttpOperationResponse; } diff --git a/sdk/servicebus/service-bus/src/core/managementClient.ts b/sdk/servicebus/service-bus/src/core/managementClient.ts index 8d53950264a3..57874ae6b765 100644 --- a/sdk/servicebus/service-bus/src/core/managementClient.ts +++ b/sdk/servicebus/service-bus/src/core/managementClient.ts @@ -59,9 +59,9 @@ export interface RuleDescription { * - `string`: SQL-like condition expression that is evaluated against the messages' * user-defined properties and system properties. All system properties will be prefixed with * `sys.` in the condition expression. - * - `CorrelationFilter`: Properties of the filter will be used to match with the message properties. + * - `CorrelationRuleFilter`: Properties of the filter will be used to match with the message properties. */ - filter?: string | CorrelationFilter; + filter?: string | CorrelationRuleFilter; /** * Action to perform if the message satisfies the filtering expression. */ @@ -74,10 +74,10 @@ export interface RuleDescription { /** * Represents the correlation filter expression. - * A CorrelationFilter holds a set of conditions that are matched against user and system properties + * A CorrelationRuleFilter holds a set of conditions that are matched against user and system properties * of incoming messages from a Subscription. */ -export interface CorrelationFilter { +export interface CorrelationRuleFilter { /** * Value to be matched with the `correlationId` property of the incoming message. */ @@ -1301,7 +1301,7 @@ export class ManagementClient extends LinkEntity { */ async addRule( ruleName: string, - filter: boolean | string | CorrelationFilter, + filter: boolean | string | CorrelationRuleFilter, sqlRuleActionExpression?: string, options?: OperationOptions & SendManagementRequestOptions ): Promise { @@ -1322,7 +1322,7 @@ export class ManagementClient extends LinkEntity { !correlationProperties.some((validProperty) => filter.hasOwnProperty(validProperty)) ) { throw new TypeError( - `The parameter "filter" should be either a boolean, string or implement the CorrelationFilter interface.` + `The parameter "filter" should be either a boolean, string or implement the CorrelationRuleFilter interface.` ); } diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index 1b4625f99dd1..8d6a986c6990 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -53,11 +53,11 @@ export { } from "./serializers/subscriptionResourceSerializer"; export { RuleOptions, - RuleDetails, + RuleDescription, SqlAction, - SqlFilter + SqlRuleFilter } from "./serializers/ruleResourceSerializer"; -export { CorrelationFilter } from "./core/managementClient"; +export { CorrelationRuleFilter } from "./core/managementClient"; export { ServiceBusManagementClient, ServiceBusManagementClientOptions, diff --git a/sdk/servicebus/service-bus/src/receivers/subscriptionRuleManager.ts b/sdk/servicebus/service-bus/src/receivers/subscriptionRuleManager.ts index d47777eb0081..6e90a9c3422f 100644 --- a/sdk/servicebus/service-bus/src/receivers/subscriptionRuleManager.ts +++ b/sdk/servicebus/service-bus/src/receivers/subscriptionRuleManager.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { RuleDescription, CorrelationFilter } from "../core/managementClient"; +import { RuleDescription, CorrelationRuleFilter } from "../core/managementClient"; import { throwErrorIfClientOrConnectionClosed } from "../util/errors"; import { ClientEntityContext } from "../clientEntityContext"; import { retry, RetryOperationType, RetryConfig, RetryOptions } from "@azure/core-amqp"; @@ -51,7 +51,7 @@ interface SubscriptionRuleManager { */ addRule( ruleName: string, - filter: boolean | string | CorrelationFilter, + filter: boolean | string | CorrelationRuleFilter, sqlRuleActionExpression?: string, options?: OperationOptions ): Promise; @@ -129,7 +129,7 @@ export class SubscriptionRuleManagerImpl implements SubscriptionRuleManager { addRule( ruleName: string, - filter: boolean | string | CorrelationFilter, + filter: boolean | string | CorrelationRuleFilter, sqlRuleActionExpression?: string, options: OperationOptions = {} ): Promise { diff --git a/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts index e0dc00176ce9..0c7afe50f8cd 100644 --- a/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts @@ -15,7 +15,7 @@ import { getString, isJSONLikeObject } from "../util/utils"; -import { CorrelationFilter } from "../core/managementClient"; +import { CorrelationRuleFilter } from "../core/managementClient"; /** * @internal @@ -38,7 +38,7 @@ export function buildRuleOptions(name: string, ruleOptions: RuleOptions = {}): I * response from the service * @param rawRule */ -export function buildRule(rawRule: any): RuleDetails { +export function buildRule(rawRule: any): RuleDescription { return { ruleName: getString(rawRule["RuleName"], "ruleName"), topicName: getString(rawRule["TopicName"], "topicName"), @@ -56,8 +56,8 @@ export function buildRule(rawRule: any): RuleDetails { * or undefined if not passed in. * @param value */ -function getTopicFilter(value: any): SqlFilter | CorrelationFilter { - let result: SqlFilter | CorrelationFilter; +function getTopicFilter(value: any): SqlRuleFilter | CorrelationRuleFilter { + let result: SqlRuleFilter | CorrelationRuleFilter; if (value["SqlExpression"] != undefined) { result = { @@ -107,12 +107,12 @@ function getRuleActionOrUndefined(value: any): SqlAction | undefined { */ export interface RuleOptions { /** - * Defines the filter expression that the rule evaluates. For `SqlFilter` input, + * Defines the filter expression that the rule evaluates. For `SqlRuleFilter` input, * the expression string is interpreted as a SQL92 expression which must - * evaluate to True or False. Only one between a `CorrelationFilter` or - * a `SqlFilter` can be defined. + * evaluate to True or False. Only one between a `CorrelationRuleFilter` or + * a `SqlRuleFilter` can be defined. */ - filter?: SqlFilter | CorrelationFilter; + filter?: SqlRuleFilter | CorrelationRuleFilter; /** * The SQL like expression that can be executed on the message should the @@ -138,7 +138,7 @@ export interface InternalRuleOptions extends RuleOptions { /** * Represents all attributes of a rule entity */ -export interface RuleDetails { +export interface RuleDescription { /** * @internal * @ignore @@ -149,12 +149,12 @@ export interface RuleDetails { /** * @internal * @ignore - * Defines the filter expression that the rule evaluates. For `SqlFilter` input, + * Defines the filter expression that the rule evaluates. For `SqlRuleFilter` input, * the expression string is interpreted as a SQL92 expression which must - * evaluate to True or False. Only one between a `CorrelationFilter` or - * a `SqlFilter` can be defined. + * evaluate to True or False. Only one between a `CorrelationRuleFilter` or + * a `SqlRuleFilter` can be defined. */ - filter?: SqlFilter | CorrelationFilter; + filter?: SqlRuleFilter | CorrelationRuleFilter; /** * @internal @@ -189,12 +189,12 @@ export interface RuleDetails { /** * Represents all possible fields on SqlAction */ -export type SqlAction = SqlFilter; +export type SqlAction = SqlRuleFilter; /** - * Represents all possible fields on SqlFilter + * Represents all possible fields on SqlRuleFilter */ -export interface SqlFilter { +export interface SqlRuleFilter { /** * @internal * @ignore @@ -249,7 +249,7 @@ export class RuleResourceSerializer implements AtomXmlSerializer { }; } else { if (rule.filter.hasOwnProperty("sqlExpression")) { - const sqlFilter: SqlFilter = rule.filter as SqlFilter; + const sqlFilter: SqlRuleFilter = rule.filter as SqlRuleFilter; resource.Filter = { SqlExpression: sqlFilter.sqlExpression, Parameters: getRawSqlParameters(sqlFilter.sqlParameters), @@ -261,7 +261,7 @@ export class RuleResourceSerializer implements AtomXmlSerializer { "xmlns:p4": "http://www.w3.org/2001/XMLSchema-instance" }; } else { - const correlationFilter: CorrelationFilter = rule.filter as CorrelationFilter; + const correlationFilter: CorrelationRuleFilter = rule.filter as CorrelationRuleFilter; resource.Filter = { CorrelationId: correlationFilter.correlationId, diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 51fc8e519f7e..5abb5d1ade88 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -59,7 +59,7 @@ import { InternalRuleOptions, RuleOptions, buildRuleOptions, - RuleDetails, + RuleDescription, buildRule } from "./serializers/ruleResourceSerializer"; import { isJSONLikeObject, isAbsoluteUrl } from "./util/utils"; @@ -292,7 +292,7 @@ export interface ListSubscriptionsResponse extends Array { /** * Represents result of create, get, update and delete operations on rule. */ -export interface RuleResponse extends RuleDetails { +export interface RuleResponse extends RuleDescription { /** * The underlying HTTP response. */ @@ -302,7 +302,7 @@ export interface RuleResponse extends RuleDetails { /** * Create Rule response */ -export interface CreateRuleResponse extends RuleDetails { +export interface CreateRuleResponse extends RuleDescription { /** * The underlying HTTP response. */ @@ -312,7 +312,7 @@ export interface CreateRuleResponse extends RuleDetails { /** * Get Rule response */ -export interface GetRuleResponse extends RuleDetails { +export interface GetRuleResponse extends RuleDescription { /** * The underlying HTTP response. */ @@ -322,7 +322,7 @@ export interface GetRuleResponse extends RuleDetails { /** * Update Rule response */ -export interface UpdateRuleResponse extends RuleDetails { +export interface UpdateRuleResponse extends RuleDescription { /** * The underlying HTTP response. */ @@ -342,7 +342,7 @@ export interface DeleteRuleResponse { /** * Represents result of list operation on rules. */ -export interface ListRulesResponse extends Array { +export interface ListRulesResponse extends Array { /** * The underlying HTTP response. */ @@ -1146,7 +1146,7 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async getRuleDetails( + async getRuleDescription( topicName: string, subscriptioName: string, ruleName: string @@ -1614,7 +1614,7 @@ export class ServiceBusManagementClient extends ServiceClient { private buildListRulesResponse(response: HttpOperationResponse): ListRulesResponse { try { - const rules: RuleDetails[] = []; + const rules: RuleDescription[] = []; if (!Array.isArray(response.parsedBody)) { throw new TypeError(`${response.parsedBody} was expected to be of type Array`); } diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index a7f5fe8a101c..6b501cec3f99 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -2041,7 +2041,7 @@ async function getEntity( "TestError: Topic path AND subscription path must be passed when invoking tests on rules" ); } - const ruleResponse = await serviceBusAtomManagementClient.getRuleDetails( + const ruleResponse = await serviceBusAtomManagementClient.getRuleDescription( topicPath, subscriptionPath, entityPath From 988eb84a839d560005955ecd3e1bfe052c7f5a02 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 11:18:16 -0700 Subject: [PATCH 16/61] fix test failures --- .../src/serviceBusAtomManagementClient.ts | 10 +++++-- sdk/servicebus/service-bus/src/util/utils.ts | 19 +++++++++++++ .../service-bus/test/atomManagement.spec.ts | 28 +------------------ 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 5abb5d1ade88..d38064d83250 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -62,7 +62,7 @@ import { RuleDescription, buildRule } from "./serializers/ruleResourceSerializer"; -import { isJSONLikeObject, isAbsoluteUrl } from "./util/utils"; +import { isJSONLikeObject, isAbsoluteUrl, areOptionsUndefined } from "./util/utils"; /** * Options to use with ServiceBusManagementClient creation @@ -675,7 +675,13 @@ export class ServiceBusManagementClient extends ServiceClient { if (!isJSONLikeObject(queueNameOrOptions) || queueNameOrOptions === null) { throw new TypeError( - `Parameter "queue" must be an object of type "QueueOptions" and cannot be undefined or null.` + `Parameter "queue" must be an object of type "QueueDescription" and cannot be undefined or null.` + ); + } + + if (areOptionsUndefined(queueNameOrOptions, "queueName")) { + throw new TypeError( + `Parameter "queue" must be an object of type "QueueDescription" and at least one of the parameters other than queueName must be defined.` ); } diff --git a/sdk/servicebus/service-bus/src/util/utils.ts b/sdk/servicebus/service-bus/src/util/utils.ts index 15cb8c1de73b..65a065dcfabb 100644 --- a/sdk/servicebus/service-bus/src/util/utils.ts +++ b/sdk/servicebus/service-bus/src/util/utils.ts @@ -287,6 +287,25 @@ export function isJSONLikeObject(value: any): boolean { return typeof value === "object" && !(value instanceof Number) && !(value instanceof String); } +/** + * Helper method for the update APIs to verify if all the options passed in are undefined. + * + * @export + * @param {*} options + * @param {("queueName" | "topicName" | "subscriptionName")} name + * @returns + */ +export function areOptionsUndefined( + options: any, + name: "queueName" | "topicName" | "subscriptionName" +) { + for (const [key, value] of Object.entries(options)) { + if (key != name && value != undefined) { + return false; + } + } + return true; +} /** * @internal * @ignore diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 6b501cec3f99..c3089e668f7b 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -948,26 +948,19 @@ const newManagementEntity2 = EntityNames.MANAGEMENT_NEW_ENTITY_2; output: { authorizationRules: undefined, autoDeleteOnIdle: "P10675199DT2H48M5.4775807S", - messageCountDetails: undefined, deadLetteringOnMessageExpiration: false, defaultMessageTtl: "P10675199DT2H48M5.4775807S", duplicateDetectionHistoryTimeWindow: "PT10M", enableBatchedOperations: true, - enableExpress: false, enablePartitioning: false, - entityAvailabilityStatus: "Available", forwardDeadLetteredMessagesTo: undefined, - isAnonymousAccessible: false, lockDuration: "PT1M", maxDeliveryCount: 10, maxSizeInMegabytes: 1024, - messageCount: 0, queueName: managementQueue1, requiresDuplicateDetection: false, requiresSession: false, - sizeInBytes: 0, status: "Active", - supportOrdering: true, forwardTo: undefined, userMetadata: undefined } @@ -1013,8 +1006,6 @@ const newManagementEntity2 = EntityNames.MANAGEMENT_NEW_ENTITY_2; output: { duplicateDetectionHistoryTimeWindow: "PT1M", lockDuration: "PT45S", - messageCount: 0, - sizeInBytes: 0, defaultMessageTtl: "P2D", deadLetteringOnMessageExpiration: true, enableBatchedOperations: false, @@ -1047,16 +1038,11 @@ const newManagementEntity2 = EntityNames.MANAGEMENT_NEW_ENTITY_2; enablePartitioning: true, maxSizeInMegabytes: 16384, - supportOrdering: false, forwardDeadLetteredMessagesTo: undefined, forwardTo: undefined, userMetadata: "test metadata", - messageCountDetails: undefined, - enableExpress: false, - entityAvailabilityStatus: "Available", - isAnonymousAccessible: false, status: "ReceiveDisabled", queueName: managementQueue1 } @@ -1273,7 +1259,7 @@ const newManagementEntity2 = EntityNames.MANAGEMENT_NEW_ENTITY_2; testCaseTitle: "Undefined queue options", input: undefined, output: { - testErrorMessage: `Parameter "queueOptions" must be an object of type "QueueOptions" and cannot be undefined or null.` + testErrorMessage: `Parameter "queue" must be an object of type "QueueDescription" and at least one of the parameters other than queueName must be defined.` } }, { @@ -1315,12 +1301,9 @@ const newManagementEntity2 = EntityNames.MANAGEMENT_NEW_ENTITY_2; output: { duplicateDetectionHistoryTimeWindow: "PT2M", lockDuration: "PT50S", - messageCount: undefined, - sizeInBytes: undefined, defaultMessageTtl: "P1D", deadLetteringOnMessageExpiration: true, enableBatchedOperations: false, - requiresDuplicateDetection: true, requiresSession: true, authorizationRules: [ @@ -1345,21 +1328,12 @@ const newManagementEntity2 = EntityNames.MANAGEMENT_NEW_ENTITY_2; secondaryKey: "UreXLPWiP6Murmsq2HYiIXs23qAvWa36ZOL3gb9rXLs=" } ], - maxDeliveryCount: 5, maxSizeInMegabytes: 16384, - autoDeleteOnIdle: "PT2H", forwardDeadLetteredMessagesTo: undefined, forwardTo: undefined, userMetadata: "test metadata", - - messageCountDetails: undefined, - - enableExpress: undefined, - entityAvailabilityStatus: undefined, - isAnonymousAccessible: undefined, - supportOrdering: undefined, status: "ReceiveDisabled", enablePartitioning: true, queueName: managementQueue1 From b1766b24a36e162c12eeea93294bc2748847cad3 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 12:05:08 -0700 Subject: [PATCH 17/61] changes to Topic APIs --- .../serializers/topicResourceSerializer.ts | 174 ++-------- .../src/serviceBusAtomManagementClient.ts | 299 ++++++++++++------ .../service-bus/test/atomManagement.spec.ts | 18 +- .../service-bus/test/atomXml.spec.ts | 2 +- 4 files changed, 245 insertions(+), 248 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serializers/topicResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/topicResourceSerializer.ts index abbcba2d31d2..2229b9cd8ab0 100644 --- a/sdk/servicebus/service-bus/src/serializers/topicResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/topicResourceSerializer.ts @@ -11,15 +11,12 @@ import { import { getStringOrUndefined, getIntegerOrUndefined, - getCountDetailsOrUndefined, - MessageCountDetails, getRawAuthorizationRules, getAuthorizationRulesOrUndefined, AuthorizationRule, getString, getInteger, getBoolean, - getBooleanOrUndefined, EntityStatus } from "../util/utils"; @@ -31,7 +28,7 @@ import { * converts values to string and ensures the right order as expected by the service * @param topicOptions */ -export function buildTopicOptions(topicOptions: TopicOptions): InternalTopicOptions { +export function buildTopicOptions(topicOptions: TopicDescription): InternalTopicOptions { return { DefaultMessageTimeToLive: topicOptions.defaultMessageTtl, MaxSizeInMegabytes: getStringOrUndefined(topicOptions.maxSizeInMegabytes), @@ -54,14 +51,10 @@ export function buildTopicOptions(topicOptions: TopicOptions): InternalTopicOpti * response from the service * @param rawTopic */ -export function buildTopic(rawTopic: any): TopicDetails { +export function buildTopic(rawTopic: any): TopicDescription { return { topicName: getString(rawTopic[Constants.TOPIC_NAME], "topicName"), - sizeInBytes: getIntegerOrUndefined(rawTopic[Constants.SIZE_IN_BYTES]), maxSizeInMegabytes: getInteger(rawTopic[Constants.MAX_SIZE_IN_MEGABYTES], "maxSizeInMegabytes"), - messageCount: getIntegerOrUndefined(rawTopic[Constants.MESSAGE_COUNT]), - maxDeliveryCount: getIntegerOrUndefined(rawTopic[Constants.MAX_DELIVERY_COUNT]), - subscriptionCount: getIntegerOrUndefined(rawTopic[Constants.SUBSCRIPTION_COUNT]), enablePartitioning: getBoolean(rawTopic[Constants.ENABLE_PARTITIONING], "enablePartitioning"), supportOrdering: getBoolean(rawTopic[Constants.SUPPORT_ORDERING], "supportOrdering"), @@ -85,23 +78,25 @@ export function buildTopic(rawTopic: any): TopicDetails { "duplicateDetectionHistoryTimeWindow" ), - filteringMessagesBeforePublishing: getBooleanOrUndefined( - rawTopic[Constants.FILTER_MESSAGES_BEFORE_PUBLISHING] - ), - enableSubscriptionPartitioning: getBooleanOrUndefined( - rawTopic[Constants.ENABLE_SUBSCRIPTION_PARTITIONING] - ), - - messageCountDetails: getCountDetailsOrUndefined(rawTopic[Constants.COUNT_DETAILS]), - isExpress: getBooleanOrUndefined(rawTopic[Constants.IS_EXPRESS]), - enableExpress: getBooleanOrUndefined(rawTopic[Constants.ENABLE_EXPRESS]), - authorizationRules: getAuthorizationRulesOrUndefined(rawTopic[Constants.AUTHORIZATION_RULES]), - isAnonymousAccessible: getBooleanOrUndefined(rawTopic[Constants.IS_ANONYMOUS_ACCESSIBLE]), userMetadata: rawTopic[Constants.USER_METADATA], - entityAvailabilityStatus: rawTopic[Constants.ENTITY_AVAILABILITY_STATUS], - status: rawTopic[Constants.STATUS], + status: rawTopic[Constants.STATUS] + }; +} + +/** + * @internal + * @ignore + * Builds the topic object from the raw json object gotten after deserializing the + * response from the service + * @param rawTopic + */ +export function buildTopicRuntimeInfo(rawTopic: any): TopicRuntimeInfo { + return { + topicName: getString(rawTopic[Constants.TOPIC_NAME], "topicName"), + sizeInBytes: getIntegerOrUndefined(rawTopic[Constants.SIZE_IN_BYTES]), + subscriptionCount: getIntegerOrUndefined(rawTopic[Constants.SUBSCRIPTION_COUNT]), createdOn: rawTopic[Constants.CREATED_AT], updatedOn: rawTopic[Constants.UPDATED_AT], accessedOn: rawTopic[Constants.ACCESSED_AT] @@ -111,7 +106,12 @@ export function buildTopic(rawTopic: any): TopicDetails { /** * Represents settable options on a topic */ -export interface TopicOptions { +export interface TopicDescription { + /** + * Name of the topic + */ + topicName: string; + /** * Determines how long a message lives in the associated subscriptions. * Subscriptions inherit the TTL from the topic unless they are created explicitly @@ -270,9 +270,9 @@ export interface InternalTopicOptions { } /** - * Represents all attributes of a topic entity + * Represents runtime info attributes of a topic entity */ -export interface TopicDetails { +export interface TopicRuntimeInfo { /** * Name of the topic */ @@ -283,134 +283,12 @@ export interface TopicDetails { */ sizeInBytes?: number; - /** - * Specifies the maximum topic size in megabytes. Any attempt to enqueue a message - * that will cause the topic to exceed this value will fail. All messages that are - * stored in the topic or any of its subscriptions count towards this value. - * Multiple copies of a message that reside in one or multiple subscriptions - * count as a single messages. For example, if message m exists once in subscription - * s1 and twice in subscription s2, m is counted as a single message. - */ - maxSizeInMegabytes: number; - - /** - * If enabled, the topic will detect duplicate messages within the time span specified - * by the DuplicateDetectionHistoryTimeWindow property. - * Settable only at topic creation time. - */ - requiresDuplicateDetection: boolean; - - /** - * Enable Subscription Partitioning option - */ - enableSubscriptionPartitioning?: boolean; - - /** - * Filtering Messages Before Publishing option - */ - filteringMessagesBeforePublishing?: boolean; - - /** - * Authorization rules on the topic - */ - authorizationRules?: AuthorizationRule[]; - - /** - * Specifies whether the topic should be partitioned - */ - enablePartitioning: boolean; - - /** - * Specifies whether the topic supports message ordering. - */ - supportOrdering: boolean; - - /** - * Specifies if batched operations should be allowed. - */ - enableBatchedOperations: boolean; - - /** - * Max idle time before entity is deleted. - * This is to be specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - autoDeleteOnIdle?: string; - - /** - * The entity's message count. - * - */ - messageCount?: number; - /** * The subscription count on given topic. * */ subscriptionCount?: number; - /** - * The maximum delivery count of messages after which if it is still not settled, - * gets moved to the dead-letter sub-queue. - * - */ - maxDeliveryCount?: number; - - /** - * Determines how long a message lives in the associated subscriptions. - * Subscriptions inherit the TTL from the topic unless they are created explicitly with - * a smaller TTL. Based on whether dead-lettering is enabled, a message whose TTL has - * expired will either be moved to the subscription’s associated dead-letter sub-queue or - * will be permanently deleted. - * This is to be specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - defaultMessageTtl: string; - - /** - * Specifies the time span during which the Service Bus will detect message duplication. - * This is to be specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - duplicateDetectionHistoryTimeWindow: string; - - /** - * The user provided metadata information associated with the topic description. - * Used to specify textual content such as tags, labels, etc. - * Value must not exceed 1024 bytes encoded in utf-8. - */ - userMetadata?: string; - - /** - * Is Express option - */ - isExpress?: boolean; - - /** - * Enable express option - */ - enableExpress?: boolean; - - /** - * Message count details - */ - messageCountDetails?: MessageCountDetails; - - /** - * Is anonymous accessible topic option - */ - isAnonymousAccessible?: boolean; - - /** - * Entity availability status - */ - entityAvailabilityStatus?: string; - - /** - * Status of the messaging entity. - */ - status?: EntityStatus; - /** * Created at timestamp */ diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index d38064d83250..3cae3aedd57c 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -41,10 +41,11 @@ import { import { TopicResourceSerializer, InternalTopicOptions, - TopicOptions, + TopicRuntimeInfo, buildTopicOptions, - TopicDetails, - buildTopic + TopicDescription, + buildTopic, + buildTopicRuntimeInfo } from "./serializers/topicResourceSerializer"; import { SubscriptionResourceSerializer, @@ -172,7 +173,27 @@ export interface GetQueuesResponse extends Array { /** * Represents result of create, get, update and delete operations on topic. */ -export interface TopicResponse extends TopicDetails { +export interface GetTopicRuntimeInfoResponse extends TopicRuntimeInfo { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + +/** + * Represents result of create, get, update and delete operations on topic. + */ +export interface GetTopicsRuntimeInfoResponse extends Array { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + +/** + * Represents result of create, get, update and delete operations on topic. + */ +export interface TopicResponse extends TopicDescription { /** * The underlying HTTP response. */ @@ -182,7 +203,7 @@ export interface TopicResponse extends TopicDetails { /** * Create Topic response */ -export interface CreateTopicResponse extends TopicDetails { +export interface CreateTopicResponse extends TopicDescription { /** * The underlying HTTP response. */ @@ -192,7 +213,7 @@ export interface CreateTopicResponse extends TopicDetails { /** * Get Topic response */ -export interface GetTopicResponse extends TopicDetails { +export interface GetTopicResponse extends TopicDescription { /** * The underlying HTTP response. */ @@ -202,7 +223,7 @@ export interface GetTopicResponse extends TopicDetails { /** * Update Topic response */ -export interface UpdateTopicResponse extends TopicDetails { +export interface UpdateTopicResponse extends TopicDescription { /** * The underlying HTTP response. */ @@ -222,7 +243,7 @@ export interface DeleteTopicResponse { /** * Represents result of list operation on topics. */ -export interface ListTopicsResponse extends Array { +export interface GetTopicsResponse extends Array { /** * The underlying HTTP response. */ @@ -619,21 +640,6 @@ export class ServiceBusManagementClient extends ServiceClient { return this.buildListQueuesRuntimeInfoResponse(response); } - /** - * Updates properties on the Queue by the given name based on the given options - * @param queueName - * - * Following are errors that can be expected from this operation - * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, - * @throws `RestError` with code `MessageEntityNotFoundError` when requested messaging entity does not exist, - * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, - * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, - * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as - * bad requests or requests resulting in conflicting operation on the server, - * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at - * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 - */ - async updateQueue(queueName: string): Promise; /** * Updates properties on the Queue by the given name based on the given options * @param queue Options to configure the Queue being updated. @@ -649,55 +655,35 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async updateQueue(queue: QueueDescription): Promise; - async updateQueue(queueNameOrOptions: string | QueueDescription): Promise { - if (typeof queueNameOrOptions == "string") { - log.httpAtomXml( - `Performing management operation - updateQueue() for "${queueNameOrOptions}"` - ); - - const finalQueueOptions: QueueDescription = { queueName: queueNameOrOptions }; - const getQueueResult = await this.getQueue(queueNameOrOptions); - Object.assign(finalQueueOptions, getQueueResult); + async updateQueue(queue: QueueDescription): Promise { + log.httpAtomXml( + `Performing management operation - updateQueue() for "${queue.queueName}" with options: ${queue}` + ); - const response: HttpOperationResponse = await this.putResource( - queueNameOrOptions, - buildQueueOptions(finalQueueOptions), - this.queueResourceSerializer, - true + if (!isJSONLikeObject(queue) || queue === null) { + throw new TypeError( + `Parameter "queue" must be an object of type "QueueDescription" and cannot be undefined or null.` ); + } - return this.buildQueueResponse(response); - } else { - log.httpAtomXml( - `Performing management operation - updateQueue() for "${queueNameOrOptions.queueName}" with options: ${queueNameOrOptions}` + if (areOptionsUndefined(queue, "queueName")) { + throw new TypeError( + `Parameter "queue" must be an object of type "QueueDescription" and at least one of the parameters other than queueName must be defined.` ); + } - if (!isJSONLikeObject(queueNameOrOptions) || queueNameOrOptions === null) { - throw new TypeError( - `Parameter "queue" must be an object of type "QueueDescription" and cannot be undefined or null.` - ); - } - - if (areOptionsUndefined(queueNameOrOptions, "queueName")) { - throw new TypeError( - `Parameter "queue" must be an object of type "QueueDescription" and at least one of the parameters other than queueName must be defined.` - ); - } - - const finalQueueOptions: QueueDescription = { queueName: queueNameOrOptions.queueName }; - const getQueueResult = await this.getQueue(queueNameOrOptions.queueName); - Object.assign(finalQueueOptions, getQueueResult, queueNameOrOptions); + const finalQueueOptions: QueueDescription = { queueName: queue.queueName }; + const getQueueResult = await this.getQueue(queue.queueName); + Object.assign(finalQueueOptions, getQueueResult, queue); - const response: HttpOperationResponse = await this.putResource( - queueNameOrOptions.queueName, - buildQueueOptions(finalQueueOptions), - this.queueResourceSerializer, - true - ); + const response: HttpOperationResponse = await this.putResource( + queue.queueName, + buildQueueOptions(finalQueueOptions), + this.queueResourceSerializer, + true + ); - return this.buildQueueResponse(response); - } + return this.buildQueueResponse(response); } /** @@ -743,7 +729,22 @@ export class ServiceBusManagementClient extends ServiceClient { /** * Creates a topic with given name, configured using the given options * @param topicName - * @param topicOptions Options to configure the Topic being created. + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityAlreadyExistsError` when requested messaging entity already exists, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `QuotaExceededError` when requested operation fails due to quote limits exceeding from service side, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async createTopic(topicName: string): Promise; + /** + * Creates a topic with given name, configured using the given options + * @param topic Options to configure the Topic being created. * For example, you can configure a topic to support partitions or sessions. * * Following are errors that can be expected from this operation @@ -757,15 +758,54 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async createTopic(topicName: string, topicOptions?: TopicOptions): Promise { - log.httpAtomXml( - `Performing management operation - createTopic() for "${topicName}" with options: ${topicOptions}` - ); - const response: HttpOperationResponse = await this.putResource( + async createTopic(topicOptions: TopicDescription): Promise; + async createTopic(topicNameOrOptions: string | TopicDescription): Promise { + if (typeof topicNameOrOptions == "string") { + log.httpAtomXml( + `Performing management operation - createTopic() for "${topicNameOrOptions}"` + ); + const response: HttpOperationResponse = await this.putResource( + topicNameOrOptions, + buildTopicOptions({ topicName: topicNameOrOptions }), + this.topicResourceSerializer, + false + ); + + return this.buildTopicResponse(response); + } else { + log.httpAtomXml( + `Performing management operation - createTopic() for "${topicNameOrOptions.topicName}" with options: ${topicNameOrOptions}` + ); + const response: HttpOperationResponse = await this.putResource( + topicNameOrOptions.topicName, + buildTopicOptions(topicNameOrOptions || {}), + this.topicResourceSerializer, + false + ); + + return this.buildTopicResponse(response); + } + } + + /** + * Returns an object representing the Topic with the given name along with all its properties + * @param topicName + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityNotFoundError` when requested messaging entity does not exist, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async getTopic(topicName: string): Promise { + log.httpAtomXml(`Performing management operation - getTopic() for "${topicName}"`); + const response: HttpOperationResponse = await this.getResource( topicName, - buildTopicOptions(topicOptions || {}), - this.topicResourceSerializer, - false + this.topicResourceSerializer ); return this.buildTopicResponse(response); @@ -785,14 +825,14 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async getTopicDetails(topicName: string): Promise { + async getTopicRuntimeInfo(topicName: string): Promise { log.httpAtomXml(`Performing management operation - getTopic() for "${topicName}"`); const response: HttpOperationResponse = await this.getResource( topicName, this.topicResourceSerializer ); - return this.buildTopicResponse(response); + return this.buildTopicRuntimeInfoResponse(response); } /** @@ -808,7 +848,7 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async listTopics(listRequestOptions?: ListRequestOptions): Promise { + async getTopics(listRequestOptions?: ListRequestOptions): Promise { log.httpAtomXml( `Performing management operation - listTopics() with options: ${listRequestOptions}` ); @@ -821,10 +861,37 @@ export class ServiceBusManagementClient extends ServiceClient { return this.buildListTopicsResponse(response); } + /** + * Lists existing topics. + * @param listRequestOptions + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async getTopicsRuntimeInfo( + listRequestOptions?: ListRequestOptions + ): Promise { + log.httpAtomXml( + `Performing management operation - listTopics() with options: ${listRequestOptions}` + ); + const response: HttpOperationResponse = await this.listResources( + "$Resources/Topics", + listRequestOptions, + this.topicResourceSerializer + ); + + return this.buildListTopicsRuntimeInfoResponse(response); + } + /** * Updates properties on the Topic by the given name based on the given options - * @param topicName - * @param topicOptions Options to configure the Topic being updated. + * @param topic Options to configure the Topic being updated. * For example, you can configure a topic to support partitions or sessions. * * Following are errors that can be expected from this operation @@ -837,23 +904,23 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async updateTopic(topicName: string, topicOptions: TopicOptions): Promise { + async updateTopic(topic: TopicDescription): Promise { log.httpAtomXml( - `Performing management operation - updateTopic() for "${topicName}" with options: ${topicOptions}` + `Performing management operation - updateTopic() for "${topic.topicName}" with options: ${topic}` ); - if (!isJSONLikeObject(topicOptions) || topicOptions === null) { + if (!isJSONLikeObject(topic) || topic === null) { throw new TypeError( `Parameter "topicOptions" must be an object of type "TopicOptions" and cannot be undefined or null.` ); } - const finalTopicOptions: TopicOptions = {}; - const getTopicResult = await this.getTopicDetails(topicName); - Object.assign(finalTopicOptions, getTopicResult, topicOptions); + const finalTopicOptions: TopicDescription = { topicName: topic.topicName }; + const getTopicResult = await this.getTopic(topic.topicName); + Object.assign(finalTopicOptions, getTopicResult, topic); const response: HttpOperationResponse = await this.putResource( - topicName, + topic.topicName, buildTopicOptions(finalTopicOptions), this.topicResourceSerializer, true @@ -893,7 +960,7 @@ export class ServiceBusManagementClient extends ServiceClient { async topicExists(topicName: string): Promise { log.httpAtomXml(`Performing management operation - topicExists() for "${topicName}"`); try { - await this.getTopicDetails(topicName); + await this.getTopic(topicName); } catch (error) { if (error.code == "MessageEntityNotFoundError") { return false; @@ -1520,9 +1587,40 @@ export class ServiceBusManagementClient extends ServiceClient { } } - private buildListTopicsResponse(response: HttpOperationResponse): ListTopicsResponse { + private buildListTopicsResponse(response: HttpOperationResponse): GetTopicsResponse { + try { + const topics: TopicDescription[] = []; + if (!Array.isArray(response.parsedBody)) { + throw new TypeError(`${response.parsedBody} was expected to be of type Array`); + } + const rawTopicArray: any = response.parsedBody; + for (let i = 0; i < rawTopicArray.length; i++) { + const topic = buildTopic(rawTopicArray[i]); + if (topic) { + topics.push(topic); + } + } + const listTopicsResponse: GetTopicsResponse = Object.assign(topics, { + _response: response + }); + return listTopicsResponse; + } catch (err) { + log.warning("Failure parsing response from service - %0 ", err); + throw new RestError( + `Error occurred while parsing the response body - cannot form a list of topics using the response from the service.`, + RestError.PARSE_ERROR, + response.status, + stripRequest(response.request), + stripResponse(response) + ); + } + } + + private buildListTopicsRuntimeInfoResponse( + response: HttpOperationResponse + ): GetTopicsRuntimeInfoResponse { try { - const topics: TopicDetails[] = []; + const topics: TopicRuntimeInfo[] = []; if (!Array.isArray(response.parsedBody)) { throw new TypeError(`${response.parsedBody} was expected to be of type Array`); } @@ -1533,7 +1631,7 @@ export class ServiceBusManagementClient extends ServiceClient { topics.push(topic); } } - const listTopicsResponse: ListTopicsResponse = Object.assign(topics, { + const listTopicsResponse: GetTopicsRuntimeInfoResponse = Object.assign(topics, { _response: response }); return listTopicsResponse; @@ -1568,6 +1666,27 @@ export class ServiceBusManagementClient extends ServiceClient { } } + private buildTopicRuntimeInfoResponse( + response: HttpOperationResponse + ): GetTopicRuntimeInfoResponse { + try { + const topic = buildTopicRuntimeInfo(response.parsedBody); + const topicResponse: GetTopicRuntimeInfoResponse = Object.assign(topic || {}, { + _response: response + }); + return topicResponse; + } catch (err) { + log.warning("Failure parsing response from service - %0 ", err); + throw new RestError( + `Error occurred while parsing the response body - cannot form a topic object using the response from the service.`, + RestError.PARSE_ERROR, + response.status, + stripRequest(response.request), + stripResponse(response) + ); + } + } + private buildListSubscriptionsResponse( response: HttpOperationResponse ): ListSubscriptionsResponse { diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index c3089e668f7b..af29eacfb128 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. import { QueueDescription } from "../src/serializers/queueResourceSerializer"; -import { TopicOptions } from "../src/serializers/topicResourceSerializer"; +import { TopicDescription } from "../src/serializers/topicResourceSerializer"; import { SubscriptionOptions } from "../src/serializers/subscriptionResourceSerializer"; import { RuleOptions } from "../src/serializers/ruleResourceSerializer"; import { EntityStatus } from "../src/util/utils"; @@ -1894,7 +1894,7 @@ async function createEntity( subscriptionPath?: string, overrideOptions?: boolean, // If this is false, then the default options will be populated as used for basic testing. queueOptions?: Omit, - topicOptions?: TopicOptions, + topicOptions?: Omit, subscriptionOptions?: SubscriptionOptions, ruleOptions?: RuleOptions ): Promise { @@ -1951,10 +1951,10 @@ async function createEntity( }); return queueResponse; case EntityType.TOPIC: - const topicResponse = await serviceBusAtomManagementClient.createTopic( - entityPath, - topicOptions - ); + const topicResponse = await serviceBusAtomManagementClient.createTopic({ + topicName: entityPath, + ...topicOptions + }); return topicResponse; case EntityType.SUBSCRIPTION: if (!topicPath) { @@ -1996,7 +1996,7 @@ async function getEntity( const queueResponse = await serviceBusAtomManagementClient.getQueue(entityPath); return queueResponse; case EntityType.TOPIC: - const topicResponse = await serviceBusAtomManagementClient.getTopicDetails(entityPath); + const topicResponse = await serviceBusAtomManagementClient.getTopic(entityPath); return topicResponse; case EntityType.SUBSCRIPTION: if (!topicPath) { @@ -2032,7 +2032,7 @@ async function updateEntity( subscriptionPath?: string, overrideOptions?: boolean, // If this is false, then the default options will be populated as used for basic testing. queueOptions?: Omit, - topicOptions?: TopicOptions, + topicOptions?: Omit, subscriptionOptions?: SubscriptionOptions, ruleOptions?: RuleOptions ): Promise { @@ -2181,7 +2181,7 @@ async function listEntities( }); return queueResponse; case EntityType.TOPIC: - const topicResponse = await serviceBusAtomManagementClient.listTopics({ + const topicResponse = await serviceBusAtomManagementClient.getTopics({ skip: skip, top: top }); diff --git a/sdk/servicebus/service-bus/test/atomXml.spec.ts b/sdk/servicebus/service-bus/test/atomXml.spec.ts index 8b5f207a47f7..4b439e896b57 100644 --- a/sdk/servicebus/service-bus/test/atomXml.spec.ts +++ b/sdk/servicebus/service-bus/test/atomXml.spec.ts @@ -954,7 +954,7 @@ describe(`Parse empty response for list() requests to return as empty array`, fu headers: new HttpHeaders({}) }; }; - const result = await mockServiceBusAtomManagementClient.listTopics(); + const result = await mockServiceBusAtomManagementClient.getTopics(); assertEmptyArray(result); }); From 07f0a2d13368e1637d8b81c0a7aa1ca984ad3dc0 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 12:12:38 -0700 Subject: [PATCH 18/61] fix build failures --- sdk/servicebus/service-bus/src/index.ts | 4 ++-- .../service-bus/test/utils/managementUtils.ts | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index 8d6a986c6990..212877e41338 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -46,7 +46,7 @@ export { Sender } from "./sender"; export { ServiceBusClient } from "./serviceBusClient"; export { QueueDescription, QueueRuntimeInfo } from "./serializers/queueResourceSerializer"; -export { TopicOptions, TopicDetails } from "./serializers/topicResourceSerializer"; +export { TopicDescription, TopicRuntimeInfo } from "./serializers/topicResourceSerializer"; export { SubscriptionOptions, SubscriptionDetails @@ -79,7 +79,7 @@ export { GetTopicResponse, ListRulesResponse, ListSubscriptionsResponse, - ListTopicsResponse, + GetTopicsResponse, UpdateQueueResponse, UpdateRuleResponse, UpdateSubscriptionResponse, diff --git a/sdk/servicebus/service-bus/test/utils/managementUtils.ts b/sdk/servicebus/service-bus/test/utils/managementUtils.ts index 98047068d1da..74d1f4ed1c70 100644 --- a/sdk/servicebus/service-bus/test/utils/managementUtils.ts +++ b/sdk/servicebus/service-bus/test/utils/managementUtils.ts @@ -3,7 +3,7 @@ import { delay } from "../../src"; import { QueueDescription } from "../../src/serializers/queueResourceSerializer"; -import { TopicOptions } from "../../src/serializers/topicResourceSerializer"; +import { TopicDescription } from "../../src/serializers/topicResourceSerializer"; import { SubscriptionOptions } from "../../src/serializers/subscriptionResourceSerializer"; import { ServiceBusManagementClient } from "../../src/serviceBusAtomManagementClient"; @@ -15,7 +15,7 @@ let client: ServiceBusManagementClient; /** * Utility to fetch cached instance of `ServiceBusAtomManagementClient` else creates and returns - * a new instance constructed based on the connection string configured in environmet. + * a new instance constructed based on the connection string configured in environment. */ async function getManagementClient() { if (client == undefined) { @@ -27,7 +27,7 @@ async function getManagementClient() { /** * Utility to apply retries to a given `operationCallBack`. - * Default policy is performing linear retries of upto `5` attempts that are `1000 milliseconds` apart. + * Default policy is performing linear retries of up to `5` attempts that are `1000 milliseconds` apart. * The retries will be preempted if given `breakConditionCallback` evaluates to `true` early on. * @param operationCallback * @param breakConditionCallback @@ -114,7 +114,10 @@ export async function recreateQueue( * @param topicName * @param parameters */ -export async function recreateTopic(topicName: string, parameters?: TopicOptions): Promise { +export async function recreateTopic( + topicName: string, + parameters?: Omit +): Promise { await getManagementClient(); const deleteTopicOperation = async () => { @@ -122,12 +125,12 @@ export async function recreateTopic(topicName: string, parameters?: TopicOptions }; const createTopicOperation = async () => { - await client.createTopic(topicName, parameters); + await client.createTopic({ topicName, ...parameters }); }; const checkIfTopicExistsOperation = async () => { try { - await client.getTopicDetails(topicName); + await client.getTopic(topicName); } catch (err) { return false; } From b4546b3dad2d13bf1932cc85d045483a0c97c3eb Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 12:12:48 -0700 Subject: [PATCH 19/61] generate API report --- .../service-bus/review/service-bus.api.md | 73 ++++++++----------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 946e9a9d5e07..47b0979cd528 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -81,7 +81,7 @@ export interface CreateSubscriptionResponse extends SubscriptionDetails { } // @public -export interface CreateTopicResponse extends TopicDetails { +export interface CreateTopicResponse extends TopicDescription { _response: HttpOperationResponse; } @@ -153,7 +153,12 @@ export interface GetSubscriptionResponse extends SubscriptionDetails { } // @public -export interface GetTopicResponse extends TopicDetails { +export interface GetTopicResponse extends TopicDescription { + _response: HttpOperationResponse; +} + +// @public +export interface GetTopicsResponse extends Array { _response: HttpOperationResponse; } @@ -173,11 +178,6 @@ export interface ListSubscriptionsResponse extends Array { _response: HttpOperationResponse; } -// @public -export interface ListTopicsResponse extends Array { - _response: HttpOperationResponse; -} - // @public export type MessageCountDetails = { activeMessageCount: number; @@ -349,7 +349,8 @@ export class ServiceBusManagementClient extends ServiceClient { createQueue(queue: QueueDescription): Promise; createRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions?: RuleOptions): Promise; createSubscription(topicName: string, subscriptionName: string, subscriptionOptions?: SubscriptionOptions): Promise; - createTopic(topicName: string, topicOptions?: TopicOptions): Promise; + createTopic(topicName: string): Promise; + createTopic(topicOptions: TopicDescription): Promise; deleteQueue(queueName: string): Promise; deleteRule(topicName: string, subscriptionName: string, ruleName: string): Promise; deleteSubscription(topicName: string, subscriptionName: string): Promise; @@ -360,18 +361,21 @@ export class ServiceBusManagementClient extends ServiceClient { getQueuesRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; getRuleDescription(topicName: string, subscriptioName: string, ruleName: string): Promise; getSubscriptionDetails(topicName: string, subscriptionName: string): Promise; - getTopicDetails(topicName: string): Promise; + getTopic(topicName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetTopicRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getTopicRuntimeInfo(topicName: string): Promise; + getTopics(listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "GetTopicsRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getTopicsRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; listRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; listSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; - listTopics(listRequestOptions?: ListRequestOptions): Promise; queueExists(queueName: string): Promise; subscriptionExists(topicName: string, subscriptionName: string): Promise; topicExists(topicName: string): Promise; - updateQueue(queueName: string): Promise; updateQueue(queue: QueueDescription): Promise; updateRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions: RuleOptions): Promise; updateSubscription(topicName: string, subscriptionName: string, subscriptionOptions: SubscriptionOptions): Promise; - updateTopic(topicName: string, topicOptions: TopicOptions): Promise; + updateTopic(topic: TopicDescription): Promise; } // @public @@ -488,37 +492,7 @@ export { TokenCredential } export { TokenType } // @public -export interface TopicDetails { - accessedOn?: string; - authorizationRules?: AuthorizationRule[]; - autoDeleteOnIdle?: string; - createdOn?: string; - defaultMessageTtl: string; - duplicateDetectionHistoryTimeWindow: string; - enableBatchedOperations: boolean; - enableExpress?: boolean; - enablePartitioning: boolean; - enableSubscriptionPartitioning?: boolean; - entityAvailabilityStatus?: string; - filteringMessagesBeforePublishing?: boolean; - isAnonymousAccessible?: boolean; - isExpress?: boolean; - maxDeliveryCount?: number; - maxSizeInMegabytes: number; - messageCount?: number; - messageCountDetails?: MessageCountDetails; - requiresDuplicateDetection: boolean; - sizeInBytes?: number; - status?: EntityStatus; - subscriptionCount?: number; - supportOrdering: boolean; - topicName: string; - updatedOn?: string; - userMetadata?: string; -} - -// @public -export interface TopicOptions { +export interface TopicDescription { authorizationRules?: AuthorizationRule[]; autoDeleteOnIdle?: string; defaultMessageTtl?: string; @@ -529,9 +503,20 @@ export interface TopicOptions { requiresDuplicateDetection?: boolean; status?: EntityStatus; supportOrdering?: boolean; + topicName: string; userMetadata?: string; } +// @public +export interface TopicRuntimeInfo { + accessedOn?: string; + createdOn?: string; + sizeInBytes?: number; + subscriptionCount?: number; + topicName: string; + updatedOn?: string; +} + // @public export interface UpdateQueueResponse extends QueueDescription { _response: HttpOperationResponse; @@ -548,7 +533,7 @@ export interface UpdateSubscriptionResponse extends SubscriptionDetails { } // @public -export interface UpdateTopicResponse extends TopicDetails { +export interface UpdateTopicResponse extends TopicDescription { _response: HttpOperationResponse; } From 09a1c0464189ad096117ff9bccf95c66f26e78bc Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 12:50:40 -0700 Subject: [PATCH 20/61] subscription APIs updated --- .../subscriptionResourceSerializer.ts | 176 +++--------- .../src/serviceBusAtomManagementClient.ts | 263 +++++++++++++++--- 2 files changed, 256 insertions(+), 183 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts index 9dc660ee9a34..287826de6a21 100644 --- a/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts @@ -10,8 +10,6 @@ import { } from "../util/atomXmlHelper"; import { getStringOrUndefined, - getIntegerOrUndefined, - getBooleanOrUndefined, getCountDetailsOrUndefined, MessageCountDetails, getString, @@ -29,7 +27,7 @@ import { * @param subscriptionOptions */ export function buildSubscriptionOptions( - subscriptionOptions: SubscriptionOptions + subscriptionOptions: SubscriptionDescription ): InternalSubscriptionOptions { return { LockDuration: subscriptionOptions.lockDuration, @@ -60,19 +58,14 @@ export function buildSubscriptionOptions( * the response from the service * @param rawSubscription */ -export function buildSubscription(rawSubscription: any): SubscriptionDetails { +export function buildSubscription(rawSubscription: any): SubscriptionDescription { return { subscriptionName: getString(rawSubscription[Constants.SUBSCRIPTION_NAME], "subscriptionName"), topicName: getString(rawSubscription[Constants.TOPIC_NAME], "topicName"), lockDuration: getString(rawSubscription[Constants.LOCK_DURATION], "lockDuration"), - sizeInBytes: getIntegerOrUndefined(rawSubscription[Constants.SIZE_IN_BYTES]), - maxSizeInMegabytes: getIntegerOrUndefined(rawSubscription[Constants.MAX_SIZE_IN_MEGABYTES]), - - messageCount: getInteger(rawSubscription[Constants.MESSAGE_COUNT], "messageCount"), maxDeliveryCount: getInteger(rawSubscription[Constants.MAX_DELIVERY_COUNT], "maxDeliveryCount"), - enablePartitioning: getBooleanOrUndefined(rawSubscription[Constants.ENABLE_PARTITIONING]), requiresSession: getBoolean(rawSubscription[Constants.REQUIRES_SESSION], "requiresSession"), enableBatchedOperations: getBoolean( rawSubscription[Constants.ENABLE_BATCHED_OPERATIONS], @@ -96,18 +89,27 @@ export function buildSubscription(rawSubscription: any): SubscriptionDetails { forwardDeadLetteredMessagesTo: getStringOrUndefined( rawSubscription[Constants.FORWARD_DEADLETTERED_MESSAGES_TO] ), - defaultRuleDescription: rawSubscription[Constants.DEFAULT_RULE_DESCRIPTION], - - messageCountDetails: getCountDetailsOrUndefined(rawSubscription[Constants.COUNT_DETAILS]), forwardTo: getStringOrUndefined(rawSubscription[Constants.FORWARD_TO]), userMetadata: rawSubscription[Constants.USER_METADATA], - entityAvailabilityStatus: getString( - rawSubscription[Constants.ENTITY_AVAILABILITY_STATUS], - "entityAvailabilityStatus" - ), - status: getString(rawSubscription[Constants.STATUS], "status") as EntityStatus, + status: getString(rawSubscription[Constants.STATUS], "status") as EntityStatus + }; +} + +/** + * @internal + * @ignore + * Builds the subscription object from the raw json object gotten after deserializing + * the response from the service + * @param rawSubscription + */ +export function buildSubscriptionRuntimeInfo(rawSubscription: any): SubscriptionRuntimeInfo { + return { + subscriptionName: getString(rawSubscription[Constants.SUBSCRIPTION_NAME], "subscriptionName"), + topicName: getString(rawSubscription[Constants.TOPIC_NAME], "topicName"), + messageCount: getInteger(rawSubscription[Constants.MESSAGE_COUNT], "messageCount"), + messageCountDetails: getCountDetailsOrUndefined(rawSubscription[Constants.COUNT_DETAILS]), createdOn: getString(rawSubscription[Constants.CREATED_AT], "createdOn"), updatedOn: getString(rawSubscription[Constants.UPDATED_AT], "updatedOn"), accessedOn: rawSubscription[Constants.ACCESSED_AT] @@ -117,7 +119,17 @@ export function buildSubscription(rawSubscription: any): SubscriptionDetails { /** * Represents settable options on a subscription */ -export interface SubscriptionOptions { +export interface SubscriptionDescription { + /** + * Name of the subscription + */ + subscriptionName: string; + + /** + * Name of the topic + */ + topicName: string; + /** * The default lock duration is applied to subscriptions that do not define a lock * duration. Settable only at subscription creation time. @@ -307,9 +319,9 @@ export interface InternalSubscriptionOptions { } /** - * Represents all attributes of a subscription entity + * Represents runtime info attributes of a subscription entity */ -export interface SubscriptionDetails { +export interface SubscriptionRuntimeInfo { /** * Name of the subscription */ @@ -320,141 +332,17 @@ export interface SubscriptionDetails { */ topicName: string; - /** - * The default lock duration is applied to subscriptions that do not define a - * lock duration. - * Settable only at subscription creation time. - * This is specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - lockDuration: string; - - /** - * The entity's size in bytes. - * - */ - sizeInBytes?: number; - - /** - * Specifies the maximum topic size in megabytes. Any attempt to enqueue a message - * that will cause the topic to exceed this value will fail. All messages that are - * stored in the topic or any of its subscriptions count towards this value. - * Multiple copies of a message that reside in one or multiple subscriptions - * count as a single messages. For example, if message m exists once in subscription - * s1 and twice in subscription s2, m is counted as a single message. - */ - maxSizeInMegabytes?: number; - /** * The entity's message count. * */ messageCount: number; - /** - * Specifies whether the topic should be partitioned - */ - enablePartitioning?: boolean; - - /** - * If set to true, the subscription will be session-aware and only SessionReceiver - * will be supported. Session-aware subscription are not supported through REST. - * Settable only at subscription creation time. - */ - requiresSession: boolean; - - /** - * Specifies if batched operations should be allowed. - */ - enableBatchedOperations: boolean; - - /** - * Determines how long a message lives in the subscription. Based on whether - * dead-lettering is enabled, a message whose TTL has expired will either be moved - * to the subscription’s associated dead-letter sub-queue or permanently deleted. - * This is to be specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - defaultMessageTtl?: string; - - /** - * Indicates the default rule description. - * - */ - defaultRuleDescription?: any; - - /** - * Max idle time before entity is deleted. - * This is to be specified in ISO-8601 duration format - * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. - */ - autoDeleteOnIdle: string; - - /** - * If it is enabled and a message expires, the Service Bus moves the message from - * the queue into the subscription’s dead-letter sub-queue. If disabled, message - * will be permanently deleted from the subscription’s main queue. Settable only - * at subscription creation time. - */ - deadLetteringOnMessageExpiration: boolean; - - /** - * Determines how the Service Bus handles a message that causes an exception - * during a subscription’s filter evaluation. If the value is set to true, - * the message that caused the exception will be moved to the subscription’s - * dead-letter sub-queue. Otherwise, it will be discarded. By default this - * parameter is set to true, allowing the user a chance to investigate the - * cause of the exception. It can occur from a malformed message or some - * incorrect assumptions being made in the filter about the form of the message. - * Settable only at topic creation time. - */ - deadLetteringOnFilterEvaluationExceptions: boolean; - - /** - * Absolute URL or the name of the queue or topic the dead-lettered - * messages are to be forwarded to. - * For example, an absolute URL input would be of the form - * `sb:///` - */ - forwardDeadLetteredMessagesTo?: string; - - /** - * The maximum delivery count of messages after which if it is still not settled, - * gets moved to the dead-letter sub-queue. - * - */ - maxDeliveryCount: number; - - /** - * Absolute URL or the name of the queue or topic the - * messages are to be forwarded to. - * For example, an absolute URL input would be of the form - * `sb:///` - */ - forwardTo?: string; - - /** - * The user provided metadata information associated with the subscription description. - * Used to specify textual content such as tags, labels, etc. - * Value must not exceed 1024 bytes encoded in utf-8. - */ - userMetadata?: string; - /** * Message count details */ messageCountDetails?: MessageCountDetails; - /** - * Entity availability status - */ - entityAvailabilityStatus: string; - - /** - * Status of the messaging entity. - */ - status?: EntityStatus; - /** * Created at timestamp */ diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 3cae3aedd57c..434ca5b9e107 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -50,10 +50,11 @@ import { import { SubscriptionResourceSerializer, InternalSubscriptionOptions, - SubscriptionOptions, + SubscriptionDescription, buildSubscriptionOptions, - SubscriptionDetails, - buildSubscription + SubscriptionRuntimeInfo, + buildSubscription, + buildSubscriptionRuntimeInfo } from "./serializers/subscriptionResourceSerializer"; import { RuleResourceSerializer, @@ -250,10 +251,30 @@ export interface GetTopicsResponse extends Array { _response: HttpOperationResponse; } +/** + * Represents result of create, get, update and delete operations on topic. + */ +export interface GetSubscriptionRuntimeInfoResponse extends SubscriptionRuntimeInfo { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + +/** + * Represents result of create, get, update and delete operations on topic. + */ +export interface GetSubscriptionsRuntimeInfoResponse extends Array { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + /** * Represents result of create, get, update and delete operations on subscription. */ -export interface SubscriptionResponse extends SubscriptionDetails { +export interface SubscriptionResponse extends SubscriptionDescription { /** * The underlying HTTP response. */ @@ -263,7 +284,7 @@ export interface SubscriptionResponse extends SubscriptionDetails { /** * Create Subscription response */ -export interface CreateSubscriptionResponse extends SubscriptionDetails { +export interface CreateSubscriptionResponse extends SubscriptionDescription { /** * The underlying HTTP response. */ @@ -273,7 +294,7 @@ export interface CreateSubscriptionResponse extends SubscriptionDetails { /** * Get Subscription response */ -export interface GetSubscriptionResponse extends SubscriptionDetails { +export interface GetSubscriptionResponse extends SubscriptionDescription { /** * The underlying HTTP response. */ @@ -283,7 +304,7 @@ export interface GetSubscriptionResponse extends SubscriptionDetails { /** * Update Subscription response */ -export interface UpdateSubscriptionResponse extends SubscriptionDetails { +export interface UpdateSubscriptionResponse extends SubscriptionDescription { /** * The underlying HTTP response. */ @@ -303,7 +324,7 @@ export interface DeleteSubscriptionResponse { /** * Represents result of list operation on subscriptions. */ -export interface ListSubscriptionsResponse extends Array { +export interface GetSubscriptionsResponse extends Array { /** * The underlying HTTP response. */ @@ -973,8 +994,6 @@ export class ServiceBusManagementClient extends ServiceClient { * Creates a subscription with given name, configured using the given options * @param topicName * @param subscriptionName - * @param subscriptionOptions Options to configure the Subscription being created. - * For example, you can configure a Subscription to support partitions or sessions. * * Following are errors that can be expected from this operation * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, @@ -989,18 +1008,94 @@ export class ServiceBusManagementClient extends ServiceClient { */ async createSubscription( topicName: string, - subscriptionName: string, - subscriptionOptions?: SubscriptionOptions + subscriptionName: string + ): Promise; + + /** + * Creates a subscription with given name, configured using the given options + * @param subscription Options to configure the Subscription being created. + * For example, you can configure a Subscription to support partitions or sessions. + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityAlreadyExistsError` when requested messaging entity already exists, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `QuotaExceededError` when requested operation fails due to quote limits exceeding from service side, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async createSubscription( + subscription: SubscriptionDescription + ): Promise; + async createSubscription( + topicNameOrSubscriptionOptions: string | SubscriptionDescription, + subscriptionName?: string ): Promise { + if (typeof topicNameOrSubscriptionOptions == "string") { + log.httpAtomXml( + `Performing management operation - createSubscription() for "${subscriptionName}"` + ); + if (!subscriptionName) { + throw new Error("Subscription name is not provided"); + } + const fullPath = this.getSubscriptionPath(topicNameOrSubscriptionOptions, subscriptionName); + const response: HttpOperationResponse = await this.putResource( + fullPath, + buildSubscriptionOptions({ + topicName: topicNameOrSubscriptionOptions, + subscriptionName: subscriptionName + }), + this.subscriptionResourceSerializer, + false + ); + + return this.buildSubscriptionResponse(response); + } else { + const options = topicNameOrSubscriptionOptions; + log.httpAtomXml( + `Performing management operation - createSubscription() for "${subscriptionName}" with options: ${options}` + ); + const fullPath = this.getSubscriptionPath(options.topicName, options.subscriptionName); + const response: HttpOperationResponse = await this.putResource( + fullPath, + buildSubscriptionOptions(options || {}), + this.subscriptionResourceSerializer, + false + ); + + return this.buildSubscriptionResponse(response); + } + } + + /** + * Returns an object representing the Subscription with the given name along with all its properties + * @param topicName + * @param subscriptionName + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityNotFoundError` when requested messaging entity does not exist, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async getSubscription( + topicName: string, + subscriptionName: string + ): Promise { log.httpAtomXml( - `Performing management operation - createSubscription() for "${subscriptionName}" with options: ${subscriptionOptions}` + `Performing management operation - getSubscription() for "${subscriptionName}"` ); const fullPath = this.getSubscriptionPath(topicName, subscriptionName); - const response: HttpOperationResponse = await this.putResource( + const response: HttpOperationResponse = await this.getResource( fullPath, - buildSubscriptionOptions(subscriptionOptions || {}), - this.subscriptionResourceSerializer, - false + this.subscriptionResourceSerializer ); return this.buildSubscriptionResponse(response); @@ -1021,10 +1116,10 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async getSubscriptionDetails( + async getSubscriptionRuntimeInfo( topicName: string, subscriptionName: string - ): Promise { + ): Promise { log.httpAtomXml( `Performing management operation - getSubscription() for "${subscriptionName}"` ); @@ -1034,7 +1129,7 @@ export class ServiceBusManagementClient extends ServiceClient { this.subscriptionResourceSerializer ); - return this.buildSubscriptionResponse(response); + return this.buildSubscriptionRuntimeInfoResponse(response); } /** @@ -1051,10 +1146,10 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async listSubscriptions( + async getSubscriptions( topicName: string, listRequestOptions?: ListRequestOptions - ): Promise { + ): Promise { log.httpAtomXml( `Performing management operation - listSubscriptions() with options: ${listRequestOptions}` ); @@ -1068,10 +1163,38 @@ export class ServiceBusManagementClient extends ServiceClient { } /** - * Updates properties on the Subscription by the given name based on the given options + * Lists existing subscriptions. * @param topicName - * @param subscriptionName - * @param subscriptionOptions Options to configure the Subscription being updated. + * @param listRequestOptions + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async getSubscriptionsRuntimeInfo( + topicName: string, + listRequestOptions?: ListRequestOptions + ): Promise { + log.httpAtomXml( + `Performing management operation - listSubscriptions() with options: ${listRequestOptions}` + ); + const response: HttpOperationResponse = await this.listResources( + topicName + "/Subscriptions/", + listRequestOptions, + this.subscriptionResourceSerializer + ); + + return this.buildListSubscriptionsRuntimeInfoResponse(response); + } + + /** + * Updates properties on the Subscription by the given name based on the given options + * @param subscription Options to configure the Subscription being updated. * For example, you can configure a Subscription to support partitions or sessions. * * Following are errors that can be expected from this operation @@ -1085,25 +1208,29 @@ export class ServiceBusManagementClient extends ServiceClient { * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ async updateSubscription( - topicName: string, - subscriptionName: string, - subscriptionOptions: SubscriptionOptions + subscription: SubscriptionDescription ): Promise { log.httpAtomXml( - `Performing management operation - updateSubscription() for "${subscriptionName}" with options: ${subscriptionOptions}` + `Performing management operation - updateSubscription() for "${subscription.subscriptionName}" with options: ${subscription}` ); - if (!isJSONLikeObject(subscriptionOptions) || subscriptionOptions === null) { + if (!isJSONLikeObject(subscription) || subscription === null) { throw new TypeError( - `Parameter "subscriptionOptions" must be an object of type "SubscriptionOptions" and cannot be undefined or null.` + `Parameter "subscription" must be an object of type "SubscriptionOptions" and cannot be undefined or null.` ); } - const fullPath = this.getSubscriptionPath(topicName, subscriptionName); + const fullPath = this.getSubscriptionPath( + subscription.topicName, + subscription.subscriptionName + ); - const finalSubscriptionOptions: SubscriptionOptions = {}; - const getSubscriptionResult = await this.getSubscriptionDetails(topicName, subscriptionName); - Object.assign(finalSubscriptionOptions, getSubscriptionResult, subscriptionOptions); + const finalSubscriptionOptions: SubscriptionDescription = subscription; + const getSubscriptionResult = await this.getSubscription( + subscription.topicName, + subscription.subscriptionName + ); + Object.assign(finalSubscriptionOptions, getSubscriptionResult, subscription); const response: HttpOperationResponse = await this.putResource( fullPath, @@ -1157,7 +1284,7 @@ export class ServiceBusManagementClient extends ServiceClient { `Performing management operation - subscriptionExists() for "${topicName}" and "${subscriptionName}"` ); try { - await this.getSubscriptionDetails(topicName, subscriptionName); + await this.getSubscription(topicName, subscriptionName); } catch (error) { if (error.code == "MessageEntityNotFoundError") { return false; @@ -1689,9 +1816,9 @@ export class ServiceBusManagementClient extends ServiceClient { private buildListSubscriptionsResponse( response: HttpOperationResponse - ): ListSubscriptionsResponse { + ): GetSubscriptionsResponse { try { - const subscriptions: SubscriptionDetails[] = []; + const subscriptions: SubscriptionDescription[] = []; if (!Array.isArray(response.parsedBody)) { throw new TypeError(`${response.parsedBody} was expected to be of type Array`); } @@ -1702,7 +1829,7 @@ export class ServiceBusManagementClient extends ServiceClient { subscriptions.push(subscription); } } - const listSubscriptionsResponse: ListSubscriptionsResponse = Object.assign(subscriptions, { + const listSubscriptionsResponse: GetSubscriptionsResponse = Object.assign(subscriptions, { _response: response }); return listSubscriptionsResponse; @@ -1718,6 +1845,40 @@ export class ServiceBusManagementClient extends ServiceClient { } } + private buildListSubscriptionsRuntimeInfoResponse( + response: HttpOperationResponse + ): GetSubscriptionsRuntimeInfoResponse { + try { + const subscriptions: SubscriptionRuntimeInfo[] = []; + if (!Array.isArray(response.parsedBody)) { + throw new TypeError(`${response.parsedBody} was expected to be of type Array`); + } + const rawSubscriptionArray: any = response.parsedBody; + for (let i = 0; i < rawSubscriptionArray.length; i++) { + const subscription = buildSubscriptionRuntimeInfo(rawSubscriptionArray[i]); + if (subscription) { + subscriptions.push(subscription); + } + } + const listSubscriptionsResponse: GetSubscriptionsRuntimeInfoResponse = Object.assign( + subscriptions, + { + _response: response + } + ); + return listSubscriptionsResponse; + } catch (err) { + log.warning("Failure parsing response from service - %0 ", err); + throw new RestError( + `Error occurred while parsing the response body - cannot form a list of subscriptions using the response from the service.`, + RestError.PARSE_ERROR, + response.status, + stripRequest(response.request), + stripResponse(response) + ); + } + } + private buildSubscriptionResponse(response: HttpOperationResponse): SubscriptionResponse { try { const subscription = buildSubscription(response.parsedBody); @@ -1737,6 +1898,30 @@ export class ServiceBusManagementClient extends ServiceClient { } } + private buildSubscriptionRuntimeInfoResponse( + response: HttpOperationResponse + ): GetSubscriptionRuntimeInfoResponse { + try { + const subscription = buildSubscriptionRuntimeInfo(response.parsedBody); + const subscriptionResponse: GetSubscriptionRuntimeInfoResponse = Object.assign( + subscription || {}, + { + _response: response + } + ); + return subscriptionResponse; + } catch (err) { + log.warning("Failure parsing response from service - %0 ", err); + throw new RestError( + `Error occurred while parsing the response body - cannot form a subscription object using the response from the service.`, + RestError.PARSE_ERROR, + response.status, + stripRequest(response.request), + stripResponse(response) + ); + } + } + private buildListRulesResponse(response: HttpOperationResponse): ListRulesResponse { try { const rules: RuleDescription[] = []; From 5a58acad32de5aa3a7a10449d823cda410faf00e Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 13:00:21 -0700 Subject: [PATCH 21/61] fix build failures --- sdk/servicebus/service-bus/src/index.ts | 6 +-- .../service-bus/test/atomManagement.spec.ts | 40 +++++++++---------- .../service-bus/test/atomXml.spec.ts | 2 +- .../service-bus/test/utils/managementUtils.ts | 10 ++--- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index 212877e41338..b2d19d915a9d 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -48,8 +48,8 @@ export { ServiceBusClient } from "./serviceBusClient"; export { QueueDescription, QueueRuntimeInfo } from "./serializers/queueResourceSerializer"; export { TopicDescription, TopicRuntimeInfo } from "./serializers/topicResourceSerializer"; export { - SubscriptionOptions, - SubscriptionDetails + SubscriptionDescription, + SubscriptionRuntimeInfo } from "./serializers/subscriptionResourceSerializer"; export { RuleOptions, @@ -78,7 +78,7 @@ export { GetSubscriptionResponse, GetTopicResponse, ListRulesResponse, - ListSubscriptionsResponse, + GetSubscriptionsResponse, GetTopicsResponse, UpdateQueueResponse, UpdateRuleResponse, diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index af29eacfb128..437206db6d0f 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -3,7 +3,7 @@ import { QueueDescription } from "../src/serializers/queueResourceSerializer"; import { TopicDescription } from "../src/serializers/topicResourceSerializer"; -import { SubscriptionOptions } from "../src/serializers/subscriptionResourceSerializer"; +import { SubscriptionDescription } from "../src/serializers/subscriptionResourceSerializer"; import { RuleOptions } from "../src/serializers/ruleResourceSerializer"; import { EntityStatus } from "../src/util/utils"; import { ServiceBusManagementClient } from "../src/serviceBusAtomManagementClient"; @@ -1895,7 +1895,7 @@ async function createEntity( overrideOptions?: boolean, // If this is false, then the default options will be populated as used for basic testing. queueOptions?: Omit, topicOptions?: Omit, - subscriptionOptions?: SubscriptionOptions, + subscriptionOptions?: Omit, ruleOptions?: RuleOptions ): Promise { if (!overrideOptions) { @@ -1962,11 +1962,11 @@ async function createEntity( "TestError: Topic path must be passed when invoking tests on subscriptions" ); } - const subscriptionResponse = await serviceBusAtomManagementClient.createSubscription( - topicPath, - entityPath, - subscriptionOptions - ); + const subscriptionResponse = await serviceBusAtomManagementClient.createSubscription({ + topicName: topicPath, + subscriptionName: entityPath, + ...subscriptionOptions + }); return subscriptionResponse; case EntityType.RULE: if (!topicPath || !subscriptionPath) { @@ -2004,7 +2004,7 @@ async function getEntity( "TestError: Topic path must be passed when invoking tests on subscriptions" ); } - const subscriptionResponse = await serviceBusAtomManagementClient.getSubscriptionDetails( + const subscriptionResponse = await serviceBusAtomManagementClient.getSubscription( topicPath, entityPath ); @@ -2033,7 +2033,7 @@ async function updateEntity( overrideOptions?: boolean, // If this is false, then the default options will be populated as used for basic testing. queueOptions?: Omit, topicOptions?: Omit, - subscriptionOptions?: SubscriptionOptions, + subscriptionOptions?: Omit, ruleOptions?: RuleOptions ): Promise { if (!overrideOptions) { @@ -2089,11 +2089,10 @@ async function updateEntity( }); return queueResponse; case EntityType.TOPIC: - const topicResponse = await serviceBusAtomManagementClient.updateTopic( - entityPath, - // @ts-ignore - topicOptions - ); + const topicResponse = await serviceBusAtomManagementClient.updateTopic({ + topicName: entityPath, + ...topicOptions + }); return topicResponse; case EntityType.SUBSCRIPTION: if (!topicPath) { @@ -2101,12 +2100,11 @@ async function updateEntity( "TestError: Topic path must be passed when invoking tests on subscriptions" ); } - const subscriptionResponse = await serviceBusAtomManagementClient.updateSubscription( - topicPath, - entityPath, - // @ts-ignore - subscriptionOptions - ); + const subscriptionResponse = await serviceBusAtomManagementClient.updateSubscription({ + topicName: topicPath, + subscriptionName: entityPath, + ...subscriptionOptions + }); return subscriptionResponse; case EntityType.RULE: if (!topicPath || !subscriptionPath) { @@ -2192,7 +2190,7 @@ async function listEntities( "TestError: Topic path must be passed when invoking tests on subscriptions" ); } - const subscriptionResponse = await serviceBusAtomManagementClient.listSubscriptions( + const subscriptionResponse = await serviceBusAtomManagementClient.getSubscriptions( topicPath, { skip: skip, top: top } ); diff --git a/sdk/servicebus/service-bus/test/atomXml.spec.ts b/sdk/servicebus/service-bus/test/atomXml.spec.ts index 4b439e896b57..3774c624d542 100644 --- a/sdk/servicebus/service-bus/test/atomXml.spec.ts +++ b/sdk/servicebus/service-bus/test/atomXml.spec.ts @@ -967,7 +967,7 @@ describe(`Parse empty response for list() requests to return as empty array`, fu headers: new HttpHeaders({}) }; }; - const result = await mockServiceBusAtomManagementClient.listSubscriptions("testTopic"); + const result = await mockServiceBusAtomManagementClient.getSubscriptions("testTopic"); assertEmptyArray(result); }); diff --git a/sdk/servicebus/service-bus/test/utils/managementUtils.ts b/sdk/servicebus/service-bus/test/utils/managementUtils.ts index 74d1f4ed1c70..c1094e0b0a37 100644 --- a/sdk/servicebus/service-bus/test/utils/managementUtils.ts +++ b/sdk/servicebus/service-bus/test/utils/managementUtils.ts @@ -4,7 +4,7 @@ import { delay } from "../../src"; import { QueueDescription } from "../../src/serializers/queueResourceSerializer"; import { TopicDescription } from "../../src/serializers/topicResourceSerializer"; -import { SubscriptionOptions } from "../../src/serializers/subscriptionResourceSerializer"; +import { SubscriptionDescription } from "../../src/serializers/subscriptionResourceSerializer"; import { ServiceBusManagementClient } from "../../src/serviceBusAtomManagementClient"; import { EnvVarNames, getEnvVars } from "./envVarUtils"; @@ -156,7 +156,7 @@ export async function recreateTopic( export async function recreateSubscription( topicName: string, subscriptionName: string, - parameters?: SubscriptionOptions + parameters?: Omit ): Promise { await getManagementClient(); /* @@ -166,12 +166,12 @@ export async function recreateSubscription( */ const createSubscriptionOperation = async () => { - await client.createSubscription(topicName, subscriptionName, parameters); + await client.createSubscription({ topicName, subscriptionName, ...parameters }); }; const checkIfSubscriptionExistsOperation = async () => { try { - await client.getSubscriptionDetails(topicName, subscriptionName); + await client.getSubscription(topicName, subscriptionName); } catch (err) { return false; } @@ -205,7 +205,7 @@ export async function verifyMessageCount( should.equal( queueName ? (await client.getQueueRuntimeInfo(queueName)).messageCount - : (await client.getSubscriptionDetails(topicName!, subscriptionName!)).messageCount, + : (await client.getSubscriptionRuntimeInfo(topicName!, subscriptionName!)).messageCount, expectedMessageCount, `Unexpected number of messages are present in the entity.` ); From 92ba1a43b5e136f090f48e243bd958a95344f988 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 13:00:51 -0700 Subject: [PATCH 22/61] generate API report --- .../service-bus/review/service-bus.api.md | 72 ++++++++----------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 47b0979cd528..90e0e33f353f 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -76,7 +76,7 @@ export interface CreateSessionReceiverOptions extends SessionReceiverOptions, Op } // @public -export interface CreateSubscriptionResponse extends SubscriptionDetails { +export interface CreateSubscriptionResponse extends SubscriptionDescription { _response: HttpOperationResponse; } @@ -148,7 +148,12 @@ export interface GetRuleResponse extends RuleDescription { } // @public -export interface GetSubscriptionResponse extends SubscriptionDetails { +export interface GetSubscriptionResponse extends SubscriptionDescription { + _response: HttpOperationResponse; +} + +// @public +export interface GetSubscriptionsResponse extends Array { _response: HttpOperationResponse; } @@ -173,11 +178,6 @@ export interface ListRulesResponse extends Array { _response: HttpOperationResponse; } -// @public -export interface ListSubscriptionsResponse extends Array { - _response: HttpOperationResponse; -} - // @public export type MessageCountDetails = { activeMessageCount: number; @@ -348,7 +348,8 @@ export class ServiceBusManagementClient extends ServiceClient { createQueue(queueName: string): Promise; createQueue(queue: QueueDescription): Promise; createRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions?: RuleOptions): Promise; - createSubscription(topicName: string, subscriptionName: string, subscriptionOptions?: SubscriptionOptions): Promise; + createSubscription(topicName: string, subscriptionName: string): Promise; + createSubscription(subscription: SubscriptionDescription): Promise; createTopic(topicName: string): Promise; createTopic(topicOptions: TopicDescription): Promise; deleteQueue(queueName: string): Promise; @@ -360,7 +361,12 @@ export class ServiceBusManagementClient extends ServiceClient { getQueues(listRequestOptions?: ListRequestOptions): Promise; getQueuesRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; getRuleDescription(topicName: string, subscriptioName: string, ruleName: string): Promise; - getSubscriptionDetails(topicName: string, subscriptionName: string): Promise; + getSubscription(topicName: string, subscriptionName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetSubscriptionRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getSubscriptionRuntimeInfo(topicName: string, subscriptionName: string): Promise; + getSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "GetSubscriptionsRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getSubscriptionsRuntimeInfo(topicName: string, listRequestOptions?: ListRequestOptions): Promise; getTopic(topicName: string): Promise; // Warning: (ae-forgotten-export) The symbol "GetTopicRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getTopicRuntimeInfo(topicName: string): Promise; @@ -368,13 +374,12 @@ export class ServiceBusManagementClient extends ServiceClient { // Warning: (ae-forgotten-export) The symbol "GetTopicsRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getTopicsRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; listRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; - listSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; queueExists(queueName: string): Promise; subscriptionExists(topicName: string, subscriptionName: string): Promise; topicExists(topicName: string): Promise; updateQueue(queue: QueueDescription): Promise; updateRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions: RuleOptions): Promise; - updateSubscription(topicName: string, subscriptionName: string, subscriptionOptions: SubscriptionOptions): Promise; + updateSubscription(subscription: SubscriptionDescription): Promise; updateTopic(topic: TopicDescription): Promise; } @@ -444,35 +449,7 @@ export interface SubscribeOptions extends OperationOptions, MessageHandlerOption } // @public -export interface SubscriptionDetails { - accessedOn?: string; - autoDeleteOnIdle: string; - createdOn: string; - deadLetteringOnFilterEvaluationExceptions: boolean; - deadLetteringOnMessageExpiration: boolean; - defaultMessageTtl?: string; - defaultRuleDescription?: any; - enableBatchedOperations: boolean; - enablePartitioning?: boolean; - entityAvailabilityStatus: string; - forwardDeadLetteredMessagesTo?: string; - forwardTo?: string; - lockDuration: string; - maxDeliveryCount: number; - maxSizeInMegabytes?: number; - messageCount: number; - messageCountDetails?: MessageCountDetails; - requiresSession: boolean; - sizeInBytes?: number; - status?: EntityStatus; - subscriptionName: string; - topicName: string; - updatedOn: string; - userMetadata?: string; -} - -// @public -export interface SubscriptionOptions { +export interface SubscriptionDescription { autoDeleteOnIdle?: string; deadLetteringOnFilterEvaluationExceptions?: boolean; deadLetteringOnMessageExpiration?: boolean; @@ -484,9 +461,22 @@ export interface SubscriptionOptions { maxDeliveryCount?: number; requiresSession?: boolean; status?: EntityStatus; + subscriptionName: string; + topicName: string; userMetadata?: string; } +// @public +export interface SubscriptionRuntimeInfo { + accessedOn?: string; + createdOn: string; + messageCount: number; + messageCountDetails?: MessageCountDetails; + subscriptionName: string; + topicName: string; + updatedOn: string; +} + export { TokenCredential } export { TokenType } @@ -528,7 +518,7 @@ export interface UpdateRuleResponse extends RuleDescription { } // @public -export interface UpdateSubscriptionResponse extends SubscriptionDetails { +export interface UpdateSubscriptionResponse extends SubscriptionDescription { _response: HttpOperationResponse; } From 5cb629a22f6260d37be54881a36117b79b453638 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 13:03:09 -0700 Subject: [PATCH 23/61] fix API report warnings --- .../service-bus/review/service-bus.api.md | 24 +++++++++++++++---- sdk/servicebus/service-bus/src/index.ts | 4 ++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 90e0e33f353f..aa94802d39cb 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -152,21 +152,41 @@ export interface GetSubscriptionResponse extends SubscriptionDescription { _response: HttpOperationResponse; } +// @public +export interface GetSubscriptionRuntimeInfoResponse extends SubscriptionRuntimeInfo { + _response: HttpOperationResponse; +} + // @public export interface GetSubscriptionsResponse extends Array { _response: HttpOperationResponse; } +// @public +export interface GetSubscriptionsRuntimeInfoResponse extends Array { + _response: HttpOperationResponse; +} + // @public export interface GetTopicResponse extends TopicDescription { _response: HttpOperationResponse; } +// @public +export interface GetTopicRuntimeInfoResponse extends TopicRuntimeInfo { + _response: HttpOperationResponse; +} + // @public export interface GetTopicsResponse extends Array { _response: HttpOperationResponse; } +// @public +export interface GetTopicsRuntimeInfoResponse extends Array { + _response: HttpOperationResponse; +} + // @public export interface ListRequestOptions { skip?: number; @@ -362,16 +382,12 @@ export class ServiceBusManagementClient extends ServiceClient { getQueuesRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; getRuleDescription(topicName: string, subscriptioName: string, ruleName: string): Promise; getSubscription(topicName: string, subscriptionName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetSubscriptionRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getSubscriptionRuntimeInfo(topicName: string, subscriptionName: string): Promise; getSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "GetSubscriptionsRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getSubscriptionsRuntimeInfo(topicName: string, listRequestOptions?: ListRequestOptions): Promise; getTopic(topicName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetTopicRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getTopicRuntimeInfo(topicName: string): Promise; getTopics(listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "GetTopicsRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getTopicsRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; listRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; queueExists(queueName: string): Promise; diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index b2d19d915a9d..fee3482e35f3 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -77,8 +77,12 @@ export { GetRuleResponse, GetSubscriptionResponse, GetTopicResponse, + GetTopicRuntimeInfoResponse, + GetTopicsRuntimeInfoResponse, ListRulesResponse, GetSubscriptionsResponse, + GetSubscriptionRuntimeInfoResponse, + GetSubscriptionsRuntimeInfoResponse, GetTopicsResponse, UpdateQueueResponse, UpdateRuleResponse, From ab59d311832e006ddf94149b9fc9494d9e10726b Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 13:51:55 -0700 Subject: [PATCH 24/61] changes to rule APIs --- sdk/servicebus/service-bus/src/index.ts | 9 +--- .../src/serializers/ruleResourceSerializer.ts | 50 +++---------------- .../src/serviceBusAtomManagementClient.ts | 40 +++++++-------- 3 files changed, 26 insertions(+), 73 deletions(-) diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index fee3482e35f3..bcbde5f2f3b2 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -51,12 +51,7 @@ export { SubscriptionDescription, SubscriptionRuntimeInfo } from "./serializers/subscriptionResourceSerializer"; -export { - RuleOptions, - RuleDescription, - SqlAction, - SqlRuleFilter -} from "./serializers/ruleResourceSerializer"; +export { RuleDescription, SqlAction, SqlRuleFilter } from "./serializers/ruleResourceSerializer"; export { CorrelationRuleFilter } from "./core/managementClient"; export { ServiceBusManagementClient, @@ -79,7 +74,7 @@ export { GetTopicResponse, GetTopicRuntimeInfoResponse, GetTopicsRuntimeInfoResponse, - ListRulesResponse, + GetRulesResponse, GetSubscriptionsResponse, GetSubscriptionRuntimeInfoResponse, GetSubscriptionsRuntimeInfoResponse, diff --git a/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts index 0c7afe50f8cd..2ca774eb394c 100644 --- a/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts @@ -26,7 +26,10 @@ import { CorrelationRuleFilter } from "../core/managementClient"; * @param name * @param ruleOptions */ -export function buildRuleOptions(name: string, ruleOptions: RuleOptions = {}): InternalRuleOptions { +export function buildRuleOptions( + name: string, + ruleOptions: Pick = {} +): InternalRuleOptions { const internalRuleOptions: InternalRuleOptions = Object.assign({}, ruleOptions, { name: name }); return internalRuleOptions; } @@ -44,8 +47,7 @@ export function buildRule(rawRule: any): RuleDescription { topicName: getString(rawRule["TopicName"], "topicName"), subscriptionName: getString(rawRule["SubscriptionName"], "subscriptionName"), filter: getTopicFilter(rawRule["Filter"]), - action: getRuleActionOrUndefined(rawRule["Action"]), - createdOn: getString(rawRule["CreatedAt"], "createdOn") + action: getRuleActionOrUndefined(rawRule["Action"]) }; } @@ -102,31 +104,12 @@ function getRuleActionOrUndefined(value: any): SqlAction | undefined { } } -/** - * Represents settable options on a rule - */ -export interface RuleOptions { - /** - * Defines the filter expression that the rule evaluates. For `SqlRuleFilter` input, - * the expression string is interpreted as a SQL92 expression which must - * evaluate to True or False. Only one between a `CorrelationRuleFilter` or - * a `SqlRuleFilter` can be defined. - */ - filter?: SqlRuleFilter | CorrelationRuleFilter; - - /** - * The SQL like expression that can be executed on the message should the - * associated filter apply. - */ - action?: SqlAction; -} - /** * @internal * @ignore * Internal representation of settable options on a rule */ -export interface InternalRuleOptions extends RuleOptions { +export interface InternalRuleOptions extends Pick { /** * @internal * @ignore @@ -163,27 +146,6 @@ export interface RuleDescription { * associated filter apply. */ action?: SqlAction; - - /** - * @internal - * @ignore - * Name of topic - */ - topicName: string; - - /** - * @internal - * @ignore - * Name of subscription - */ - subscriptionName: string; - - /** - * @internal - * @ignore - * Created at timestamp - */ - createdOn: string; } /** diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 434ca5b9e107..83582a942c3f 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -59,9 +59,8 @@ import { import { RuleResourceSerializer, InternalRuleOptions, - RuleOptions, - buildRuleOptions, RuleDescription, + buildRuleOptions, buildRule } from "./serializers/ruleResourceSerializer"; import { isJSONLikeObject, isAbsoluteUrl, areOptionsUndefined } from "./util/utils"; @@ -384,7 +383,7 @@ export interface DeleteRuleResponse { /** * Represents result of list operation on rules. */ -export interface ListRulesResponse extends Array { +export interface GetRulesResponse extends Array { /** * The underlying HTTP response. */ @@ -1297,8 +1296,7 @@ export class ServiceBusManagementClient extends ServiceClient { * Creates a rule with given name, configured using the given options. * @param topicName * @param subscriptionName - * @param ruleName - * @param ruleOptions + * @param rule * * Following are errors that can be expected from this operation * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, @@ -1314,16 +1312,15 @@ export class ServiceBusManagementClient extends ServiceClient { async createRule( topicName: string, subscriptionName: string, - ruleName: string, - ruleOptions?: RuleOptions + rule: RuleDescription ): Promise { log.httpAtomXml( - `Performing management operation - createRule() for "${ruleName}" with options: "${ruleOptions}"` + `Performing management operation - createRule() for "${rule.ruleName}" with options: "${rule}"` ); - const fullPath = this.getRulePath(topicName, subscriptionName, ruleName); + const fullPath = this.getRulePath(topicName, subscriptionName, rule.ruleName); const response: HttpOperationResponse = await this.putResource( fullPath, - buildRuleOptions(ruleName, ruleOptions), + buildRuleOptions(rule.ruleName, rule), this.ruleResourceSerializer, false ); @@ -1346,7 +1343,7 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async getRuleDescription( + async getRule( topicName: string, subscriptioName: string, ruleName: string @@ -1376,11 +1373,11 @@ export class ServiceBusManagementClient extends ServiceClient { * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 */ - async listRules( + async getRules( topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions - ): Promise { + ): Promise { log.httpAtomXml( `Performing management operation - listRules() with options: ${listRequestOptions}` ); @@ -1415,23 +1412,22 @@ export class ServiceBusManagementClient extends ServiceClient { async updateRule( topicName: string, subscriptionName: string, - ruleName: string, - ruleOptions: RuleOptions + rule: RuleDescription ): Promise { log.httpAtomXml( - `Performing management operation - updateRule() for "${ruleName}" with options: ${ruleOptions}` + `Performing management operation - updateRule() for "${rule.ruleName}" with options: ${rule}` ); - if (!isJSONLikeObject(ruleOptions) || ruleOptions === null) { + if (!isJSONLikeObject(rule) || rule === null) { throw new TypeError( - `Parameter "ruleOptions" must be an object of type "RuleOptions" and cannot be undefined or null.` + `Parameter "rule" must be an object of type "RuleDescription" and cannot be undefined or null.` ); } - const fullPath = this.getRulePath(topicName, subscriptionName, ruleName); + const fullPath = this.getRulePath(topicName, subscriptionName, rule.ruleName); const response: HttpOperationResponse = await this.putResource( fullPath, - buildRuleOptions(ruleName, ruleOptions), + buildRuleOptions(rule.ruleName, rule), this.ruleResourceSerializer, true ); @@ -1922,7 +1918,7 @@ export class ServiceBusManagementClient extends ServiceClient { } } - private buildListRulesResponse(response: HttpOperationResponse): ListRulesResponse { + private buildListRulesResponse(response: HttpOperationResponse): GetRulesResponse { try { const rules: RuleDescription[] = []; if (!Array.isArray(response.parsedBody)) { @@ -1935,7 +1931,7 @@ export class ServiceBusManagementClient extends ServiceClient { rules.push(rule); } } - const listRulesResponse: ListRulesResponse = Object.assign(rules, { + const listRulesResponse: GetRulesResponse = Object.assign(rules, { _response: response }); return listRulesResponse; From 75148241ccf27d16a35f79da4f6f21b72562fe3a Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 13:53:43 -0700 Subject: [PATCH 25/61] fix build failures --- .../src/serializers/ruleResourceSerializer.ts | 2 -- .../service-bus/test/atomManagement.spec.ts | 13 ++++++------- sdk/servicebus/service-bus/test/atomXml.spec.ts | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts index 2ca774eb394c..a845a9c4ac1e 100644 --- a/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts @@ -44,8 +44,6 @@ export function buildRuleOptions( export function buildRule(rawRule: any): RuleDescription { return { ruleName: getString(rawRule["RuleName"], "ruleName"), - topicName: getString(rawRule["TopicName"], "topicName"), - subscriptionName: getString(rawRule["SubscriptionName"], "subscriptionName"), filter: getTopicFilter(rawRule["Filter"]), action: getRuleActionOrUndefined(rawRule["Action"]) }; diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 437206db6d0f..35d4b6413562 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -4,7 +4,7 @@ import { QueueDescription } from "../src/serializers/queueResourceSerializer"; import { TopicDescription } from "../src/serializers/topicResourceSerializer"; import { SubscriptionDescription } from "../src/serializers/subscriptionResourceSerializer"; -import { RuleOptions } from "../src/serializers/ruleResourceSerializer"; +import { RuleDescription } from "../src/serializers/ruleResourceSerializer"; import { EntityStatus } from "../src/util/utils"; import { ServiceBusManagementClient } from "../src/serviceBusAtomManagementClient"; @@ -1896,7 +1896,7 @@ async function createEntity( queueOptions?: Omit, topicOptions?: Omit, subscriptionOptions?: Omit, - ruleOptions?: RuleOptions + ruleOptions?: Omit ): Promise { if (!overrideOptions) { if (queueOptions == undefined) { @@ -1977,8 +1977,7 @@ async function createEntity( const ruleResponse = await serviceBusAtomManagementClient.createRule( topicPath, subscriptionPath, - entityPath, - ruleOptions + { ruleName: entityPath, ...ruleOptions } ); return ruleResponse; } @@ -2015,7 +2014,7 @@ async function getEntity( "TestError: Topic path AND subscription path must be passed when invoking tests on rules" ); } - const ruleResponse = await serviceBusAtomManagementClient.getRuleDescription( + const ruleResponse = await serviceBusAtomManagementClient.getRule( topicPath, subscriptionPath, entityPath @@ -2034,7 +2033,7 @@ async function updateEntity( queueOptions?: Omit, topicOptions?: Omit, subscriptionOptions?: Omit, - ruleOptions?: RuleOptions + ruleOptions?: Omit ): Promise { if (!overrideOptions) { if (queueOptions == undefined) { @@ -2201,7 +2200,7 @@ async function listEntities( "TestError: Topic path AND subscription path must be passed when invoking tests on rules" ); } - const ruleResponse = await serviceBusAtomManagementClient.listRules( + const ruleResponse = await serviceBusAtomManagementClient.getRules( topicPath, subscriptionPath, { skip: skip, top: top } diff --git a/sdk/servicebus/service-bus/test/atomXml.spec.ts b/sdk/servicebus/service-bus/test/atomXml.spec.ts index 3774c624d542..1c5721942e21 100644 --- a/sdk/servicebus/service-bus/test/atomXml.spec.ts +++ b/sdk/servicebus/service-bus/test/atomXml.spec.ts @@ -980,7 +980,7 @@ describe(`Parse empty response for list() requests to return as empty array`, fu headers: new HttpHeaders({}) }; }; - const result = await mockServiceBusAtomManagementClient.listRules( + const result = await mockServiceBusAtomManagementClient.getRules( "testTopic", "testSubscription" ); From a5e164b259c5c55be47718869c827899a2fa13a5 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 13:54:08 -0700 Subject: [PATCH 26/61] generate API report --- .../service-bus/review/service-bus.api.md | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index aa94802d39cb..fe98b3aaf868 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -147,6 +147,11 @@ export interface GetRuleResponse extends RuleDescription { _response: HttpOperationResponse; } +// @public +export interface GetRulesResponse extends Array { + _response: HttpOperationResponse; +} + // @public export interface GetSubscriptionResponse extends SubscriptionDescription { _response: HttpOperationResponse; @@ -193,11 +198,6 @@ export interface ListRequestOptions { top?: number; } -// @public -export interface ListRulesResponse extends Array { - _response: HttpOperationResponse; -} - // @public export type MessageCountDetails = { activeMessageCount: number; @@ -313,12 +313,6 @@ export { RetryOptions } export interface RuleDescription { } -// @public -export interface RuleOptions { - action?: SqlAction; - filter?: SqlRuleFilter | CorrelationRuleFilter; -} - // @public export interface Sender { cancelScheduledMessage(sequenceNumber: Long, options?: OperationOptions): Promise; @@ -367,7 +361,7 @@ export class ServiceBusManagementClient extends ServiceClient { constructor(fullyQualifiedNamespace: string, credential: TokenCredential, options?: ServiceBusManagementClientOptions); createQueue(queueName: string): Promise; createQueue(queue: QueueDescription): Promise; - createRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions?: RuleOptions): Promise; + createRule(topicName: string, subscriptionName: string, rule: RuleDescription): Promise; createSubscription(topicName: string, subscriptionName: string): Promise; createSubscription(subscription: SubscriptionDescription): Promise; createTopic(topicName: string): Promise; @@ -380,7 +374,8 @@ export class ServiceBusManagementClient extends ServiceClient { getQueueRuntimeInfo(queueName: string): Promise; getQueues(listRequestOptions?: ListRequestOptions): Promise; getQueuesRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; - getRuleDescription(topicName: string, subscriptioName: string, ruleName: string): Promise; + getRule(topicName: string, subscriptioName: string, ruleName: string): Promise; + getRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; getSubscription(topicName: string, subscriptionName: string): Promise; getSubscriptionRuntimeInfo(topicName: string, subscriptionName: string): Promise; getSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; @@ -389,12 +384,11 @@ export class ServiceBusManagementClient extends ServiceClient { getTopicRuntimeInfo(topicName: string): Promise; getTopics(listRequestOptions?: ListRequestOptions): Promise; getTopicsRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; - listRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; queueExists(queueName: string): Promise; subscriptionExists(topicName: string, subscriptionName: string): Promise; topicExists(topicName: string): Promise; updateQueue(queue: QueueDescription): Promise; - updateRule(topicName: string, subscriptionName: string, ruleName: string, ruleOptions: RuleOptions): Promise; + updateRule(topicName: string, subscriptionName: string, rule: RuleDescription): Promise; updateSubscription(subscription: SubscriptionDescription): Promise; updateTopic(topic: TopicDescription): Promise; } From e94446429f9275cbcf5c47976c65d468c2dc7b0b Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 17:24:14 -0700 Subject: [PATCH 27/61] getNamespaceProperties API --- .../namespaceResourceSerializer.ts | 51 ++++++++++++++++ .../src/serviceBusAtomManagementClient.ts | 61 +++++++++++++++++++ .../service-bus/src/util/atomXmlHelper.ts | 3 - 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts diff --git a/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts new file mode 100644 index 000000000000..5d25942b0ba4 --- /dev/null +++ b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { + AtomXmlSerializer, + serializeToAtomXmlRequest, + deserializeAtomXmlResponse +} from "../util/atomXmlHelper"; +import { HttpOperationResponse } from "@azure/core-http"; +import { getString } from "../util/utils"; + +// TODO: Add docs for the attributes and for the interface +export interface NamespaceProperties { + createdOn: string; + messagingSku: string; + updatedOn: string; + name: string; + namespaceType: string; +} + +/** + * @internal + * @ignore + * Builds the namespace object from the raw json object gotten after deserializing the + * response from the service + * @param rawNamespace + */ +export function buildNamespace(rawNamespace: any): NamespaceProperties { + return { + createdOn: getString(rawNamespace["CreatedTime"], "createdOn"), + messagingSku: getString(rawNamespace["MessagingSKU"], "messagingSku"), + updatedOn: getString(rawNamespace["ModifiedTime"], "updatedOn"), + name: getString(rawNamespace["Name"], "name"), + namespaceType: getString(rawNamespace["NamespaceType"], "namespaceType") + }; +} + +/** + * @internal + * @ignore + * Atom XML Serializer for Queues. + */ +export class NamespaceResourceSerializer implements AtomXmlSerializer { + serialize(): object { + return serializeToAtomXmlRequest("NamespaceProperties", {}); + } + + async deserialize(response: HttpOperationResponse): Promise { + return deserializeAtomXmlResponse(["Name"], response); + } +} diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 83582a942c3f..fb0d8ae3a030 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -64,6 +64,11 @@ import { buildRule } from "./serializers/ruleResourceSerializer"; import { isJSONLikeObject, isAbsoluteUrl, areOptionsUndefined } from "./util/utils"; +import { + NamespaceResourceSerializer, + buildNamespace, + NamespaceProperties +} from "./serializers/namespaceResourceSerializer"; /** * Options to use with ServiceBusManagementClient creation @@ -90,6 +95,25 @@ export interface ListRequestOptions { skip?: number; } +/** + * Represents properties of the namespace. + */ +export interface NamespaceResponse extends NamespaceProperties { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} +/** + * Represents properties of the namespace. + */ +export interface GetNamespaceResponse extends NamespaceProperties { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + /** * Represents result of create, get, update and delete operations on queue. */ @@ -409,6 +433,7 @@ export class ServiceBusManagementClient extends ServiceClient { /** * Singleton instances of serializers used across the various operations. */ + private namespaceResourceSerializer: AtomXmlSerializer; private queueResourceSerializer: AtomXmlSerializer; private topicResourceSerializer: AtomXmlSerializer; private subscriptionResourceSerializer: AtomXmlSerializer; @@ -491,12 +516,29 @@ export class ServiceBusManagementClient extends ServiceClient { connectionStringObj.SharedAccessKey ); } + this.namespaceResourceSerializer = new NamespaceResourceSerializer(); this.queueResourceSerializer = new QueueResourceSerializer(); this.topicResourceSerializer = new TopicResourceSerializer(); this.subscriptionResourceSerializer = new SubscriptionResourceSerializer(); this.ruleResourceSerializer = new RuleResourceSerializer(); } + /** + * Returns an object representing the Queue with the given name along with all its properties + * @param queueName + * + */ + async getNamespaceProperties(): Promise { + //Promise { + log.httpAtomXml(`Performing management operation - getNamespaceProperties()`); + const response: HttpOperationResponse = await this.getResource( + "$namespaceinfo", + this.namespaceResourceSerializer + ); + + return this.buildNamespaceResponse(response); + } + /** * Creates a queue with given name, configured using the given options * @param queueName @@ -1610,6 +1652,25 @@ export class ServiceBusManagementClient extends ServiceClient { return topicName + "/Subscriptions/" + subscriptionName + "/Rules/" + ruleName; } + private buildNamespaceResponse(response: HttpOperationResponse): NamespaceResponse { + try { + const namespace = buildNamespace(response.parsedBody); + const namespaceResponse: NamespaceResponse = Object.assign(namespace || {}, { + _response: response + }); + return namespaceResponse; + } catch (err) { + log.warning("Failure parsing response from service - %0 ", err); + throw new RestError( + `Error occurred while parsing the response body - cannot form a namespace object using the response from the service.`, + RestError.PARSE_ERROR, + response.status, + stripRequest(response.request), + stripResponse(response) + ); + } + } + private buildListQueuesResponse(response: HttpOperationResponse): GetQueuesResponse { try { const queues: QueueDescription[] = []; diff --git a/sdk/servicebus/service-bus/src/util/atomXmlHelper.ts b/sdk/servicebus/service-bus/src/util/atomXmlHelper.ts index 9fed25782210..30ee38b1e756 100644 --- a/sdk/servicebus/service-bus/src/util/atomXmlHelper.ts +++ b/sdk/servicebus/service-bus/src/util/atomXmlHelper.ts @@ -1,6 +1,3 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. From fece1008283e8967a6f9a290d3ed1f165bea4475 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 17:39:02 -0700 Subject: [PATCH 28/61] namespace info improvement + API report --- .../service-bus/review/service-bus.api.md | 20 ++++++++++ sdk/servicebus/service-bus/src/index.ts | 2 + .../namespaceResourceSerializer.ts | 39 ++++++++++++++++--- .../src/serviceBusAtomManagementClient.ts | 3 +- 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index fe98b3aaf868..10cfeec2e1b8 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -122,6 +122,11 @@ export type EntityStatus = "Active" | "Creating" | "Deleting" | "ReceiveDisabled export interface GetMessageIteratorOptions extends OperationOptions, WaitTimeOptions { } +// @public +export interface GetNamespaceResponse extends NamespaceProperties { + _response: HttpOperationResponse; +} + // @public export interface GetQueueResponse extends QueueDescription { _response: HttpOperationResponse; @@ -222,6 +227,20 @@ export interface MessageHandlers { export { MessagingError } +// @public (undocumented) +export interface NamespaceProperties { + // (undocumented) + createdOn: string; + // (undocumented) + messagingSku: string; + // (undocumented) + name: string; + // (undocumented) + namespaceType: string; + // (undocumented) + updatedOn: string; +} + // @public export interface OperationOptions { abortSignal?: AbortSignalLike; @@ -370,6 +389,7 @@ export class ServiceBusManagementClient extends ServiceClient { deleteRule(topicName: string, subscriptionName: string, ruleName: string): Promise; deleteSubscription(topicName: string, subscriptionName: string): Promise; deleteTopic(topicName: string): Promise; + getNamespaceProperties(): Promise; getQueue(queueName: string): Promise; getQueueRuntimeInfo(queueName: string): Promise; getQueues(listRequestOptions?: ListRequestOptions): Promise; diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index bcbde5f2f3b2..8a4cbb5b9fc7 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -47,6 +47,7 @@ export { ServiceBusClient } from "./serviceBusClient"; export { QueueDescription, QueueRuntimeInfo } from "./serializers/queueResourceSerializer"; export { TopicDescription, TopicRuntimeInfo } from "./serializers/topicResourceSerializer"; +export { NamespaceProperties } from "./serializers/namespaceResourceSerializer"; export { SubscriptionDescription, SubscriptionRuntimeInfo @@ -79,6 +80,7 @@ export { GetSubscriptionRuntimeInfoResponse, GetSubscriptionsRuntimeInfoResponse, GetTopicsResponse, + GetNamespaceResponse, UpdateQueueResponse, UpdateRuleResponse, UpdateSubscriptionResponse, diff --git a/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts index 5d25942b0ba4..11d9cc05686e 100644 --- a/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts @@ -7,15 +7,39 @@ import { deserializeAtomXmlResponse } from "../util/atomXmlHelper"; import { HttpOperationResponse } from "@azure/core-http"; -import { getString } from "../util/utils"; +import { getString, getInteger } from "../util/utils"; -// TODO: Add docs for the attributes and for the interface +/** + * Represents the metadata related to a service bus namespace. + * + * @export + * @interface NamespaceProperties + */ export interface NamespaceProperties { createdOn: string; + /** + * The SKU/tier of the namespace. + * "Basic", "Standard" and "Premium" + */ messagingSku: string; + /** + * The last time at which the namespace was modified. + */ updatedOn: string; + /** + * Name of the namespace. + */ name: string; + /** + * Type of entities present in the namespace. + */ namespaceType: string; + /** + * Number of messaging units allocated for namespace. + * Valid only for Premium namespaces. + * messagingUnits would be set to `undefined` for Basic and Standard namespaces. + */ + messagingUnits: number | undefined; } /** @@ -26,19 +50,24 @@ export interface NamespaceProperties { * @param rawNamespace */ export function buildNamespace(rawNamespace: any): NamespaceProperties { + const messagingSku = getString(rawNamespace["MessagingSKU"], "messagingSku"); return { createdOn: getString(rawNamespace["CreatedTime"], "createdOn"), - messagingSku: getString(rawNamespace["MessagingSKU"], "messagingSku"), + messagingSku: messagingSku, updatedOn: getString(rawNamespace["ModifiedTime"], "updatedOn"), name: getString(rawNamespace["Name"], "name"), - namespaceType: getString(rawNamespace["NamespaceType"], "namespaceType") + namespaceType: getString(rawNamespace["NamespaceType"], "namespaceType"), + messagingUnits: + messagingSku === "Premium" + ? getInteger(rawNamespace["MessagingUnits"], "messagingUnits") + : undefined }; } /** * @internal * @ignore - * Atom XML Serializer for Queues. + * Atom XML Serializer for Namespaces. */ export class NamespaceResourceSerializer implements AtomXmlSerializer { serialize(): object { diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index fb0d8ae3a030..267a0754f264 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -524,12 +524,11 @@ export class ServiceBusManagementClient extends ServiceClient { } /** - * Returns an object representing the Queue with the given name along with all its properties + * Returns an object representing the metadata related to a service bus namespace. * @param queueName * */ async getNamespaceProperties(): Promise { - //Promise { log.httpAtomXml(`Performing management operation - getNamespaceProperties()`); const response: HttpOperationResponse = await this.getResource( "$namespaceinfo", From ea5f1d5811b0e33ae32ed8803044a6cced43c550 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 17:43:00 -0700 Subject: [PATCH 29/61] fix warnings in the API report --- sdk/servicebus/service-bus/review/service-bus.api.md | 7 ++----- .../src/serializers/namespaceResourceSerializer.ts | 3 +++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 10cfeec2e1b8..ac957abce7fb 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -227,17 +227,14 @@ export interface MessageHandlers { export { MessagingError } -// @public (undocumented) +// @public export interface NamespaceProperties { // (undocumented) createdOn: string; - // (undocumented) messagingSku: string; - // (undocumented) + messagingUnits: number | undefined; name: string; - // (undocumented) namespaceType: string; - // (undocumented) updatedOn: string; } diff --git a/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts index 11d9cc05686e..009200650bdf 100644 --- a/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts @@ -16,6 +16,9 @@ import { getString, getInteger } from "../util/utils"; * @interface NamespaceProperties */ export interface NamespaceProperties { + /** + * The time at which the namespace was created. + */ createdOn: string; /** * The SKU/tier of the namespace. From adca0d25e0e889ce5ffc725cfbbef2647057c206 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Mon, 1 Jun 2020 17:44:01 -0700 Subject: [PATCH 30/61] generatre API report --- sdk/servicebus/service-bus/review/service-bus.api.md | 1 - 1 file changed, 1 deletion(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index ac957abce7fb..de0488152bc8 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -229,7 +229,6 @@ export { MessagingError } // @public export interface NamespaceProperties { - // (undocumented) createdOn: string; messagingSku: string; messagingUnits: number | undefined; From 243187d51dca0f5c313d363c5d4019b2ae6b7618 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 3 Jun 2020 15:26:16 -0700 Subject: [PATCH 31/61] resolve merge conflicts and organize imports --- .../namespaceResourceSerializer.ts | 8 +- .../src/serviceBusAtomManagementClient.ts | 200 ++++++++++++++---- 2 files changed, 164 insertions(+), 44 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts index 009200650bdf..123b3da7b3e7 100644 --- a/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts @@ -1,13 +1,13 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { HttpOperationResponse } from "@azure/core-http"; import { AtomXmlSerializer, - serializeToAtomXmlRequest, - deserializeAtomXmlResponse + deserializeAtomXmlResponse, + serializeToAtomXmlRequest } from "../util/atomXmlHelper"; -import { HttpOperationResponse } from "@azure/core-http"; -import { getString, getInteger } from "../util/utils"; +import { getInteger, getString } from "../util/utils"; /** * Represents the metadata related to a service bus namespace. diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 2ff3a36dbe95..e73d5469cd27 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -1,67 +1,68 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { + isTokenCredential, + parseConnectionString, + SharedKeyCredential, + TokenCredential +} from "@azure/core-amqp"; import { HttpOperationResponse, + proxyPolicy, ProxySettings, RequestPolicyFactory, RestError, ServiceClient, ServiceClientOptions, - URLBuilder, - WebResource, - proxyPolicy, signingPolicy, stripRequest, - stripResponse + stripResponse, + URLBuilder, + WebResource } from "@azure/core-http"; - -import { parseConnectionString, SharedKeyCredential, TokenCredential, isTokenCredential } from "@azure/core-amqp"; - -import { AtomXmlSerializer, executeAtomXmlOperation } from "./util/atomXmlHelper"; - import * as log from "./log"; -import { SasServiceClientCredentials } from "./util/sasServiceClientCredentials"; -import * as Constants from "./util/constants"; - import { - InternalQueueOptions, - QueueDescription, - buildQueueOptions, + buildNamespace, + NamespaceProperties, + NamespaceResourceSerializer +} from "./serializers/namespaceResourceSerializer"; +import { buildQueue, + buildQueueOptions, buildQueueRuntimeInfo, - QueueRuntimeInfo, - QueueResourceSerializer + InternalQueueOptions, + QueueDescription, + QueueResourceSerializer, + QueueRuntimeInfo } from "./serializers/queueResourceSerializer"; import { - InternalTopicOptions, - TopicRuntimeInfo, - buildTopicOptions, - TopicDescription, - buildTopic, - buildTopicRuntimeInfo, - TopicResourceSerializer -} from "./serializers/topicResourceSerializer"; + buildRule, + RuleDescription, + RuleResourceSerializer +} from "./serializers/ruleResourceSerializer"; import { - InternalSubscriptionOptions, - SubscriptionDescription, - buildSubscriptionOptions, - SubscriptionRuntimeInfo, buildSubscription, + buildSubscriptionOptions, buildSubscriptionRuntimeInfo, - SubscriptionResourceSerializer + InternalSubscriptionOptions, + SubscriptionDescription, + SubscriptionResourceSerializer, + SubscriptionRuntimeInfo } from "./serializers/subscriptionResourceSerializer"; import { - RuleResourceSerializer, - RuleDescription, - buildRule -} from "./serializers/ruleResourceSerializer"; -import { isJSONLikeObject, isAbsoluteUrl } from "./util/utils"; -import { - NamespaceResourceSerializer, - buildNamespace, - NamespaceProperties -} from "./serializers/namespaceResourceSerializer"; + buildTopic, + buildTopicOptions, + buildTopicRuntimeInfo, + InternalTopicOptions, + TopicDescription, + TopicResourceSerializer, + TopicRuntimeInfo +} from "./serializers/topicResourceSerializer"; +import { AtomXmlSerializer, executeAtomXmlOperation } from "./util/atomXmlHelper"; +import * as Constants from "./util/constants"; +import { SasServiceClientCredentials } from "./util/sasServiceClientCredentials"; +import { isAbsoluteUrl, isJSONLikeObject } from "./util/utils"; /** * Options to use with ServiceBusManagementClient creation @@ -215,6 +216,26 @@ export interface GetTopicsResponse extends Array { _response: HttpOperationResponse; } +/** + * Represents result of create, get, update and delete operations on topic. + */ +export interface GetTopicRuntimeInfoResponse extends TopicRuntimeInfo { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + +/** + * Represents result of create, get, update and delete operations on topic. + */ +export interface GetTopicsRuntimeInfoResponse extends Array { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + /** * Represents result of create, get, update and delete operations on subscription. */ @@ -260,6 +281,26 @@ export interface GetSubscriptionsResponse extends Array _response: HttpOperationResponse; } +/** + * Represents result of create, get, update and delete operations on topic. + */ +export interface GetSubscriptionRuntimeInfoResponse extends SubscriptionRuntimeInfo { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + +/** + * Represents result of create, get, update and delete operations on topic. + */ +export interface GetSubscriptionsRuntimeInfoResponse extends Array { + /** + * The underlying HTTP response. + */ + _response: HttpOperationResponse; +} + /** * Represents result of create, get, update and delete operations on rule. */ @@ -505,6 +546,30 @@ export class ServiceBusManagementClient extends ServiceClient { return this.buildQueueResponse(response); } + /** + * Returns an object representing the Queue with the given name along with all its properties + * @param queueName + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityNotFoundError` when requested messaging entity does not exist, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async getQueueRuntimeInfo(queueName: string): Promise { + log.httpAtomXml(`Performing management operation - getQueue() for "${queueName}"`); + const response: HttpOperationResponse = await this.getResource( + queueName, + this.queueResourceSerializer + ); + + return this.buildQueueRuntimeInfoResponse(response); + } + /** * Lists existing queues. * @param listRequestOptions @@ -717,6 +782,30 @@ export class ServiceBusManagementClient extends ServiceClient { this.topicResourceSerializer ); + return this.buildTopicResponse(response); + } + + /** + * Returns an object representing the Topic with the given name along with all its properties + * @param topicName + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityNotFoundError` when requested messaging entity does not exist, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async getTopicRuntimeInfo(topicName: string): Promise { + log.httpAtomXml(`Performing management operation - getTopicRuntimeInfo() for "${topicName}"`); + const response: HttpOperationResponse = await this.getResource( + topicName, + this.topicResourceSerializer + ); + return this.buildTopicRuntimeInfoResponse(response); } @@ -931,6 +1020,37 @@ export class ServiceBusManagementClient extends ServiceClient { return this.buildSubscriptionResponse(response); } + /** + * Returns an object representing the Subscription with the given name along with all its properties + * @param topicName + * @param subscriptionName + * + * Following are errors that can be expected from this operation + * @throws `RestError` with code `UnauthorizedRequestError` when given request fails due to authorization problems, + * @throws `RestError` with code `MessageEntityNotFoundError` when requested messaging entity does not exist, + * @throws `RestError` with code `InvalidOperationError` when requested operation is invalid and we encounter a 403 HTTP status code, + * @throws `RestError` with code `ServerBusyError` when the request fails due to server being busy, + * @throws `RestError` with code `ServiceError` when receiving unrecognized HTTP status or for a scenarios such as + * bad requests or requests resulting in conflicting operation on the server, + * @throws `RestError` with code that is a value from the standard set of HTTP status codes as documented at + * https://docs.microsoft.com/en-us/dotnet/api/system.net.httpstatuscode?view=netframework-4.8 + */ + async getSubscription( + topicName: string, + subscriptionName: string + ): Promise { + log.httpAtomXml( + `Performing management operation - getSubscription() for "${subscriptionName}"` + ); + const fullPath = this.getSubscriptionPath(topicName, subscriptionName); + const response: HttpOperationResponse = await this.getResource( + fullPath, + this.subscriptionResourceSerializer + ); + + return this.buildSubscriptionRuntimeInfoResponse(response); + } + /** * Returns an object representing the Subscription with the given name along with all its properties * @param topicName From 1a41ea13728e823ec4f5d29ed3f2f7d45815721e Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 3 Jun 2020 15:34:40 -0700 Subject: [PATCH 32/61] fix the warnings from API report --- .../service-bus/review/service-bus.api.md | 40 ++++++++++--------- sdk/servicebus/service-bus/src/index.ts | 8 ++++ .../src/serviceBusAtomManagementClient.ts | 7 +--- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 5c3c77614a77..ce5624cb3eb2 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -176,16 +176,6 @@ export interface MessageHandlers { export { MessagingError } -// @public -export interface NamespaceProperties { - createdOn: string; - messagingSku: string; - messagingUnits: number | undefined; - name: string; - namespaceType: string; - updatedOn: string; -} - // @public export interface OperationOptions { abortSignal?: AbortSignalLike; @@ -220,9 +210,7 @@ export interface QueueResponse extends QueueDescription { _response: HttpOperationResponse; } -// Warning: (ae-internal-missing-underscore) The name "QueueRuntimeInfo" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal +// @public export interface QueueRuntimeInfo { accessedOn?: string; createdOn?: string; @@ -339,6 +327,7 @@ export interface ServiceBusClientOptions { // @public export class ServiceBusManagementClient extends ServiceClient { constructor(connectionString: string, options?: ServiceBusManagementClientOptions); + constructor(fullyQualifiedNamespace: string, credential: TokenCredential, options?: ServiceBusManagementClientOptions); createQueue(queueName: string): Promise; createQueue(queue: QueueDescription): Promise; createRule(topicName: string, subscriptionName: string, rule: RuleDescription): Promise; @@ -350,14 +339,31 @@ export class ServiceBusManagementClient extends ServiceClient { deleteRule(topicName: string, subscriptionName: string, ruleName: string): Promise; deleteSubscription(topicName: string, subscriptionName: string): Promise; deleteTopic(topicName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetNamespaceResponse" needs to be exported by the entry point index.d.ts + getNamespaceProperties(): Promise; getQueue(queueName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetQueueRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getQueueRuntimeInfo(queueName: string): Promise; getQueues(listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "GetQueuesRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getQueuesRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; getRule(topicName: string, subscriptioName: string, ruleName: string): Promise; getRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; getSubscription(topicName: string, subscriptionName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetSubscriptionRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getSubscriptionRuntimeInfo(topicName: string, subscriptionName: string): Promise; getSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "GetSubscriptionsRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getSubscriptionsRuntimeInfo(topicName: string, listRequestOptions?: ListRequestOptions): Promise; getTopic(topicName: string): Promise; + // Warning: (ae-forgotten-export) The symbol "GetTopicRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getTopicRuntimeInfo(topicName: string): Promise; getTopics(listRequestOptions?: ListRequestOptions): Promise; + // Warning: (ae-forgotten-export) The symbol "GetTopicsRuntimeInfoResponse" needs to be exported by the entry point index.d.ts + getTopicsRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; + queueExists(queueName: string): Promise; + subscriptionExists(topicName: string, subscriptionName: string): Promise; + topicExists(topicName: string): Promise; updateQueue(queue: QueueDescription): Promise; updateRule(topicName: string, subscriptionName: string, rule: RuleDescription): Promise; updateSubscription(subscription: SubscriptionDescription): Promise; @@ -467,9 +473,7 @@ export interface SubscriptionResponse extends SubscriptionDescription { _response: HttpOperationResponse; } -// Warning: (ae-internal-missing-underscore) The name "SubscriptionRuntimeInfo" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal +// @public export interface SubscriptionRuntimeInfo { accessedOn?: string; createdOn: string; @@ -505,9 +509,7 @@ export interface TopicResponse extends TopicDescription { _response: HttpOperationResponse; } -// Warning: (ae-internal-missing-underscore) The name "TopicRuntimeInfo" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal +// @public export interface TopicRuntimeInfo { accessedOn?: string; createdOn?: string; diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index 175272a75d61..dbf2c43f945f 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -31,6 +31,7 @@ export { OperationOptions } from "./modelsToBeSharedWithEventHubs"; export { Receiver } from "./receivers/receiver"; export { SessionReceiver } from "./receivers/sessionReceiver"; export { Sender } from "./sender"; +export { NamespaceProperties } from "./serializers/namespaceResourceSerializer"; export { QueueDescription, QueueRuntimeInfo } from "./serializers/queueResourceSerializer"; export { RuleDescription, @@ -52,14 +53,21 @@ export { DeleteRuleResponse, DeleteSubscriptionResponse, DeleteTopicResponse, + GetNamespaceResponse, GetQueueResponse, + GetQueueRuntimeInfoResponse, GetQueuesResponse, + GetQueuesRuntimeInfoResponse, GetRuleResponse, GetRulesResponse, GetSubscriptionResponse, + GetSubscriptionRuntimeInfoResponse, GetSubscriptionsResponse, + GetSubscriptionsRuntimeInfoResponse, GetTopicResponse, + GetTopicRuntimeInfoResponse, GetTopicsResponse, + GetTopicsRuntimeInfoResponse, ListRequestOptions, QueueResponse, RuleResponse, diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index e73d5469cd27..55facbe5a5cc 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -100,12 +100,7 @@ export interface NamespaceResponse extends NamespaceProperties { /** * Represents properties of the namespace. */ -export interface GetNamespaceResponse extends NamespaceProperties { - /** - * The underlying HTTP response. - */ - _response: HttpOperationResponse; -} +export type GetNamespaceResponse = NamespaceResponse; /** * Represents result of create, get, update and delete operations on queue. From 7aa01a282eef7a4577f30ad16f9846af6152783f Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 3 Jun 2020 15:42:21 -0700 Subject: [PATCH 33/61] API report --- .../service-bus/review/service-bus.api.md | 55 ++++++++++++++++--- sdk/servicebus/service-bus/src/index.ts | 1 + 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index ce5624cb3eb2..5853a27f8a28 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -114,14 +114,27 @@ export type EntityStatus = "Active" | "Creating" | "Deleting" | "ReceiveDisabled export interface GetMessageIteratorOptions extends OperationOptions, WaitTimeOptions { } +// @public +export type GetNamespaceResponse = NamespaceResponse; + // @public export type GetQueueResponse = QueueResponse; +// @public +export interface GetQueueRuntimeInfoResponse extends QueueRuntimeInfo { + _response: HttpOperationResponse; +} + // @public export interface GetQueuesResponse extends Array { _response: HttpOperationResponse; } +// @public +export interface GetQueuesRuntimeInfoResponse extends Array { + _response: HttpOperationResponse; +} + // @public export type GetRuleResponse = RuleResponse; @@ -133,19 +146,39 @@ export interface GetRulesResponse extends Array { // @public export type GetSubscriptionResponse = SubscriptionResponse; +// @public +export interface GetSubscriptionRuntimeInfoResponse extends SubscriptionRuntimeInfo { + _response: HttpOperationResponse; +} + // @public export interface GetSubscriptionsResponse extends Array { _response: HttpOperationResponse; } +// @public +export interface GetSubscriptionsRuntimeInfoResponse extends Array { + _response: HttpOperationResponse; +} + // @public export type GetTopicResponse = TopicResponse; +// @public +export interface GetTopicRuntimeInfoResponse extends TopicRuntimeInfo { + _response: HttpOperationResponse; +} + // @public export interface GetTopicsResponse extends Array { _response: HttpOperationResponse; } +// @public +export interface GetTopicsRuntimeInfoResponse extends Array { + _response: HttpOperationResponse; +} + // @public export interface ListRequestOptions { skip?: number; @@ -176,6 +209,21 @@ export interface MessageHandlers { export { MessagingError } +// @public +export interface NamespaceProperties { + createdOn: string; + messagingSku: string; + messagingUnits: number | undefined; + name: string; + namespaceType: string; + updatedOn: string; +} + +// @public +export interface NamespaceResponse extends NamespaceProperties { + _response: HttpOperationResponse; +} + // @public export interface OperationOptions { abortSignal?: AbortSignalLike; @@ -339,27 +387,20 @@ export class ServiceBusManagementClient extends ServiceClient { deleteRule(topicName: string, subscriptionName: string, ruleName: string): Promise; deleteSubscription(topicName: string, subscriptionName: string): Promise; deleteTopic(topicName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetNamespaceResponse" needs to be exported by the entry point index.d.ts getNamespaceProperties(): Promise; getQueue(queueName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetQueueRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getQueueRuntimeInfo(queueName: string): Promise; getQueues(listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "GetQueuesRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getQueuesRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; getRule(topicName: string, subscriptioName: string, ruleName: string): Promise; getRules(topicName: string, subscriptionName: string, listRequestOptions?: ListRequestOptions): Promise; getSubscription(topicName: string, subscriptionName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetSubscriptionRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getSubscriptionRuntimeInfo(topicName: string, subscriptionName: string): Promise; getSubscriptions(topicName: string, listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "GetSubscriptionsRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getSubscriptionsRuntimeInfo(topicName: string, listRequestOptions?: ListRequestOptions): Promise; getTopic(topicName: string): Promise; - // Warning: (ae-forgotten-export) The symbol "GetTopicRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getTopicRuntimeInfo(topicName: string): Promise; getTopics(listRequestOptions?: ListRequestOptions): Promise; - // Warning: (ae-forgotten-export) The symbol "GetTopicsRuntimeInfoResponse" needs to be exported by the entry point index.d.ts getTopicsRuntimeInfo(listRequestOptions?: ListRequestOptions): Promise; queueExists(queueName: string): Promise; subscriptionExists(topicName: string, subscriptionName: string): Promise; diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index dbf2c43f945f..e601354f999b 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -69,6 +69,7 @@ export { GetTopicsResponse, GetTopicsRuntimeInfoResponse, ListRequestOptions, + NamespaceResponse, QueueResponse, RuleResponse, ServiceBusManagementClient, From a67bee14b0bcaaa354c84fd993b71447213173de Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 3 Jun 2020 16:43:12 -0700 Subject: [PATCH 34/61] tests for getRuntimeInfo API for a single entity --- .../service-bus/test/atomManagement.spec.ts | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 23fbb3babed4..ae6e7e967898 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -254,6 +254,107 @@ const newManagementEntity2 = EntityNames.MANAGEMENT_NEW_ENTITY_2; }); }); +[ + { + entityType: EntityType.QUEUE, + alwaysBeExistingEntity: managementQueue1, + output: { + sizeInBytes: 0, + messageCount: 0, + messageCountDetails: { + activeMessageCount: 0, + deadLetterMessageCount: 0, + scheduledMessageCount: 0, + transferMessageCount: 0, + transferDeadLetterMessageCount: 0 + }, + name: managementQueue1 + } + }, + { + entityType: EntityType.TOPIC, + alwaysBeExistingEntity: managementTopic1, + output: { + sizeInBytes: 0, + subscriptionCount: 0, + name: managementTopic1 + } + }, + { + entityType: EntityType.SUBSCRIPTION, + alwaysBeExistingEntity: managementSubscription1, + output: { + messageCount: 0, + messageCountDetails: { + activeMessageCount: 0, + deadLetterMessageCount: 0, + scheduledMessageCount: 0, + transferMessageCount: 0, + transferDeadLetterMessageCount: 0 + }, + topicName: managementTopic1, + subscriptionName: managementSubscription1 + } + } +].forEach((testCase) => { + describe(`Atom management - Get runtime info on "${testCase.entityType}" entity`, function(): void { + beforeEach(async () => { + switch (testCase.entityType) { + case EntityType.QUEUE: + await recreateQueue(managementQueue1); + break; + + case EntityType.TOPIC: + await recreateTopic(managementTopic1); + break; + + case EntityType.SUBSCRIPTION: + await recreateTopic(managementTopic1); + await recreateSubscription(managementTopic1, managementSubscription1); + break; + + default: + throw new Error("TestError: Unrecognized EntityType"); + } + }); + + afterEach(async () => { + switch (testCase.entityType) { + case EntityType.QUEUE: + await deleteEntity(EntityType.QUEUE, managementQueue1); + break; + + case EntityType.TOPIC: + case EntityType.SUBSCRIPTION: + await deleteEntity(EntityType.TOPIC, managementTopic1); + break; + + default: + throw new Error("TestError: Unrecognized EntityType"); + } + }); + + it(`Gets runtime info for an existing ${testCase.entityType} entity(single) successfully`, async () => { + const response = await getRuntimeInfo( + testCase.entityType, + testCase.alwaysBeExistingEntity, + managementTopic1 + ); + should.equal( + response[testCase.entityType === EntityType.SUBSCRIPTION ? "subscriptionName" : "name"], + testCase.alwaysBeExistingEntity, + "Entity name mismatch" + ); + assert.deepEqualExcluding(response, testCase.output, [ + "_response", + "createdOn", + "updatedOn", + "accessedOn" + ]); + }); + }); +}); + [ { entityType: EntityType.QUEUE, @@ -1937,6 +2038,33 @@ async function getEntity( throw new Error("TestError: Unrecognized EntityType"); } +async function getRuntimeInfo( + testEntityType: EntityType, + entityPath: string, + topicPath?: string +): Promise { + switch (testEntityType) { + case EntityType.QUEUE: + const queueResponse = await serviceBusAtomManagementClient.getQueueRuntimeInfo(entityPath); + return queueResponse; + case EntityType.TOPIC: + const topicResponse = await serviceBusAtomManagementClient.getTopicRuntimeInfo(entityPath); + return topicResponse; + case EntityType.SUBSCRIPTION: + if (!topicPath) { + throw new Error( + "TestError: Topic path must be passed when invoking tests on subscriptions" + ); + } + const subscriptionResponse = await serviceBusAtomManagementClient.getSubscriptionRuntimeInfo( + topicPath, + entityPath + ); + return subscriptionResponse; + } + throw new Error("TestError: Unrecognized EntityType"); +} + async function updateEntity( testEntityType: EntityType, entityPath: string, From 887b94fe59b09776148179dfe520acd3754e9961 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 3 Jun 2020 16:54:25 -0700 Subject: [PATCH 35/61] remove messageCount from *Description APIs --- sdk/servicebus/service-bus/review/service-bus.api.md | 4 ---- .../service-bus/src/serializers/queueResourceSerializer.ts | 5 +---- .../src/serializers/subscriptionResourceSerializer.ts | 3 --- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 5853a27f8a28..37dbb5886ee9 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -244,8 +244,6 @@ export interface QueueDescription { lockDuration?: string; maxDeliveryCount?: number; maxSizeInMegabytes?: number; - // (undocumented) - messageCount?: number; name: string; requiresDuplicateDetection?: boolean; requiresSession?: boolean; @@ -500,8 +498,6 @@ export interface SubscriptionDescription { forwardTo?: string; lockDuration?: string; maxDeliveryCount?: number; - // (undocumented) - messageCount?: number; requiresSession?: boolean; status?: EntityStatus; subscriptionName: string; diff --git a/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts index b5270ba4c0ab..b797c459e6c3 100644 --- a/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/queueResourceSerializer.ts @@ -101,8 +101,7 @@ export function buildQueue(rawQueue: any): QueueDescription { authorizationRules: getAuthorizationRulesOrUndefined(rawQueue[Constants.AUTHORIZATION_RULES]), - status: rawQueue[Constants.STATUS], - messageCount: getIntegerOrUndefined(rawQueue[Constants.MESSAGE_COUNT]) + status: rawQueue[Constants.STATUS] }; } @@ -245,8 +244,6 @@ export interface QueueDescription { * `sb:///` */ forwardDeadLetteredMessagesTo?: string; - // TODO: will be removed once the RuntimeInfo APIs are added - messageCount?: number; } /** diff --git a/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts index 0854eeb1f6d1..f45a47e00814 100644 --- a/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts @@ -217,9 +217,6 @@ export interface SubscriptionDescription { * such as "PT1M" for 1 minute, "PT5S" for 5 seconds. */ autoDeleteOnIdle?: string; - - // TODO: will be removed once the RuntimeInfo APIs are added - messageCount?: number; } /** From 08701574caf4ccc2af491d8d3b82349f4f60d052 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 3 Jun 2020 23:29:23 -0700 Subject: [PATCH 36/61] remove unused helper --- sdk/servicebus/service-bus/src/util/utils.ts | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/sdk/servicebus/service-bus/src/util/utils.ts b/sdk/servicebus/service-bus/src/util/utils.ts index 5b6096f1f9b1..9d5ad7d5ab37 100644 --- a/sdk/servicebus/service-bus/src/util/utils.ts +++ b/sdk/servicebus/service-bus/src/util/utils.ts @@ -288,25 +288,6 @@ export function isJSONLikeObject(value: any): boolean { return typeof value === "object" && !(value instanceof Number) && !(value instanceof String); } -/** - * Helper method for the update APIs to verify if all the options passed in are undefined. - * - * @export - * @param {*} options - * @param {("queueName" | "topicName" | "subscriptionName")} name - * @returns - */ -export function areOptionsUndefined( - options: any, - name: "queueName" | "topicName" | "subscriptionName" -) { - for (const [key, value] of Object.entries(options)) { - if (key != name && value != undefined) { - return false; - } - } - return true; -} /** * @internal * @ignore From e44d9091bbbb1cdb76eca06cb99cff48c40a2142 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Wed, 3 Jun 2020 23:47:59 -0700 Subject: [PATCH 37/61] test for Get namespace properties --- .../src/serializers/namespaceResourceSerializer.ts | 2 +- .../service-bus/test/atomManagement.spec.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts index 123b3da7b3e7..484819af0f93 100644 --- a/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts +++ b/sdk/servicebus/service-bus/src/serializers/namespaceResourceSerializer.ts @@ -78,6 +78,6 @@ export class NamespaceResourceSerializer implements AtomXmlSerializer { } async deserialize(response: HttpOperationResponse): Promise { - return deserializeAtomXmlResponse(["Name"], response); + return deserializeAtomXmlResponse(["name"], response); } } diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index ae6e7e967898..3961d2c41d8f 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -55,6 +55,17 @@ const managementRule2 = EntityNames.MANAGEMENT_RULE_2; const newManagementEntity1 = EntityNames.MANAGEMENT_NEW_ENTITY_1; const newManagementEntity2 = EntityNames.MANAGEMENT_NEW_ENTITY_2; +describe("Atom management - Namespace", function(): void { + it("Get namespace properties", async () => { + const namespaceProperties = await serviceBusAtomManagementClient.getNamespaceProperties(); + assert.deepEqualExcluding( + namespaceProperties, + { messagingSku: "Standard", namespaceType: "Messaging", messagingUnits: undefined } as any, + ["_response", "createdOn", "updatedOn", "name"] + ); + }); +}); + [EntityType.QUEUE, EntityType.TOPIC, EntityType.SUBSCRIPTION, EntityType.RULE].forEach( (entityType) => { describe(`Atom management - List on "${entityType}" entities`, function(): void { From f8a0de7602de5d2d656b5ec915a2b452c3a19bdd Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 00:00:21 -0700 Subject: [PATCH 38/61] tests for entityExists --- .../service-bus/test/atomManagement.spec.ts | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 3961d2c41d8f..4025a0680803 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -366,6 +366,75 @@ describe("Atom management - Namespace", function(): void { }); }); +[ + { + entityType: EntityType.QUEUE, + alwaysBeExistingEntity: managementQueue1 + }, + { + entityType: EntityType.TOPIC, + alwaysBeExistingEntity: managementTopic1 + }, + { + entityType: EntityType.SUBSCRIPTION, + alwaysBeExistingEntity: managementSubscription1 + } +].forEach((testCase) => { + describe(`Atom management - "${testCase.entityType}" exists`, function(): void { + beforeEach(async () => { + switch (testCase.entityType) { + case EntityType.QUEUE: + await recreateQueue(managementQueue1); + break; + + case EntityType.TOPIC: + await recreateTopic(managementTopic1); + break; + + case EntityType.SUBSCRIPTION: + await recreateTopic(managementTopic1); + await recreateSubscription(managementTopic1, managementSubscription1); + break; + + default: + throw new Error("TestError: Unrecognized EntityType"); + } + }); + + afterEach(async () => { + switch (testCase.entityType) { + case EntityType.QUEUE: + await deleteEntity(EntityType.QUEUE, managementQueue1); + break; + + case EntityType.TOPIC: + case EntityType.SUBSCRIPTION: + await deleteEntity(EntityType.TOPIC, managementTopic1); + break; + + default: + throw new Error("TestError: Unrecognized EntityType"); + } + }); + + it(`Returns true for an existing ${testCase.entityType} entity`, async () => { + should.equal( + await entityExists(testCase.entityType, testCase.alwaysBeExistingEntity, managementTopic1), + true, + "Returned `false` for an existing entity" + ); + }); + + it(`Returns false for a non-existing ${testCase.entityType} entity`, async () => { + should.equal( + await entityExists(testCase.entityType, "non-existing-entity-name", managementTopic1), + false, + "Returned `true` for a non-existing entity" + ); + }); + }); +}); + [ { entityType: EntityType.QUEUE, @@ -2076,6 +2145,33 @@ async function getRuntimeInfo( throw new Error("TestError: Unrecognized EntityType"); } +async function entityExists( + testEntityType: EntityType, + entityPath: string, + topicPath?: string +): Promise { + switch (testEntityType) { + case EntityType.QUEUE: + const queueResponse = await serviceBusAtomManagementClient.queueExists(entityPath); + return queueResponse; + case EntityType.TOPIC: + const topicResponse = await serviceBusAtomManagementClient.topicExists(entityPath); + return topicResponse; + case EntityType.SUBSCRIPTION: + if (!topicPath) { + throw new Error( + "TestError: Topic path must be passed when invoking tests on subscriptions" + ); + } + const subscriptionResponse = await serviceBusAtomManagementClient.subscriptionExists( + topicPath, + entityPath + ); + return subscriptionResponse; + } + throw new Error("TestError: Unrecognized EntityType"); +} + async function updateEntity( testEntityType: EntityType, entityPath: string, From ee59bda3a61e306e445f4f19a9a353f3ec34185a Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 00:45:44 -0700 Subject: [PATCH 39/61] tests for getEntitiesRuntimeInfo --- .../src/serviceBusAtomManagementClient.ts | 2 +- .../service-bus/test/atomManagement.spec.ts | 176 +++++++++++++++++- 2 files changed, 175 insertions(+), 3 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 55facbe5a5cc..bb227aeaca0f 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -1727,7 +1727,7 @@ export class ServiceBusManagementClient extends ServiceClient { } const rawTopicArray: any = response.parsedBody; for (let i = 0; i < rawTopicArray.length; i++) { - const topic = buildTopic(rawTopicArray[i]); + const topic = buildTopicRuntimeInfo(rawTopicArray[i]); if (topic) { topics.push(topic); } diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 4025a0680803..dcdb2692d4ec 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -346,7 +346,7 @@ describe("Atom management - Namespace", function(): void { }); it(`Gets runtime info for an existing ${testCase.entityType} entity(single) successfully`, async () => { - const response = await getRuntimeInfo( + const response = await getEntityRuntimeInfo( testCase.entityType, testCase.alwaysBeExistingEntity, managementTopic1 @@ -366,6 +366,153 @@ describe("Atom management - Namespace", function(): void { }); }); +[ + { + entityType: EntityType.QUEUE, + 1: { + alwaysBeExistingEntity: managementQueue1, + output: { + sizeInBytes: 0, + messageCount: 0, + messageCountDetails: { + activeMessageCount: 0, + deadLetterMessageCount: 0, + scheduledMessageCount: 0, + transferMessageCount: 0, + transferDeadLetterMessageCount: 0 + }, + name: managementQueue1 + } + }, + 2: { + alwaysBeExistingEntity: managementQueue2, + output: { + sizeInBytes: 0, + messageCount: 0, + messageCountDetails: { + activeMessageCount: 0, + deadLetterMessageCount: 0, + scheduledMessageCount: 0, + transferMessageCount: 0, + transferDeadLetterMessageCount: 0 + }, + name: managementQueue2 + } + } + }, + { + entityType: EntityType.TOPIC, + 1: { + alwaysBeExistingEntity: managementTopic1, + output: { + sizeInBytes: 0, + subscriptionCount: 0, + name: managementTopic1 + } + }, + 2: { + alwaysBeExistingEntity: managementTopic2, + output: { + sizeInBytes: 0, + subscriptionCount: 0, + name: managementTopic2 + } + } + }, + { + entityType: EntityType.SUBSCRIPTION, + 1: { + alwaysBeExistingEntity: managementSubscription1, + output: { + messageCount: 0, + messageCountDetails: { + activeMessageCount: 0, + deadLetterMessageCount: 0, + scheduledMessageCount: 0, + transferMessageCount: 0, + transferDeadLetterMessageCount: 0 + }, + topicName: managementTopic1, + subscriptionName: managementSubscription1 + } + }, + 2: { + alwaysBeExistingEntity: managementSubscription2, + output: { + messageCount: 0, + messageCountDetails: { + activeMessageCount: 0, + deadLetterMessageCount: 0, + scheduledMessageCount: 0, + transferMessageCount: 0, + transferDeadLetterMessageCount: 0 + }, + topicName: managementTopic1, + subscriptionName: managementSubscription2 + } + } + } +].forEach((testCase) => { + describe(`Atom management - Get runtime info on "${testCase.entityType}" entities`, function(): void { + beforeEach(async () => { + switch (testCase.entityType) { + case EntityType.QUEUE: + await recreateQueue(managementQueue1); + await recreateQueue(managementQueue2); + break; + + case EntityType.TOPIC: + await recreateTopic(managementTopic1); + await recreateTopic(managementTopic2); + break; + + case EntityType.SUBSCRIPTION: + await recreateTopic(managementTopic1); + await recreateSubscription(managementTopic1, managementSubscription1); + await recreateSubscription(managementTopic1, managementSubscription2); + break; + + default: + throw new Error("TestError: Unrecognized EntityType"); + } + }); + + afterEach(async () => { + switch (testCase.entityType) { + case EntityType.QUEUE: + await deleteEntity(EntityType.QUEUE, managementQueue1); + await deleteEntity(EntityType.QUEUE, managementQueue2); + break; + + case EntityType.TOPIC: + await deleteEntity(EntityType.TOPIC, managementTopic1); + await deleteEntity(EntityType.TOPIC, managementTopic2); + break; + + case EntityType.SUBSCRIPTION: + await deleteEntity(EntityType.TOPIC, managementTopic1); + break; + + default: + throw new Error("TestError: Unrecognized EntityType"); + } + }); + + it(`Gets runtime info for existing ${testCase.entityType} entities(multiple) successfully`, async () => { + const response = await getEntitiesRuntimeInfo(testCase.entityType, managementTopic1); + const name = testCase.entityType === EntityType.SUBSCRIPTION ? "subscriptionName" : "name"; + const paramsToExclude = ["createdOn", "accessedOn", "updatedOn"]; + for (const info of response) { + if (info[name] == testCase[1].alwaysBeExistingEntity) { + assert.deepEqualExcluding(info, testCase[1].output, paramsToExclude); + } else if (info[name] == testCase[2].alwaysBeExistingEntity) { + assert.deepEqualExcluding(info, testCase[2].output, paramsToExclude); + } + } + }); + }); +}); + [ { entityType: EntityType.QUEUE, @@ -2118,7 +2265,7 @@ async function getEntity( throw new Error("TestError: Unrecognized EntityType"); } -async function getRuntimeInfo( +async function getEntityRuntimeInfo( testEntityType: EntityType, entityPath: string, topicPath?: string @@ -2145,6 +2292,31 @@ async function getRuntimeInfo( throw new Error("TestError: Unrecognized EntityType"); } +async function getEntitiesRuntimeInfo( + testEntityType: EntityType, + topicPath?: string +): Promise { + switch (testEntityType) { + case EntityType.QUEUE: + const queueResponse = await serviceBusAtomManagementClient.getQueuesRuntimeInfo(); + return queueResponse; + case EntityType.TOPIC: + const topicResponse = await serviceBusAtomManagementClient.getTopicsRuntimeInfo(); + return topicResponse; + case EntityType.SUBSCRIPTION: + if (!topicPath) { + throw new Error( + "TestError: Topic path must be passed when invoking tests on subscriptions" + ); + } + const subscriptionResponse = await serviceBusAtomManagementClient.getSubscriptionsRuntimeInfo( + topicPath + ); + return subscriptionResponse; + } + throw new Error("TestError: Unrecognized EntityType"); +} + async function entityExists( testEntityType: EntityType, entityPath: string, From 50c22a55f34fa5e4d2a89370aeed83e7893f9b82 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 00:50:49 -0700 Subject: [PATCH 40/61] Add changelog --- sdk/servicebus/service-bus/CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/servicebus/service-bus/CHANGELOG.md b/sdk/servicebus/service-bus/CHANGELOG.md index 8364539b86b5..fc21c380005b 100644 --- a/sdk/servicebus/service-bus/CHANGELOG.md +++ b/sdk/servicebus/service-bus/CHANGELOG.md @@ -4,6 +4,8 @@ - Improves the performance of the `ServiceBusMessageBatch.tryAdd` method. [PR 8772](https://github.com/Azure/azure-sdk-for-js/pull/8772) +- Added management api features which allows CRUD operations on the entities of a namespace. + [PR 9221](https://github.com/Azure/azure-sdk-for-js/pull/9221) ## 7.0.0-preview.2 (2020-05-05) From e23aa2b2d6fe445a0e2188fb8e3773d596e0d82e Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 00:51:42 -0700 Subject: [PATCH 41/61] Changelog --- sdk/servicebus/service-bus/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/servicebus/service-bus/CHANGELOG.md b/sdk/servicebus/service-bus/CHANGELOG.md index fc21c380005b..08eb88f6c8aa 100644 --- a/sdk/servicebus/service-bus/CHANGELOG.md +++ b/sdk/servicebus/service-bus/CHANGELOG.md @@ -5,6 +5,7 @@ - Improves the performance of the `ServiceBusMessageBatch.tryAdd` method. [PR 8772](https://github.com/Azure/azure-sdk-for-js/pull/8772) - Added management api features which allows CRUD operations on the entities of a namespace. + [PR 9116](https://github.com/Azure/azure-sdk-for-js/pull/9116) [PR 9221](https://github.com/Azure/azure-sdk-for-js/pull/9221) ## 7.0.0-preview.2 (2020-05-05) From d11567d31a8e7991b9549b6262f2d0eb2241e81c Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 12:19:12 -0700 Subject: [PATCH 42/61] tokenProvider attempt to fix --- .../src/serviceBusAtomManagementClient.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index bb227aeaca0f..06d699991100 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -366,9 +366,9 @@ export class ServiceBusManagementClient extends ServiceClient { private ruleResourceSerializer: AtomXmlSerializer; /** - * SAS token provider used to generate tokens as required for the various operations. + * Token provider used to generate tokens as required for the various operations. */ - private sasTokenProvider: SharedKeyCredential | TokenCredential; + private tokenProvider: SharedKeyCredential | TokenCredential; /** * Initializes a new instance of the ServiceBusManagementClient class. @@ -406,7 +406,7 @@ export class ServiceBusManagementClient extends ServiceClient { requestPolicyFactories: requestPolicyFactories }; super(credentialOrOptions2, serviceClientOptions); - this.sasTokenProvider = credentialOrOptions2; + this.tokenProvider = credentialOrOptions2; this.endpoint = fullyQualifiedNamespaceOrConnectionString1; this.endpointWithProtocol = "sb://" + fullyQualifiedNamespaceOrConnectionString1; } else { @@ -437,7 +437,7 @@ export class ServiceBusManagementClient extends ServiceClient { this.endpoint = (connectionString.match("Endpoint=.*://(.*)/;") || "")[1]; this.endpointWithProtocol = connectionStringObj.Endpoint; - this.sasTokenProvider = new SharedKeyCredential( + this.tokenProvider = new SharedKeyCredential( connectionStringObj.SharedAccessKeyName, connectionStringObj.SharedAccessKey ); @@ -1455,7 +1455,10 @@ export class ServiceBusManagementClient extends ServiceClient { queueOrSubscriptionFields.ForwardTo || queueOrSubscriptionFields.ForwardDeadLetteredMessagesTo ) { - const token = (await this.sasTokenProvider.getToken(this.endpoint))!.token; + const token = + this.tokenProvider instanceof SharedKeyCredential + ? this.tokenProvider.getToken(this.endpoint)!.token + : (await this.tokenProvider.getToken([]))!.token; if (queueOrSubscriptionFields.ForwardTo) { webResource.headers.set("ServiceBusSupplementaryAuthorization", token); if (!isAbsoluteUrl(queueOrSubscriptionFields.ForwardTo)) { From 5ff994e7725e94a45076085eb0385b6d40befd28 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 15:28:13 -0700 Subject: [PATCH 43/61] added servicebus scope in the getToken attribute --- .../service-bus/src/serviceBusAtomManagementClient.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 06d699991100..ffb9db036241 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -1458,7 +1458,9 @@ export class ServiceBusManagementClient extends ServiceClient { const token = this.tokenProvider instanceof SharedKeyCredential ? this.tokenProvider.getToken(this.endpoint)!.token - : (await this.tokenProvider.getToken([]))!.token; + : (await this.tokenProvider.getToken([ + "https://servicebus.azure.net//user_impersonation" + ]))!.token; if (queueOrSubscriptionFields.ForwardTo) { webResource.headers.set("ServiceBusSupplementaryAuthorization", token); if (!isAbsoluteUrl(queueOrSubscriptionFields.ForwardTo)) { From 4ce81efce248a82b8eb49e023c98e25fcc07cb4d Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 16:18:00 -0700 Subject: [PATCH 44/61] mark "@azure/identity" as external --- sdk/servicebus/service-bus/rollup.base.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/servicebus/service-bus/rollup.base.config.js b/sdk/servicebus/service-bus/rollup.base.config.js index 8f53410ffc34..3850e09b1696 100644 --- a/sdk/servicebus/service-bus/rollup.base.config.js +++ b/sdk/servicebus/service-bus/rollup.base.config.js @@ -79,7 +79,8 @@ export function nodeConfig({ test = false, production = false } = {}) { "fs", "path", "@azure/arm-servicebus", - "@azure/ms-rest-nodeauth" + "@azure/ms-rest-nodeauth", + "@azure/identity" ); baseConfig.onwarn = ignoreKnownWarnings; From bd19e383212880fc89da861a47ce5420d8b58e7c Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 20:52:30 -0700 Subject: [PATCH 45/61] Token credential --- .../src/serviceBusAtomManagementClient.ts | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index ce752105f50a..4c8765f7c45f 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -19,7 +19,8 @@ import { stripRequest, stripResponse, URLBuilder, - WebResource + WebResource, + bearerTokenAuthenticationPolicy } from "@azure/core-http"; import * as log from "./log"; import { @@ -63,7 +64,7 @@ import { AtomXmlSerializer, executeAtomXmlOperation } from "./util/atomXmlHelper import * as Constants from "./util/constants"; import { SasServiceClientCredentials } from "./util/sasServiceClientCredentials"; import { isAbsoluteUrl, isJSONLikeObject } from "./util/utils"; - +import { Constants as AMQPConstants } from "@azure/core-amqp"; /** * Options to use with ServiceBusManagementClient creation */ @@ -398,17 +399,22 @@ export class ServiceBusManagementClient extends ServiceClient { options3?: ServiceBusManagementClientOptions ) { if (isTokenCredential(credentialOrOptions2)) { + const fullyQualifiedNamespace = fullyQualifiedNamespaceOrConnectionString1; + const credential = credentialOrOptions2; const requestPolicyFactories: RequestPolicyFactory[] = []; if (options3 && options3.proxySettings) { requestPolicyFactories.push(proxyPolicy(options3.proxySettings)); } + requestPolicyFactories.push( + bearerTokenAuthenticationPolicy(credential, AMQPConstants.aadServiceBusScope) + ); const serviceClientOptions: ServiceClientOptions = { requestPolicyFactories: requestPolicyFactories }; - super(credentialOrOptions2, serviceClientOptions); - this.tokenProvider = credentialOrOptions2; - this.endpoint = fullyQualifiedNamespaceOrConnectionString1; - this.endpointWithProtocol = "sb://" + fullyQualifiedNamespaceOrConnectionString1; + super(credential, serviceClientOptions); + this.tokenProvider = credential; + this.endpoint = fullyQualifiedNamespace; + this.endpointWithProtocol = "sb://" + fullyQualifiedNamespace; } else { const connectionString = fullyQualifiedNamespaceOrConnectionString1; const options = credentialOrOptions2; @@ -1467,9 +1473,7 @@ export class ServiceBusManagementClient extends ServiceClient { const token = this.tokenProvider instanceof SharedKeyCredential ? this.tokenProvider.getToken(this.endpoint)!.token - : (await this.tokenProvider.getToken([ - "https://servicebus.azure.net//user_impersonation" - ]))!.token; + : (await this.tokenProvider.getToken([]))!.token; if (queueOrSubscriptionFields.ForwardTo) { webResource.headers.set("ServiceBusSupplementaryAuthorization", token); if (!isAbsoluteUrl(queueOrSubscriptionFields.ForwardTo)) { From 988d92786a45c061974a648467935e986d3d79d9 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 20:57:54 -0700 Subject: [PATCH 46/61] test for Token credential - DefaultAzureCredential from `@azure/identity` --- .../service-bus/test/atomManagement.spec.ts | 71 +++++++++++++++---- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 46bba68ff11e..fdd2715db047 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -1,32 +1,31 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. +import { isNode, parseConnectionString } from "@azure/core-amqp"; +import { DefaultAzureCredential } from "@azure/identity"; +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; +import chaiExclude from "chai-exclude"; +import * as dotenv from "dotenv"; import { QueueDescription } from "../src/serializers/queueResourceSerializer"; -import { TopicDescription } from "../src/serializers/topicResourceSerializer"; -import { SubscriptionDescription } from "../src/serializers/subscriptionResourceSerializer"; import { RuleDescription } from "../src/serializers/ruleResourceSerializer"; -import { EntityStatus } from "../src/util/utils"; +import { SubscriptionDescription } from "../src/serializers/subscriptionResourceSerializer"; +import { TopicDescription } from "../src/serializers/topicResourceSerializer"; import { ServiceBusManagementClient } from "../src/serviceBusAtomManagementClient"; +import { EntityStatus } from "../src/util/utils"; +import { EnvVarNames, getEnvVars } from "./utils/envVarUtils"; +import { recreateQueue, recreateSubscription, recreateTopic } from "./utils/managementUtils"; +import { EntityNames } from "./utils/testUtils"; -import chai from "chai"; -import chaiAsPromised from "chai-as-promised"; -import chaiExclude from "chai-exclude"; chai.use(chaiAsPromised); chai.use(chaiExclude); const should = chai.should(); const assert = chai.assert; -import * as dotenv from "dotenv"; dotenv.config(); -import { EnvVarNames, getEnvVars } from "./utils/envVarUtils"; const env = getEnvVars(); -import { EntityNames } from "./utils/testUtils"; - -import { parseConnectionString } from "@azure/core-amqp"; -import { recreateQueue, recreateSubscription, recreateTopic } from "./utils/managementUtils"; - const serviceBusAtomManagementClient: ServiceBusManagementClient = new ServiceBusManagementClient( env[EnvVarNames.SERVICEBUS_CONNECTION_STRING] ); @@ -42,7 +41,7 @@ enum EntityType { RULE = "Rule" } -const managementQueue1 = EntityNames.MANAGEMENT_QUEUE_1; +let managementQueue1 = EntityNames.MANAGEMENT_QUEUE_1; const managementTopic1 = EntityNames.MANAGEMENT_TOPIC_1; const managementSubscription1 = EntityNames.MANAGEMENT_SUBSCRIPTION_1; const managementRule1 = EntityNames.MANAGEMENT_RULE_1; @@ -66,6 +65,50 @@ describe("Atom management - Namespace", function(): void { }); }); +describe("Atom management - Authentication", function(): void { + if (isNode) { + it("Token credential - DefaultAzureCredential from `@azure/identity`", async () => { + const host = (parseConnectionString( + env[EnvVarNames.SERVICEBUS_CONNECTION_STRING] + ) as any).Endpoint.match(".*://([^/]*)")[1]; + managementQueue1 = managementRule1; + + const serviceBusManagementClient = new ServiceBusManagementClient( + host, + new DefaultAzureCredential() + ); + + should.equal( + (await serviceBusManagementClient.createQueue(managementQueue1)).name, + managementQueue1, + "Unexpected queue name in the response" + ); + const getQueueResponse = await serviceBusManagementClient.getQueue(managementQueue1); + should.equal( + getQueueResponse.name, + managementQueue1, + "Unexpected queue name in the response" + ); + should.equal( + (await serviceBusManagementClient.updateQueue(getQueueResponse)).name, + managementQueue1, + "Unexpected queue name in the response" + ); + should.equal( + (await serviceBusManagementClient.getQueueRuntimeInfo(managementQueue1)).name, + managementQueue1, + "Unexpected queue name in the response" + ); + should.equal( + (await serviceBusManagementClient.getNamespaceProperties()).name, + host.match("(.*).servicebus.windows.net")[1], + "Unexpected namespace name in the response" + ); + await serviceBusManagementClient.deleteQueue(managementQueue1); + }); + } +}); + [EntityType.QUEUE, EntityType.TOPIC, EntityType.SUBSCRIPTION, EntityType.RULE].forEach( (entityType) => { describe(`Atom management - List on "${entityType}" entities`, function(): void { From 8fa3fb0e9521c96568c8a5b427a5fe5e4f5ae28e Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Thu, 4 Jun 2020 22:27:52 -0700 Subject: [PATCH 47/61] update the name --- sdk/servicebus/service-bus/test/atomManagement.spec.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index fdd2715db047..0657ef0808f7 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -41,7 +41,7 @@ enum EntityType { RULE = "Rule" } -let managementQueue1 = EntityNames.MANAGEMENT_QUEUE_1; +const managementQueue1 = EntityNames.MANAGEMENT_QUEUE_1; const managementTopic1 = EntityNames.MANAGEMENT_TOPIC_1; const managementSubscription1 = EntityNames.MANAGEMENT_SUBSCRIPTION_1; const managementRule1 = EntityNames.MANAGEMENT_RULE_1; @@ -71,7 +71,6 @@ describe("Atom management - Authentication", function(): void { const host = (parseConnectionString( env[EnvVarNames.SERVICEBUS_CONNECTION_STRING] ) as any).Endpoint.match(".*://([^/]*)")[1]; - managementQueue1 = managementRule1; const serviceBusManagementClient = new ServiceBusManagementClient( host, From 9ac0e4e3622ca8aafd0f2ea08018856b485389bb Mon Sep 17 00:00:00 2001 From: Harsha Nalluru Date: Fri, 5 Jun 2020 10:59:01 -0700 Subject: [PATCH 48/61] Update sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts Co-authored-by: chradek <51000525+chradek@users.noreply.github.com> --- .../service-bus/src/serviceBusAtomManagementClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 4c8765f7c45f..f40dcc3667f4 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -383,7 +383,7 @@ export class ServiceBusManagementClient extends ServiceClient { * likely to be similar to .servicebus.windows.net. * @param credential A credential object used by the client to get the token to authenticate the connection * with the Azure Service Bus. See @azure/identity for creating the credentials. - * If you're using an own implementation of the `TokenCredential` interface against AAD, then set the "scopes" for service-bus + * If you're using your own implementation of the `TokenCredential` interface against AAD, then set the "scopes" for service-bus * to be `["https://servicebus.azure.net//user_impersonation"]` to get the appropriate token. * @param options ServiceBusManagementClientOptions */ From a772c7f3f50e193daa37ff2218d61e44ae334eb2 Mon Sep 17 00:00:00 2001 From: Harsha Nalluru Date: Fri, 5 Jun 2020 11:00:00 -0700 Subject: [PATCH 49/61] Update sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts Co-authored-by: chradek <51000525+chradek@users.noreply.github.com> --- .../service-bus/src/serviceBusAtomManagementClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index f40dcc3667f4..0150598cf735 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -379,7 +379,7 @@ export class ServiceBusManagementClient extends ServiceClient { constructor(connectionString: string, options?: ServiceBusManagementClientOptions); /** * - * @param fullyQualifiedNamespace The full namespace of your Service Bus instance which is + * @param fullyQualifiedNamespace The fully qualified namespace of your Service Bus instance which is * likely to be similar to .servicebus.windows.net. * @param credential A credential object used by the client to get the token to authenticate the connection * with the Azure Service Bus. See @azure/identity for creating the credentials. From faad510a3721a56932bd06d6bf4d0224079f3e8d Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 11:07:01 -0700 Subject: [PATCH 50/61] enter one more code path in the tests for gettoken invocation --- .../service-bus/src/serviceBusAtomManagementClient.ts | 3 ++- .../service-bus/test/atomManagement.spec.ts | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 4c8765f7c45f..a1803196c063 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -1473,7 +1473,8 @@ export class ServiceBusManagementClient extends ServiceClient { const token = this.tokenProvider instanceof SharedKeyCredential ? this.tokenProvider.getToken(this.endpoint)!.token - : (await this.tokenProvider.getToken([]))!.token; + : (await this.tokenProvider.getToken([AMQPConstants.aadServiceBusScope]))!.token; + if (queueOrSubscriptionFields.ForwardTo) { webResource.headers.set("ServiceBusSupplementaryAuthorization", token); if (!isAbsoluteUrl(queueOrSubscriptionFields.ForwardTo)) { diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 0657ef0808f7..8e4978667a0c 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -82,6 +82,11 @@ describe("Atom management - Authentication", function(): void { managementQueue1, "Unexpected queue name in the response" ); + should.equal( + (await serviceBusManagementClient.createQueue(managementQueue2)).name, + managementQueue2, + "Unexpected queue name in the response" + ); const getQueueResponse = await serviceBusManagementClient.getQueue(managementQueue1); should.equal( getQueueResponse.name, @@ -93,6 +98,12 @@ describe("Atom management - Authentication", function(): void { managementQueue1, "Unexpected queue name in the response" ); + getQueueResponse.forwardTo = managementQueue2; + should.equal( + (await serviceBusManagementClient.updateQueue(getQueueResponse)).name, + managementQueue1, + "Unexpected queue name in the response" + ); should.equal( (await serviceBusManagementClient.getQueueRuntimeInfo(managementQueue1)).name, managementQueue1, From 99488c9e29855de64641494432d79aeaa5cdc576 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 11:46:18 -0700 Subject: [PATCH 51/61] refactoring the constructor as suggested by Chris and fixing tests --- .../src/serviceBusAtomManagementClient.ts | 62 +++++++++---------- .../service-bus/test/atomManagement.spec.ts | 1 + .../service-bus/test/atomXml.spec.ts | 2 +- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 2a14499e7039..a195817b5aac 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -398,56 +398,52 @@ export class ServiceBusManagementClient extends ServiceClient { credentialOrOptions2?: TokenCredential | ServiceBusManagementClientOptions, options3?: ServiceBusManagementClientOptions ) { + const requestPolicyFactories: RequestPolicyFactory[] = []; + let options: ServiceBusManagementClientOptions; + let fullyQualifiedNamespace: string; + let credentials: SasServiceClientCredentials | TokenCredential; + let tokenProvider: SharedKeyCredential | TokenCredential; if (isTokenCredential(credentialOrOptions2)) { - const fullyQualifiedNamespace = fullyQualifiedNamespaceOrConnectionString1; - const credential = credentialOrOptions2; - const requestPolicyFactories: RequestPolicyFactory[] = []; - if (options3 && options3.proxySettings) { - requestPolicyFactories.push(proxyPolicy(options3.proxySettings)); - } + fullyQualifiedNamespace = fullyQualifiedNamespaceOrConnectionString1; + options = options3 || {}; + credentials = credentialOrOptions2; requestPolicyFactories.push( - bearerTokenAuthenticationPolicy(credential, AMQPConstants.aadServiceBusScope) + bearerTokenAuthenticationPolicy(credentials, AMQPConstants.aadServiceBusScope) ); - const serviceClientOptions: ServiceClientOptions = { - requestPolicyFactories: requestPolicyFactories - }; - super(credential, serviceClientOptions); - this.tokenProvider = credential; - this.endpoint = fullyQualifiedNamespace; - this.endpointWithProtocol = "sb://" + fullyQualifiedNamespace; + tokenProvider = credentials; } else { const connectionString = fullyQualifiedNamespaceOrConnectionString1; - const options = credentialOrOptions2; + options = credentialOrOptions2 || {}; const connectionStringObj: any = parseConnectionString(connectionString); - if (connectionStringObj.Endpoint == undefined) { throw new Error("Missing Endpoint in connection string."); } - - const credentials = new SasServiceClientCredentials( + try { + fullyQualifiedNamespace = connectionStringObj.Endpoint.match(".*://([^/]*)")[1]; + } catch (error) { + throw new Error("Endpoint in the connection string is not valid."); + } + credentials = new SasServiceClientCredentials( connectionStringObj.SharedAccessKeyName, connectionStringObj.SharedAccessKey ); - - const requestPolicyFactories: RequestPolicyFactory[] = []; requestPolicyFactories.push(signingPolicy(credentials)); - - if (options && options.proxySettings) { - requestPolicyFactories.push(proxyPolicy(options.proxySettings)); - } - const serviceClientOptions: ServiceClientOptions = { - requestPolicyFactories: requestPolicyFactories - }; - - super(credentials, serviceClientOptions); - this.endpoint = (connectionString.match("Endpoint=.*://(.*)/;") || "")[1]; - this.endpointWithProtocol = connectionStringObj.Endpoint; - - this.tokenProvider = new SharedKeyCredential( + tokenProvider = new SharedKeyCredential( connectionStringObj.SharedAccessKeyName, connectionStringObj.SharedAccessKey ); } + if (options && options.proxySettings) { + requestPolicyFactories.push(proxyPolicy(options.proxySettings)); + } + const serviceClientOptions: ServiceClientOptions = { + requestPolicyFactories: requestPolicyFactories + }; + + super(credentials, serviceClientOptions); + this.endpoint = fullyQualifiedNamespace; + this.endpointWithProtocol = "sb://" + fullyQualifiedNamespace; + this.tokenProvider = tokenProvider; this.namespaceResourceSerializer = new NamespaceResourceSerializer(); this.queueResourceSerializer = new QueueResourceSerializer(); this.topicResourceSerializer = new TopicResourceSerializer(); diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 8e4978667a0c..7740aecdd56b 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -115,6 +115,7 @@ describe("Atom management - Authentication", function(): void { "Unexpected namespace name in the response" ); await serviceBusManagementClient.deleteQueue(managementQueue1); + await serviceBusManagementClient.deleteQueue(managementQueue2); }); } }); diff --git a/sdk/servicebus/service-bus/test/atomXml.spec.ts b/sdk/servicebus/service-bus/test/atomXml.spec.ts index 1e8a9537b993..bf5b38cec6a8 100644 --- a/sdk/servicebus/service-bus/test/atomXml.spec.ts +++ b/sdk/servicebus/service-bus/test/atomXml.spec.ts @@ -72,7 +72,7 @@ const subscriptionProperties = [ const ruleProperties = ["Filter", "Action", "Name"]; const mockServiceBusAtomManagementClient: ServiceBusManagementClient = new ServiceBusManagementClient( - "Endpoint=test/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=test" + "Endpoint=sb://test/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=test" ); describe("atomSerializationPolicy", function() { From 5b0e41b5325f3cfa93b99ce0e83bc848b1ddc9d4 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 13:40:18 -0700 Subject: [PATCH 52/61] fix trailing slash issue --- .../service-bus/src/serviceBusAtomManagementClient.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index a195817b5aac..8b2e79fa7988 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -441,6 +441,9 @@ export class ServiceBusManagementClient extends ServiceClient { }; super(credentials, serviceClientOptions); + fullyQualifiedNamespace = fullyQualifiedNamespace.endsWith("/") + ? fullyQualifiedNamespace + : fullyQualifiedNamespace + "/"; this.endpoint = fullyQualifiedNamespace; this.endpointWithProtocol = "sb://" + fullyQualifiedNamespace; this.tokenProvider = tokenProvider; From 298df4a9d81b9848a1b25fcfd24d772569798b26 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 13:48:23 -0700 Subject: [PATCH 53/61] Update the test to cover more cases --- .../service-bus/test/atomManagement.spec.ts | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 7740aecdd56b..9cfe21590eda 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -80,39 +80,42 @@ describe("Atom management - Authentication", function(): void { should.equal( (await serviceBusManagementClient.createQueue(managementQueue1)).name, managementQueue1, - "Unexpected queue name in the response" + "Unexpected queue name in the createQueue response" ); + const createQueue2Response = await serviceBusManagementClient.createQueue({ + name: managementQueue2, + forwardTo: managementQueue1 + }); should.equal( - (await serviceBusManagementClient.createQueue(managementQueue2)).name, + createQueue2Response.name, managementQueue2, - "Unexpected queue name in the response" + "Unexpected queue name in the createQueue response" ); - const getQueueResponse = await serviceBusManagementClient.getQueue(managementQueue1); should.equal( - getQueueResponse.name, + createQueue2Response.forwardTo, managementQueue1, - "Unexpected queue name in the response" + "Unexpected name in the `forwardTo` field of createQueue response" ); + const getQueueResponse = await serviceBusManagementClient.getQueue(managementQueue1); should.equal( - (await serviceBusManagementClient.updateQueue(getQueueResponse)).name, + getQueueResponse.name, managementQueue1, - "Unexpected queue name in the response" + "Unexpected queue name in the getQueue response" ); - getQueueResponse.forwardTo = managementQueue2; should.equal( (await serviceBusManagementClient.updateQueue(getQueueResponse)).name, managementQueue1, - "Unexpected queue name in the response" + "Unexpected queue name in the updateQueue response" ); should.equal( (await serviceBusManagementClient.getQueueRuntimeInfo(managementQueue1)).name, managementQueue1, - "Unexpected queue name in the response" + "Unexpected queue name in the getQueueRuntimeInfo response" ); should.equal( (await serviceBusManagementClient.getNamespaceProperties()).name, host.match("(.*).servicebus.windows.net")[1], - "Unexpected namespace name in the response" + "Unexpected namespace name in the getNamespaceProperties response" ); await serviceBusManagementClient.deleteQueue(managementQueue1); await serviceBusManagementClient.deleteQueue(managementQueue2); From 52477cdbf965ab045b78ad7aca661cdc4481cfc4 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 14:01:49 -0700 Subject: [PATCH 54/61] fix test for AAD --- sdk/servicebus/service-bus/test/atomManagement.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/servicebus/service-bus/test/atomManagement.spec.ts b/sdk/servicebus/service-bus/test/atomManagement.spec.ts index 9cfe21590eda..c96a0139e74b 100644 --- a/sdk/servicebus/service-bus/test/atomManagement.spec.ts +++ b/sdk/servicebus/service-bus/test/atomManagement.spec.ts @@ -68,9 +68,9 @@ describe("Atom management - Namespace", function(): void { describe("Atom management - Authentication", function(): void { if (isNode) { it("Token credential - DefaultAzureCredential from `@azure/identity`", async () => { - const host = (parseConnectionString( - env[EnvVarNames.SERVICEBUS_CONNECTION_STRING] - ) as any).Endpoint.match(".*://([^/]*)")[1]; + const endpoint = (parseConnectionString(env[EnvVarNames.SERVICEBUS_CONNECTION_STRING]) as any) + .Endpoint; + const host = endpoint.match(".*://([^/]*)")[1]; const serviceBusManagementClient = new ServiceBusManagementClient( host, @@ -93,7 +93,7 @@ describe("Atom management - Authentication", function(): void { ); should.equal( createQueue2Response.forwardTo, - managementQueue1, + endpoint + managementQueue1, "Unexpected name in the `forwardTo` field of createQueue response" ); const getQueueResponse = await serviceBusManagementClient.getQueue(managementQueue1); From a6a4b50be8248aeb66f27618b5e64ab5e5e630fa Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 14:20:26 -0700 Subject: [PATCH 55/61] remove unneeded ! --- .../service-bus/src/serviceBusAtomManagementClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 8b2e79fa7988..dcfb099e8b43 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -1471,7 +1471,7 @@ export class ServiceBusManagementClient extends ServiceClient { ) { const token = this.tokenProvider instanceof SharedKeyCredential - ? this.tokenProvider.getToken(this.endpoint)!.token + ? this.tokenProvider.getToken(this.endpoint).token : (await this.tokenProvider.getToken([AMQPConstants.aadServiceBusScope]))!.token; if (queueOrSubscriptionFields.ForwardTo) { From 8c3b5b48a03631e9d7e77cdeb03dd62673618097 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 14:27:10 -0700 Subject: [PATCH 56/61] fix endpoint and endpointWithProtocol attributes --- .../service-bus/src/serviceBusAtomManagementClient.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index dcfb099e8b43..1aef7dac05f0 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -441,11 +441,10 @@ export class ServiceBusManagementClient extends ServiceClient { }; super(credentials, serviceClientOptions); - fullyQualifiedNamespace = fullyQualifiedNamespace.endsWith("/") - ? fullyQualifiedNamespace - : fullyQualifiedNamespace + "/"; this.endpoint = fullyQualifiedNamespace; - this.endpointWithProtocol = "sb://" + fullyQualifiedNamespace; + this.endpointWithProtocol = fullyQualifiedNamespace.endsWith("/") + ? "sb://" + fullyQualifiedNamespace + : "sb://" + fullyQualifiedNamespace + "/"; this.tokenProvider = tokenProvider; this.namespaceResourceSerializer = new NamespaceResourceSerializer(); this.queueResourceSerializer = new QueueResourceSerializer(); From c037a860970b3d954a1a4b94cad82b6c9fa923d2 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 15:23:47 -0700 Subject: [PATCH 57/61] Add getToken for SasServiceCredential --- .../service-bus/src/util/sasServiceClientCredentials.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sdk/servicebus/service-bus/src/util/sasServiceClientCredentials.ts b/sdk/servicebus/service-bus/src/util/sasServiceClientCredentials.ts index 4a5d0359769a..173dddb6c745 100644 --- a/sdk/servicebus/service-bus/src/util/sasServiceClientCredentials.ts +++ b/sdk/servicebus/service-bus/src/util/sasServiceClientCredentials.ts @@ -4,6 +4,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +import { AccessToken, SharedKeyCredential } from "@azure/core-amqp"; import { HttpHeaders, ServiceClientCredentials, WebResource } from "@azure/core-http"; import { generateKey } from "./crypto"; @@ -57,4 +58,8 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { webResource.withCredentials = true; return webResource; } + + getToken(audience: string): AccessToken { + return new SharedKeyCredential(this.keyName, this.keyValue).getToken(audience); + } } From 082afc44ceb354b0d4f183f7cf19a30dd5b3d5eb Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 15:24:14 -0700 Subject: [PATCH 58/61] merge tokenProvider into credentials --- .../src/serviceBusAtomManagementClient.ts | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts index 1aef7dac05f0..07a7c316a548 100644 --- a/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusAtomManagementClient.ts @@ -1,12 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import { - isTokenCredential, - parseConnectionString, - SharedKeyCredential, - TokenCredential -} from "@azure/core-amqp"; +import { isTokenCredential, parseConnectionString, TokenCredential } from "@azure/core-amqp"; import { HttpOperationResponse, proxyPolicy, @@ -367,9 +362,9 @@ export class ServiceBusManagementClient extends ServiceClient { private ruleResourceSerializer: AtomXmlSerializer; /** - * Token provider used to generate tokens as required for the various operations. + * Credentials used to generate tokens as required for the various operations. */ - private tokenProvider: SharedKeyCredential | TokenCredential; + private credentials: SasServiceClientCredentials | TokenCredential; /** * Initializes a new instance of the ServiceBusManagementClient class. @@ -402,7 +397,6 @@ export class ServiceBusManagementClient extends ServiceClient { let options: ServiceBusManagementClientOptions; let fullyQualifiedNamespace: string; let credentials: SasServiceClientCredentials | TokenCredential; - let tokenProvider: SharedKeyCredential | TokenCredential; if (isTokenCredential(credentialOrOptions2)) { fullyQualifiedNamespace = fullyQualifiedNamespaceOrConnectionString1; options = options3 || {}; @@ -410,7 +404,6 @@ export class ServiceBusManagementClient extends ServiceClient { requestPolicyFactories.push( bearerTokenAuthenticationPolicy(credentials, AMQPConstants.aadServiceBusScope) ); - tokenProvider = credentials; } else { const connectionString = fullyQualifiedNamespaceOrConnectionString1; options = credentialOrOptions2 || {}; @@ -428,10 +421,6 @@ export class ServiceBusManagementClient extends ServiceClient { connectionStringObj.SharedAccessKey ); requestPolicyFactories.push(signingPolicy(credentials)); - tokenProvider = new SharedKeyCredential( - connectionStringObj.SharedAccessKeyName, - connectionStringObj.SharedAccessKey - ); } if (options && options.proxySettings) { requestPolicyFactories.push(proxyPolicy(options.proxySettings)); @@ -445,7 +434,7 @@ export class ServiceBusManagementClient extends ServiceClient { this.endpointWithProtocol = fullyQualifiedNamespace.endsWith("/") ? "sb://" + fullyQualifiedNamespace : "sb://" + fullyQualifiedNamespace + "/"; - this.tokenProvider = tokenProvider; + this.credentials = credentials; this.namespaceResourceSerializer = new NamespaceResourceSerializer(); this.queueResourceSerializer = new QueueResourceSerializer(); this.topicResourceSerializer = new TopicResourceSerializer(); @@ -1469,9 +1458,9 @@ export class ServiceBusManagementClient extends ServiceClient { queueOrSubscriptionFields.ForwardDeadLetteredMessagesTo ) { const token = - this.tokenProvider instanceof SharedKeyCredential - ? this.tokenProvider.getToken(this.endpoint).token - : (await this.tokenProvider.getToken([AMQPConstants.aadServiceBusScope]))!.token; + this.credentials instanceof SasServiceClientCredentials + ? this.credentials.getToken(this.endpoint).token + : (await this.credentials.getToken([AMQPConstants.aadServiceBusScope]))!.token; if (queueOrSubscriptionFields.ForwardTo) { webResource.headers.set("ServiceBusSupplementaryAuthorization", token); From 781c41d06e652569584acdec904acbd7c9bb11ae Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 15:26:08 -0700 Subject: [PATCH 59/61] remove "@azure/ms-rest-nodeauth" from the external list in rollup config for tests --- sdk/servicebus/service-bus/rollup.base.config.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/sdk/servicebus/service-bus/rollup.base.config.js b/sdk/servicebus/service-bus/rollup.base.config.js index 3850e09b1696..5b5832ef00d4 100644 --- a/sdk/servicebus/service-bus/rollup.base.config.js +++ b/sdk/servicebus/service-bus/rollup.base.config.js @@ -74,14 +74,7 @@ export function nodeConfig({ test = false, production = false } = {}) { baseConfig.output.file = "test-dist/index.js"; // mark assert as external - baseConfig.external.push( - "assert", - "fs", - "path", - "@azure/arm-servicebus", - "@azure/ms-rest-nodeauth", - "@azure/identity" - ); + baseConfig.external.push("assert", "fs", "path", "@azure/arm-servicebus", "@azure/identity"); baseConfig.onwarn = ignoreKnownWarnings; From 1df7bd2b28f0152e63346f5d08e503ceace5c087 Mon Sep 17 00:00:00 2001 From: Harsha Nalluru Date: Fri, 5 Jun 2020 15:32:30 -0700 Subject: [PATCH 60/61] Update sdk/servicebus/service-bus/rollup.base.config.js Co-authored-by: Ramya Rao --- sdk/servicebus/service-bus/rollup.base.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/servicebus/service-bus/rollup.base.config.js b/sdk/servicebus/service-bus/rollup.base.config.js index 5b5832ef00d4..7f6e6db2b7a4 100644 --- a/sdk/servicebus/service-bus/rollup.base.config.js +++ b/sdk/servicebus/service-bus/rollup.base.config.js @@ -74,7 +74,7 @@ export function nodeConfig({ test = false, production = false } = {}) { baseConfig.output.file = "test-dist/index.js"; // mark assert as external - baseConfig.external.push("assert", "fs", "path", "@azure/arm-servicebus", "@azure/identity"); + baseConfig.external.push("assert", "fs", "path", "@azure/identity"); baseConfig.onwarn = ignoreKnownWarnings; From 518e6965138696ac3c1f8ac57132b4321e89d279 Mon Sep 17 00:00:00 2001 From: HarshaNalluru Date: Fri, 5 Jun 2020 15:37:09 -0700 Subject: [PATCH 61/61] private sharedKeyCredential --- .../service-bus/src/util/sasServiceClientCredentials.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sdk/servicebus/service-bus/src/util/sasServiceClientCredentials.ts b/sdk/servicebus/service-bus/src/util/sasServiceClientCredentials.ts index 173dddb6c745..496546d59e1e 100644 --- a/sdk/servicebus/service-bus/src/util/sasServiceClientCredentials.ts +++ b/sdk/servicebus/service-bus/src/util/sasServiceClientCredentials.ts @@ -17,7 +17,7 @@ import { generateKey } from "./crypto"; export class SasServiceClientCredentials implements ServiceClientCredentials { keyName: string; keyValue: string; - + private sharedKeyCredential: SharedKeyCredential; /** * Creates a new sasServiceClientCredentials object. * @@ -28,6 +28,7 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { constructor(sharedAccessKeyName: string, sharedAccessKey: string) { this.keyName = sharedAccessKeyName; this.keyValue = sharedAccessKey; + this.sharedKeyCredential = new SharedKeyCredential(this.keyName, this.keyValue); } private async _generateSignature(targetUri: string, expirationDate: number): Promise { @@ -60,6 +61,6 @@ export class SasServiceClientCredentials implements ServiceClientCredentials { } getToken(audience: string): AccessToken { - return new SharedKeyCredential(this.keyName, this.keyValue).getToken(audience); + return this.sharedKeyCredential.getToken(audience); } }