From 7797d023dccfae56cfcb735a07dd601c1bb22daa Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Tue, 20 Oct 2020 17:44:03 -0700 Subject: [PATCH 1/8] [Service Bus] Move settlement methods to receiver --- .../service-bus/review/service-bus.api.md | 60 +- .../instrumentServiceBusMessage.ts | 4 +- sdk/servicebus/service-bus/src/index.ts | 1 - sdk/servicebus/service-bus/src/models.ts | 8 +- .../service-bus/src/receivers/receiver.ts | 200 +++++- .../src/receivers/sessionReceiver.ts | 69 +- .../service-bus/src/receivers/shared.ts | 11 +- .../service-bus/src/serviceBusClient.ts | 63 +- .../service-bus/src/serviceBusMessage.ts | 128 +--- sdk/servicebus/service-bus/test/auth.spec.ts | 3 +- .../test/backupMessageSettlement.spec.ts | 672 +++++++++--------- .../service-bus/test/batchReceiver.spec.ts | 109 ++- .../service-bus/test/deferredMessage.spec.ts | 24 +- .../test/internal/receiver.spec.ts | 11 +- .../test/internal/serviceBusClient.spec.ts | 8 +- .../service-bus/test/internal/shared.spec.ts | 12 +- .../test/invalidParameters.spec.ts | 3 +- .../service-bus/test/managementClient.spec.ts | 4 +- .../service-bus/test/propsToModify.spec.ts | 58 +- .../test/receiveAndDeleteMode.spec.ts | 32 +- .../service-bus/test/renewLock.spec.ts | 24 +- .../test/renewLockSessions.spec.ts | 30 +- .../service-bus/test/retries.spec.ts | 27 +- .../service-bus/test/sendAndSchedule.spec.ts | 19 +- .../service-bus/test/serviceBusClient.spec.ts | 20 +- .../sessionsRequiredCleanEntityTests.spec.ts | 11 +- .../service-bus/test/sessionsTests.spec.ts | 13 +- .../service-bus/test/smoketest.spec.ts | 21 +- .../test/streamingReceiver.spec.ts | 100 ++- .../test/streamingReceiverSessions.spec.ts | 90 ++- .../service-bus/test/utils/testutils2.ts | 35 +- 31 files changed, 919 insertions(+), 951 deletions(-) diff --git a/sdk/servicebus/service-bus/review/service-bus.api.md b/sdk/servicebus/service-bus/review/service-bus.api.md index 914ebfe386c4..862638085a71 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -34,7 +34,7 @@ export interface AmqpAnnotatedMessage { applicationProperties?: { [key: string]: any; }; - body: any; + body?: any; deliveryAnnotations?: { [key: string]: any; }; @@ -192,9 +192,9 @@ export interface GetMessageIteratorOptions extends OperationOptionsBase { } // @public -export interface MessageHandlers { +export interface MessageHandlers { processError(err: Error): Promise; - processMessage(message: ReceivedMessageT): Promise; + processMessage(message: ServiceBusReceivedMessage): Promise; } export { MessagingError } @@ -337,19 +337,19 @@ export class ServiceBusAdministrationClient extends ServiceClient { export class ServiceBusClient { constructor(connectionString: string, options?: ServiceBusClientOptions); constructor(fullyQualifiedNamespace: string, credential: TokenCredential, options?: ServiceBusClientOptions); - acceptNextSession(queueName: string, options?: AcceptSessionOptions<"peekLock">): Promise>; - acceptNextSession(queueName: string, options: AcceptSessionOptions<"receiveAndDelete">): Promise>; - acceptNextSession(topicName: string, subscriptionName: string, options?: AcceptSessionOptions<"peekLock">): Promise>; - acceptNextSession(topicName: string, subscriptionName: string, options: AcceptSessionOptions<"receiveAndDelete">): Promise>; - acceptSession(queueName: string, sessionId: string, options?: AcceptSessionOptions<"peekLock">): Promise>; - acceptSession(queueName: string, sessionId: string, options: AcceptSessionOptions<"receiveAndDelete">): Promise>; - acceptSession(topicName: string, subscriptionName: string, sessionId: string, options?: AcceptSessionOptions<"peekLock">): Promise>; - acceptSession(topicName: string, subscriptionName: string, sessionId: string, options: AcceptSessionOptions<"receiveAndDelete">): Promise>; + acceptNextSession(queueName: string, options?: AcceptSessionOptions<"peekLock">): Promise; + acceptNextSession(queueName: string, options: AcceptSessionOptions<"receiveAndDelete">): Promise; + acceptNextSession(topicName: string, subscriptionName: string, options?: AcceptSessionOptions<"peekLock">): Promise; + acceptNextSession(topicName: string, subscriptionName: string, options: AcceptSessionOptions<"receiveAndDelete">): Promise; + acceptSession(queueName: string, sessionId: string, options?: AcceptSessionOptions<"peekLock">): Promise; + acceptSession(queueName: string, sessionId: string, options: AcceptSessionOptions<"receiveAndDelete">): Promise; + acceptSession(topicName: string, subscriptionName: string, sessionId: string, options?: AcceptSessionOptions<"peekLock">): Promise; + acceptSession(topicName: string, subscriptionName: string, sessionId: string, options: AcceptSessionOptions<"receiveAndDelete">): Promise; close(): Promise; - createReceiver(queueName: string, options?: CreateReceiverOptions<"peekLock">): ServiceBusReceiver; - createReceiver(queueName: string, options: CreateReceiverOptions<"receiveAndDelete">): ServiceBusReceiver; - createReceiver(topicName: string, subscriptionName: string, options?: CreateReceiverOptions<"peekLock">): ServiceBusReceiver; - createReceiver(topicName: string, subscriptionName: string, options: CreateReceiverOptions<"receiveAndDelete">): ServiceBusReceiver; + createReceiver(queueName: string, options?: CreateReceiverOptions<"peekLock">): ServiceBusReceiver; + createReceiver(queueName: string, options: CreateReceiverOptions<"receiveAndDelete">): ServiceBusReceiver; + createReceiver(topicName: string, subscriptionName: string, options?: CreateReceiverOptions<"peekLock">): ServiceBusReceiver; + createReceiver(topicName: string, subscriptionName: string, options: CreateReceiverOptions<"receiveAndDelete">): ServiceBusReceiver; createSender(queueOrTopicName: string): ServiceBusSender; fullyQualifiedNamespace: string; } @@ -410,31 +410,27 @@ export interface ServiceBusReceivedMessage extends ServiceBusMessage { } // @public -export interface ServiceBusReceivedMessageWithLock extends ServiceBusReceivedMessage { - abandon(propertiesToModify?: { +export interface ServiceBusReceiver { + abandonMessage(message: ServiceBusReceivedMessage, propertiesToModify?: { [key: string]: any; }): Promise; - complete(): Promise; - deadLetter(options?: DeadLetterOptions & { + close(): Promise; + completeMessage(message: ServiceBusReceivedMessage): Promise; + deadLetterMessage(message: ServiceBusReceivedMessage, options?: DeadLetterOptions & { [key: string]: any; }): Promise; - defer(propertiesToModify?: { + deferMessage(message: ServiceBusReceivedMessage, propertiesToModify?: { [key: string]: any; }): Promise; - renewLock(): Promise; -} - -// @public -export interface ServiceBusReceiver { - close(): Promise; entityPath: string; - getMessageIterator(options?: GetMessageIteratorOptions): AsyncIterableIterator; + getMessageIterator(options?: GetMessageIteratorOptions): AsyncIterableIterator; isClosed: boolean; peekMessages(maxMessageCount: number, options?: PeekMessagesOptions): Promise; - receiveDeferredMessages(sequenceNumbers: Long | Long[], options?: OperationOptionsBase): Promise; - receiveMessages(maxMessageCount: number, options?: ReceiveMessagesOptions): Promise; + receiveDeferredMessages(sequenceNumbers: Long | Long[], options?: OperationOptionsBase): Promise; + receiveMessages(maxMessageCount: number, options?: ReceiveMessagesOptions): Promise; receiveMode: "peekLock" | "receiveAndDelete"; - subscribe(handlers: MessageHandlers, options?: SubscribeOptions): { + renewMessageLock(message: ServiceBusReceivedMessage): Promise; + subscribe(handlers: MessageHandlers, options?: SubscribeOptions): { close(): Promise; }; } @@ -452,13 +448,13 @@ export interface ServiceBusSender { } // @public -export interface ServiceBusSessionReceiver extends ServiceBusReceiver { +export interface ServiceBusSessionReceiver extends ServiceBusReceiver { getSessionState(options?: OperationOptionsBase): Promise; renewSessionLock(options?: OperationOptionsBase): Promise; readonly sessionId: string; readonly sessionLockedUntilUtc: Date; setSessionState(state: any, options?: OperationOptionsBase): Promise; - subscribe(handlers: MessageHandlers, options?: SubscribeOptions): { + subscribe(handlers: MessageHandlers, options?: SubscribeOptions): { close(): Promise; }; } diff --git a/sdk/servicebus/service-bus/src/diagnostics/instrumentServiceBusMessage.ts b/sdk/servicebus/service-bus/src/diagnostics/instrumentServiceBusMessage.ts index d03283f8e744..6128290f3f97 100644 --- a/sdk/servicebus/service-bus/src/diagnostics/instrumentServiceBusMessage.ts +++ b/sdk/servicebus/service-bus/src/diagnostics/instrumentServiceBusMessage.ts @@ -99,7 +99,7 @@ export function createProcessingSpan( // NOTE: the connectionConfig also has an entityPath property but that only // represents the optional entityPath in their connection string which is NOT // what we want for tracing. - receiver: Pick, "entityPath">, + receiver: Pick, connectionConfig: Pick, options?: OperationOptionsBase ): Span { @@ -145,7 +145,7 @@ export function createProcessingSpan( */ export function createAndEndProcessingSpan( receivedMessages: ServiceBusReceivedMessage | ServiceBusReceivedMessage[], - receiver: Pick, "entityPath">, + receiver: Pick, connectionConfig: Pick, options?: OperationOptionsBase ): void { diff --git a/sdk/servicebus/service-bus/src/index.ts b/sdk/servicebus/service-bus/src/index.ts index 17b43d576c54..cd9bcaeb9472 100644 --- a/sdk/servicebus/service-bus/src/index.ts +++ b/sdk/servicebus/service-bus/src/index.ts @@ -69,7 +69,6 @@ export { AmqpMessageProperties, DeadLetterOptions, ServiceBusReceivedMessage, - ServiceBusReceivedMessageWithLock, ServiceBusMessage } from "./serviceBusMessage"; export { ServiceBusMessageBatch } from "./serviceBusMessageBatch"; diff --git a/sdk/servicebus/service-bus/src/models.ts b/sdk/servicebus/service-bus/src/models.ts index c712160c4834..be7b29ff65b7 100644 --- a/sdk/servicebus/service-bus/src/models.ts +++ b/sdk/servicebus/service-bus/src/models.ts @@ -3,17 +3,18 @@ import { OperationOptionsBase } from "./modelsToBeSharedWithEventHubs"; import Long from "long"; +import { ServiceBusReceivedMessage } from "./serviceBusMessage"; /** * The general message handler interface (used for streamMessages). */ -export interface MessageHandlers { +export interface MessageHandlers { /** * Handler that processes messages from service bus. * * @param message A message received from Service Bus. */ - processMessage(message: ReceivedMessageT): Promise; + processMessage(message: ServiceBusReceivedMessage): Promise; /** * Handler that processes errors that occur during receiving. * @param err An error from Service Bus. @@ -25,8 +26,7 @@ export interface MessageHandlers { * @internal * @ignore */ -export interface InternalMessageHandlers - extends MessageHandlers { +export interface InternalMessageHandlers extends MessageHandlers { /** * Called when the connection is initialized but before we subscribe to messages or add credits. * diff --git a/sdk/servicebus/service-bus/src/receivers/receiver.ts b/sdk/servicebus/service-bus/src/receivers/receiver.ts index c9b0a879e010..64c86327a6e2 100644 --- a/sdk/servicebus/service-bus/src/receivers/receiver.ts +++ b/sdk/servicebus/service-bus/src/receivers/receiver.ts @@ -24,7 +24,7 @@ import { CreateStreamingReceiverOptions, StreamingReceiver } from "../core/strea import { BatchingReceiver } from "../core/batchingReceiver"; import { assertValidMessageHandlers, getMessageIterator, wrapProcessErrorHandler } from "./shared"; import Long from "long"; -import { ServiceBusReceivedMessageWithLock, ServiceBusMessageImpl } from "../serviceBusMessage"; +import { ServiceBusMessageImpl, DeadLetterOptions } from "../serviceBusMessage"; import { Constants, RetryConfig, RetryOperationType, RetryOptions, retry } from "@azure/core-amqp"; import "@azure/core-asynciterator-polyfill"; import { LockRenewer } from "../core/autoLockRenewer"; @@ -34,7 +34,7 @@ import { receiverLogger as logger } from "../log"; /** * A receiver that does not handle sessions. */ -export interface ServiceBusReceiver { +export interface ServiceBusReceiver { /** * Streams messages to message handlers. * @param handlers A handler that gets called for messages and errors. @@ -43,7 +43,7 @@ export interface ServiceBusReceiver { * stopping new messages from arriving. */ subscribe( - handlers: MessageHandlers, + handlers: MessageHandlers, options?: SubscribeOptions ): { /** @@ -64,7 +64,9 @@ export interface ServiceBusReceiver { * @throws Error if current receiver is already in state of receiving messages. * @throws MessagingError if the service returns an error while receiving messages. */ - getMessageIterator(options?: GetMessageIteratorOptions): AsyncIterableIterator; + getMessageIterator( + options?: GetMessageIteratorOptions + ): AsyncIterableIterator; /** * Returns a promise that resolves to an array of messages received from Service Bus. @@ -81,7 +83,7 @@ export interface ServiceBusReceiver { receiveMessages( maxMessageCount: number, options?: ReceiveMessagesOptions - ): Promise; + ): Promise; /** * Returns a promise that resolves to an array of deferred messages identified by given `sequenceNumbers`. @@ -96,7 +98,7 @@ export interface ServiceBusReceiver { receiveDeferredMessages( sequenceNumbers: Long | Long[], options?: OperationOptionsBase - ): Promise; + ): Promise; /** * Peek the next batch of active messages (including deferred but not deadlettered messages) on the @@ -132,15 +134,133 @@ export interface ServiceBusReceiver { * Use the `createReceiver()` method on the ServiceBusClient to create a new Receiver. */ close(): Promise; + /** + * Removes the message from Service Bus. + * + * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) + * if the AMQP link with which the message was received is no longer alive. This can + * happen either because the lock on the session expired or the receiver was explicitly closed by + * the user or the AMQP link got closed by the library due to network loss or service error. + * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) + * if the lock on the message has expired or the AMQP link with which the message was received is + * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the + * AMQP link got closed by the library due to network loss or service error. + * @throws Error if the message is already settled. To avoid this error check the `isSettled` + * property on the message if you are not sure whether the message is settled. + * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode + * are pre-settled. To avoid this error, update your code to not settle a message which is received + * in this mode. + * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle + * the message in time. The message may or may not have been settled successfully. + * + * @returns Promise. + */ + completeMessage(message: ServiceBusReceivedMessage): Promise; + /** + * The lock held on the message by the receiver is let go, making the message available again in + * Service Bus for another receive operation. + * + * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) + * if the AMQP link with which the message was received is no longer alive. This can + * happen either because the lock on the session expired or the receiver was explicitly closed by + * the user or the AMQP link got closed by the library due to network loss or service error. + * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) + * if the lock on the message has expired or the AMQP link with which the message was received is + * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the + * AMQP link got closed by the library due to network loss or service error. + * @throws Error if the message is already settled. To avoid this error check the `isSettled` + * property on the message if you are not sure whether the message is settled. + * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode + * are pre-settled. To avoid this error, update your code to not settle a message which is received + * in this mode. + * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle + * the message in time. The message may or may not have been settled successfully. + * + * @param propertiesToModify The properties of the message to modify while abandoning the message. + * + * @return Promise. + */ + abandonMessage( + message: ServiceBusReceivedMessage, + propertiesToModify?: { [key: string]: any } + ): Promise; + /** + * Defers the processing of the message. Save the `sequenceNumber` of the message, in order to + * receive it message again in the future using the `receiveDeferredMessage` method. + * + * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) + * if the AMQP link with which the message was received is no longer alive. This can + * happen either because the lock on the session expired or the receiver was explicitly closed by + * the user or the AMQP link got closed by the library due to network loss or service error. + * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) + * if the lock on the message has expired or the AMQP link with which the message was received is + * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the + * AMQP link got closed by the library due to network loss or service error. + * @throws Error if the message is already settled. To avoid this error check the `isSettled` + * property on the message if you are not sure whether the message is settled. + * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode + * are pre-settled. To avoid this error, update your code to not settle a message which is received + * in this mode. + * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle + * the message in time. The message may or may not have been settled successfully. + * + * @param propertiesToModify The properties of the message to modify while deferring the message + * + * @returns Promise + */ + deferMessage( + message: ServiceBusReceivedMessage, + propertiesToModify?: { [key: string]: any } + ): Promise; + /** + * Moves the message to the deadletter sub-queue. To receive a deadletted message, create a new + * QueueClient/SubscriptionClient using the path for the deadletter sub-queue. + * + * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) + * if the AMQP link with which the message was received is no longer alive. This can + * happen either because the lock on the session expired or the receiver was explicitly closed by + * the user or the AMQP link got closed by the library due to network loss or service error. + * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) + * if the lock on the message has expired or the AMQP link with which the message was received is + * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the + * AMQP link got closed by the library due to network loss or service error. + * @throws Error if the message is already settled. To avoid this error check the `isSettled` + * property on the message if you are not sure whether the message is settled. + * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode + * are pre-settled. To avoid this error, update your code to not settle a message which is received + * in this mode. + * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle + * the message in time. The message may or may not have been settled successfully. + * + * @param options The DeadLetter options that can be provided while + * rejecting the message. + * + * @returns Promise + */ + deadLetterMessage( + message: ServiceBusReceivedMessage, + options?: DeadLetterOptions & { [key: string]: any } + ): Promise; + /** + * Renews the lock on the message for the duration as specified during the Queue/Subscription + * creation. + * - Check the `lockedUntilUtc` property on the message for the time when the lock expires. + * - If a message is not settled (using either `complete()`, `defer()` or `deadletter()`, + * before its lock expires, then the message lands back in the Queue/Subscription for the next + * receive operation. + * + * @returns Promise - New lock token expiry date and time in UTC format. + * @throws Error if the underlying connection, client or receiver is closed. + * @throws MessagingError if the service returns an error while renewing message lock. + */ + renewMessageLock(message: ServiceBusReceivedMessage): Promise; } /** * @internal * @ignore */ -export class ServiceBusReceiverImpl< - ReceivedMessageT extends ServiceBusReceivedMessage | ServiceBusReceivedMessageWithLock -> implements ServiceBusReceiver { +export class ServiceBusReceiverImpl implements ServiceBusReceiver { private _retryOptions: RetryOptions; /** * @property {boolean} [_isClosed] Denotes if close() was called on this receiver @@ -290,7 +410,7 @@ export class ServiceBusReceiverImpl< async receiveMessages( maxMessageCount: number, options?: ReceiveMessagesOptions - ): Promise { + ): Promise { this._throwIfReceiverOrConnectionClosed(); this._throwIfAlreadyReceiving(); @@ -319,9 +439,9 @@ export class ServiceBusReceiverImpl< options ?? {} ); - return (receivedMessages as unknown) as ReceivedMessageT[]; + return (receivedMessages as unknown) as ServiceBusReceivedMessage[]; }; - const config: RetryConfig = { + const config: RetryConfig = { connectionHost: this._context.config.host, connectionId: this._context.connectionId, operation: receiveMessages, @@ -329,17 +449,19 @@ export class ServiceBusReceiverImpl< abortSignal: options?.abortSignal, retryOptions: this._retryOptions }; - return retry(config); + return retry(config); } - getMessageIterator(options?: GetMessageIteratorOptions): AsyncIterableIterator { + getMessageIterator( + options?: GetMessageIteratorOptions + ): AsyncIterableIterator { return getMessageIterator(this, options); } async receiveDeferredMessages( sequenceNumbers: Long | Long[], options: OperationOptionsBase = {} - ): Promise { + ): Promise { this._throwIfReceiverOrConnectionClosed(); throwTypeErrorIfParameterMissing( this._context.connectionId, @@ -364,16 +486,16 @@ export class ServiceBusReceiverImpl< requestName: "receiveDeferredMessages", timeoutInMs: this._retryOptions.timeoutInMs }); - return (deferredMessages as any) as ReceivedMessageT[]; + return deferredMessages; }; - const config: RetryConfig = { + const config: RetryConfig = { operation: receiveDeferredMessagesOperationPromise, connectionId: this._context.connectionId, operationType: RetryOperationType.management, retryOptions: this._retryOptions, abortSignal: options?.abortSignal }; - return retry(config); + return retry(config); } // ManagementClient methods # Begin @@ -422,7 +544,7 @@ export class ServiceBusReceiverImpl< } subscribe( - handlers: MessageHandlers, + handlers: MessageHandlers, options?: SubscribeOptions ): { close(): Promise; @@ -432,9 +554,7 @@ export class ServiceBusReceiverImpl< const processError = wrapProcessErrorHandler(handlers); - const internalMessageHandlers = handlers as - | InternalMessageHandlers - | undefined; + const internalMessageHandlers = handlers as InternalMessageHandlers | undefined; this._registerMessageHandler( async () => { @@ -444,7 +564,7 @@ export class ServiceBusReceiverImpl< }, async (message: ServiceBusMessageImpl) => { const span = this._createProcessingSpan(message, this, this._context.config, options); - return trace(() => handlers.processMessage((message as any) as ReceivedMessageT), span); + return trace(() => handlers.processMessage(message), span); }, processError, options @@ -457,6 +577,40 @@ export class ServiceBusReceiverImpl< }; } + async completeMessage(message: ServiceBusReceivedMessage): Promise { + const msgImpl = message as ServiceBusMessageImpl; + return msgImpl.complete(); + } + + async abandonMessage( + message: ServiceBusReceivedMessage, + propertiesToModify?: { [key: string]: any } + ): Promise { + const msgImpl = message as ServiceBusMessageImpl; + return msgImpl.abandon(propertiesToModify); + } + + async deferMessage( + message: ServiceBusReceivedMessage, + propertiesToModify?: { [key: string]: any } + ): Promise { + const msgImpl = message as ServiceBusMessageImpl; + return msgImpl.defer(propertiesToModify); + } + + async deadLetterMessage( + message: ServiceBusReceivedMessage, + options?: DeadLetterOptions & { [key: string]: any } + ): Promise { + const msgImpl = message as ServiceBusMessageImpl; + return msgImpl.deadLetter(options); + } + + async renewMessageLock(message: ServiceBusReceivedMessage): Promise { + const msgImpl = message as ServiceBusMessageImpl; + return msgImpl.renewLock(); + } + async close(): Promise { try { this._isClosed = true; diff --git a/sdk/servicebus/service-bus/src/receivers/sessionReceiver.ts b/sdk/servicebus/service-bus/src/receivers/sessionReceiver.ts index 98d9dd471401..b7d46ddb3374 100644 --- a/sdk/servicebus/service-bus/src/receivers/sessionReceiver.ts +++ b/sdk/servicebus/service-bus/src/receivers/sessionReceiver.ts @@ -16,7 +16,7 @@ import { OnError, OnMessage } from "../core/messageReceiver"; import { assertValidMessageHandlers, getMessageIterator, wrapProcessErrorHandler } from "./shared"; import { defaultMaxTimeAfterFirstMessageForBatchingMs, ServiceBusReceiver } from "./receiver"; import Long from "long"; -import { ServiceBusReceivedMessageWithLock, ServiceBusMessageImpl } from "../serviceBusMessage"; +import { ServiceBusMessageImpl, DeadLetterOptions } from "../serviceBusMessage"; import { Constants, RetryConfig, @@ -35,9 +35,7 @@ import { receiverLogger as logger } from "../log"; /** *A receiver that handles sessions, including renewing the session lock. */ -export interface ServiceBusSessionReceiver< - ReceivedMessageT extends ServiceBusReceivedMessage | ServiceBusReceivedMessageWithLock -> extends ServiceBusReceiver { +export interface ServiceBusSessionReceiver extends ServiceBusReceiver { /** * The session ID. */ @@ -62,7 +60,7 @@ export interface ServiceBusSessionReceiver< * stopping new messages from arriving. */ subscribe( - handlers: MessageHandlers, + handlers: MessageHandlers, options?: SubscribeOptions ): { /** @@ -104,9 +102,7 @@ export interface ServiceBusSessionReceiver< * @internal * @ignore */ -export class ServiceBusSessionReceiverImpl< - ReceivedMessageT extends ServiceBusReceivedMessage | ServiceBusReceivedMessageWithLock -> implements ServiceBusSessionReceiver { +export class ServiceBusSessionReceiverImpl implements ServiceBusSessionReceiver { public sessionId: string; /** @@ -333,7 +329,7 @@ export class ServiceBusSessionReceiverImpl< async receiveDeferredMessages( sequenceNumbers: Long | Long[], options: OperationOptionsBase = {} - ): Promise { + ): Promise { this._throwIfReceiverOrConnectionClosed(); throwTypeErrorIfParameterMissing( this._context.connectionId, @@ -358,22 +354,22 @@ export class ServiceBusSessionReceiverImpl< requestName: "receiveDeferredMessages", timeoutInMs: this._retryOptions.timeoutInMs }); - return (deferredMessages as any) as ReceivedMessageT[]; + return deferredMessages; }; - const config: RetryConfig = { + const config: RetryConfig = { operation: receiveDeferredMessagesOperationPromise, connectionId: this._context.connectionId, operationType: RetryOperationType.management, retryOptions: this._retryOptions, abortSignal: options?.abortSignal }; - return retry(config); + return retry(config); } async receiveMessages( maxMessageCount: number, options?: ReceiveMessagesOptions - ): Promise { + ): Promise { this._throwIfReceiverOrConnectionClosed(); this._throwIfAlreadyReceiving(); @@ -389,20 +385,20 @@ export class ServiceBusSessionReceiverImpl< options ?? {} ); - return (receivedMessages as any) as ReceivedMessageT[]; + return receivedMessages; }; - const config: RetryConfig = { + const config: RetryConfig = { operation: receiveBatchOperationPromise, connectionId: this._context.connectionId, operationType: RetryOperationType.receiveMessage, retryOptions: this._retryOptions, abortSignal: options?.abortSignal }; - return retry(config); + return retry(config); } subscribe( - handlers: MessageHandlers, + handlers: MessageHandlers, options?: SubscribeOptions ): { close(): Promise; @@ -417,7 +413,7 @@ export class ServiceBusSessionReceiverImpl< this._registerMessageHandler( async (message: ServiceBusMessageImpl) => { const span = this._createProcessingSpan(message, this, this._context.config, options); - return trace(() => handlers.processMessage((message as any) as ReceivedMessageT), span); + return trace(() => handlers.processMessage(message), span); }, processError, options @@ -476,10 +472,45 @@ export class ServiceBusSessionReceiverImpl< } } - getMessageIterator(options?: GetMessageIteratorOptions): AsyncIterableIterator { + getMessageIterator( + options?: GetMessageIteratorOptions + ): AsyncIterableIterator { return getMessageIterator(this, options); } + async completeMessage(message: ServiceBusReceivedMessage): Promise { + const msgImpl = message as ServiceBusMessageImpl; + return msgImpl.complete(); + } + + async abandonMessage( + message: ServiceBusReceivedMessage, + propertiesToModify?: { [key: string]: any } + ): Promise { + const msgImpl = message as ServiceBusMessageImpl; + return msgImpl.abandon(propertiesToModify); + } + + async deferMessage( + message: ServiceBusReceivedMessage, + propertiesToModify?: { [key: string]: any } + ): Promise { + const msgImpl = message as ServiceBusMessageImpl; + return msgImpl.defer(propertiesToModify); + } + + async deadLetterMessage( + message: ServiceBusReceivedMessage, + options?: DeadLetterOptions & { [key: string]: any } + ): Promise { + const msgImpl = message as ServiceBusMessageImpl; + return msgImpl.deadLetter(options); + } + + async renewMessageLock(): Promise { + throw new Error("Renewing message lock is an invalid operation when working with sessions."); + } + async close(): Promise { try { await this._messageSession.close(); diff --git a/sdk/servicebus/service-bus/src/receivers/shared.ts b/sdk/servicebus/service-bus/src/receivers/shared.ts index 7d1f54dcc1b1..178365ff44cf 100644 --- a/sdk/servicebus/service-bus/src/receivers/shared.ts +++ b/sdk/servicebus/service-bus/src/receivers/shared.ts @@ -5,6 +5,7 @@ import { MessageHandlers } from "../models"; import { ServiceBusReceiver } from "./receiver"; import { OperationOptionsBase } from "../modelsToBeSharedWithEventHubs"; import { receiverLogger, ServiceBusLogger } from "../log"; +import { ServiceBusReceivedMessage } from "../serviceBusMessage"; /** * @internal @@ -26,10 +27,10 @@ export function assertValidMessageHandlers(handlers: any) { * @internal * @ignore */ -export async function* getMessageIterator( - receiver: Pick, "receiveMessages">, +export async function* getMessageIterator( + receiver: Pick, options?: OperationOptionsBase -): AsyncIterableIterator { +): AsyncIterableIterator { while (true) { const messages = await receiver.receiveMessages(1, options); @@ -46,9 +47,9 @@ export async function* getMessageIterator( * @ignore */ export function wrapProcessErrorHandler( - handlers: Pick, "processError">, + handlers: Pick, logger: ServiceBusLogger = receiverLogger -): MessageHandlers["processError"] { +): MessageHandlers["processError"] { return async (err: Error) => { try { await handlers.processError(err); diff --git a/sdk/servicebus/service-bus/src/serviceBusClient.ts b/sdk/servicebus/service-bus/src/serviceBusClient.ts index 185389b5aa7c..8a9f0beb17b3 100644 --- a/sdk/servicebus/service-bus/src/serviceBusClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusClient.ts @@ -14,7 +14,6 @@ import { ServiceBusSessionReceiver, ServiceBusSessionReceiverImpl } from "./receivers/sessionReceiver"; -import { ServiceBusReceivedMessage, ServiceBusReceivedMessageWithLock } from "./serviceBusMessage"; import { ServiceBusSender, ServiceBusSenderImpl } from "./sender"; import { entityPathMisMatchError } from "./util/errors"; import { MessageSession } from "./session/messageSession"; @@ -120,12 +119,12 @@ export class ServiceBusClient { * * @param queueName The name of the queue to receive from. * @param options Options to pass the receiveMode, defaulted to peekLock. - * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessageWithLock` + * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessage` */ createReceiver( queueName: string, options?: CreateReceiverOptions<"peekLock"> - ): ServiceBusReceiver; + ): ServiceBusReceiver; /** * Creates a receiver for an Azure Service Bus queue in receiveAndDelete mode. No connection is made * to the service until one of the methods on the receiver is called. @@ -144,7 +143,7 @@ export class ServiceBusClient { createReceiver( queueName: string, options: CreateReceiverOptions<"receiveAndDelete"> - ): ServiceBusReceiver; + ): ServiceBusReceiver; /** * Creates a receiver for an Azure Service Bus subscription in peekLock mode. No connection is made * to the service until one of the methods on the receiver is called. @@ -170,13 +169,13 @@ export class ServiceBusClient { * @param topicName Name of the topic for the subscription we want to receive from. * @param subscriptionName Name of the subscription (under the `topic`) that we want to receive from. * @param options Options to pass the receiveMode, defaulted to peekLock. - * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessageWithLock` + * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessage` */ createReceiver( topicName: string, subscriptionName: string, options?: CreateReceiverOptions<"peekLock"> - ): ServiceBusReceiver; + ): ServiceBusReceiver; /** * Creates a receiver for an Azure Service Bus subscription in receiveAndDelete mode. No connection is made * to the service until one of the methods on the receiver is called. @@ -198,7 +197,7 @@ export class ServiceBusClient { topicName: string, subscriptionName: string, options: CreateReceiverOptions<"receiveAndDelete"> - ): ServiceBusReceiver; + ): ServiceBusReceiver; createReceiver( queueOrTopicName1: string, optionsOrSubscriptionName2?: @@ -206,9 +205,7 @@ export class ServiceBusClient { | CreateReceiverOptions<"peekLock"> | string, options3?: CreateReceiverOptions<"receiveAndDelete"> | CreateReceiverOptions<"peekLock"> - ): - | ServiceBusReceiver - | ServiceBusReceiver { + ): ServiceBusReceiver | ServiceBusReceiver { validateEntityPath(this._connectionContext.config, queueOrTopicName1); // NOTE: we don't currently have any options for this kind of receiver but @@ -241,7 +238,7 @@ export class ServiceBusClient { : 5 * 60 * 1000; if (receiveMode === "peekLock") { - return new ServiceBusReceiverImpl( + return new ServiceBusReceiverImpl( this._connectionContext, entityPathWithSubQueue, receiveMode, @@ -249,7 +246,7 @@ export class ServiceBusClient { this._clientOptions.retryOptions ); } else { - return new ServiceBusReceiverImpl( + return new ServiceBusReceiverImpl( this._connectionContext, entityPathWithSubQueue, receiveMode, @@ -279,13 +276,13 @@ export class ServiceBusClient { * @param queueName The name of the queue to receive from. * @param sessionId The id of the session from which messages need to be received * @param options Options include receiveMode(defaulted to peekLock), options to create session receiver. - * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessageWithLock` + * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessage` */ acceptSession( queueName: string, sessionId: string, options?: AcceptSessionOptions<"peekLock"> - ): Promise>; + ): Promise; /** * Creates a receiver for a session enabled Azure Service Bus queue in receiveAndDelete mode. * If the receiveMode is not provided in the options, it defaults to the "peekLock" mode. @@ -301,7 +298,7 @@ export class ServiceBusClient { queueName: string, sessionId: string, options: AcceptSessionOptions<"receiveAndDelete"> - ): Promise>; + ): Promise; /** * Creates a receiver for a session enabled Azure Service Bus subscription in peekLock mode. * If the receiveMode is not provided in the options, it defaults to the "peekLock" mode. @@ -323,14 +320,14 @@ export class ServiceBusClient { * @param subscriptionName Name of the subscription (under the `topic`) that we want to receive from. * @param sessionId The id of the session from which messages need to be received * @param options Options include receiveMode(defaulted to peekLock), options to create session receiver. - * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessageWithLock` + * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessage` */ acceptSession( topicName: string, subscriptionName: string, sessionId: string, options?: AcceptSessionOptions<"peekLock"> - ): Promise>; + ): Promise; /** * Creates a receiver for a session enabled Azure Service Bus subscription in receiveAndDelete mode. * If the receiveMode is not provided in the options, it defaults to the "peekLock" mode. @@ -348,7 +345,7 @@ export class ServiceBusClient { subscriptionName: string, sessionId: string, options: AcceptSessionOptions<"receiveAndDelete"> - ): Promise>; + ): Promise; async acceptSession( queueOrTopicName1: string, optionsOrSubscriptionNameOrSessionId2?: @@ -360,10 +357,7 @@ export class ServiceBusClient { | AcceptSessionOptions<"receiveAndDelete"> | string, options4?: AcceptSessionOptions<"peekLock"> | AcceptSessionOptions<"receiveAndDelete"> - ): Promise< - | ServiceBusSessionReceiver - | ServiceBusSessionReceiver - > { + ): Promise { validateEntityPath(this._connectionContext.config, queueOrTopicName1); let sessionId: string; @@ -417,9 +411,7 @@ export class ServiceBusClient { } ); - const sessionReceiver = new ServiceBusSessionReceiverImpl< - ServiceBusReceivedMessageWithLock | ServiceBusReceivedMessage - >( + const sessionReceiver = new ServiceBusSessionReceiverImpl( messageSession, this._connectionContext, entityPath, @@ -449,12 +441,12 @@ export class ServiceBusClient { * * @param queueName The name of the queue to receive from. * @param options Options include receiveMode(defaulted to peekLock), options to create session receiver. - * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessageWithLock` + * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessage` */ acceptNextSession( queueName: string, options?: AcceptSessionOptions<"peekLock"> - ): Promise>; + ): Promise; /** * Creates a receiver for the next available session in a session-enabled Azure Service Bus queue in receiveAndDelete mode. * If the receiveMode is not provided in the options, it defaults to the "peekLock" mode. @@ -468,7 +460,7 @@ export class ServiceBusClient { acceptNextSession( queueName: string, options: AcceptSessionOptions<"receiveAndDelete"> - ): Promise>; + ): Promise; /** * Creates a receiver for the next available session in a session-enabled Azure Service Bus subscription in peekLock mode. * If the receiveMode is not provided in the options, it defaults to the "peekLock" mode. @@ -489,13 +481,13 @@ export class ServiceBusClient { * @param topicName Name of the topic for the subscription we want to receive from. * @param subscriptionName Name of the subscription (under the `topic`) that we want to receive from. * @param options Options include receiveMode(defaulted to peekLock), options to create session receiver. - * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessageWithLock` + * @returns A receiver that can be used to receive messages of the form `ServiceBusReceivedMessage` */ acceptNextSession( topicName: string, subscriptionName: string, options?: AcceptSessionOptions<"peekLock"> - ): Promise>; + ): Promise; /** * Creates a receiver for the next available session in a session-enabled Azure Service Bus subscription in receiveAndDelete mode. * If the receiveMode is not provided in the options, it defaults to the "peekLock" mode. @@ -511,7 +503,7 @@ export class ServiceBusClient { topicName: string, subscriptionName: string, options: AcceptSessionOptions<"receiveAndDelete"> - ): Promise>; + ): Promise; async acceptNextSession( queueOrTopicName1: string, optionsOrSubscriptionName2?: @@ -519,10 +511,7 @@ export class ServiceBusClient { | AcceptSessionOptions<"receiveAndDelete"> | string, options3?: AcceptSessionOptions<"peekLock"> | AcceptSessionOptions<"receiveAndDelete"> - ): Promise< - | ServiceBusSessionReceiver - | ServiceBusSessionReceiver - > { + ): Promise { validateEntityPath(this._connectionContext.config, queueOrTopicName1); const { entityPath, receiveMode, options } = extractReceiverArguments( @@ -542,9 +531,7 @@ export class ServiceBusClient { } ); - const sessionReceiver = new ServiceBusSessionReceiverImpl< - ServiceBusReceivedMessageWithLock | ServiceBusReceivedMessage - >( + const sessionReceiver = new ServiceBusSessionReceiverImpl( messageSession, this._connectionContext, entityPath, diff --git a/sdk/servicebus/service-bus/src/serviceBusMessage.ts b/sdk/servicebus/service-bus/src/serviceBusMessage.ts index 73882c6abd93..df6b4b20db53 100644 --- a/sdk/servicebus/service-bus/src/serviceBusMessage.ts +++ b/sdk/servicebus/service-bus/src/serviceBusMessage.ts @@ -249,7 +249,7 @@ export interface AmqpAnnotatedMessage { /** * The message body. */ - body: any; + body?: any; } /** @@ -572,128 +572,6 @@ export interface ServiceBusReceivedMessage extends ServiceBusMessage { readonly _amqpAnnotatedMessage: AmqpAnnotatedMessage; } -/** - * A message that can be settled by completing it, abandoning it, deferring it, or sending - * it to the dead letter queue. - */ -export interface ServiceBusReceivedMessageWithLock extends ServiceBusReceivedMessage { - /** - * Removes the message from Service Bus. - * - * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) - * if the AMQP link with which the message was received is no longer alive. This can - * happen either because the lock on the session expired or the receiver was explicitly closed by - * the user or the AMQP link got closed by the library due to network loss or service error. - * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) - * if the lock on the message has expired or the AMQP link with which the message was received is - * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the - * AMQP link got closed by the library due to network loss or service error. - * @throws Error if the message is already settled. To avoid this error check the `isSettled` - * property on the message if you are not sure whether the message is settled. - * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode - * are pre-settled. To avoid this error, update your code to not settle a message which is received - * in this mode. - * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle - * the message in time. The message may or may not have been settled successfully. - * - * @returns Promise. - */ - complete(): Promise; - - /** - * The lock held on the message by the receiver is let go, making the message available again in - * Service Bus for another receive operation. - * - * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) - * if the AMQP link with which the message was received is no longer alive. This can - * happen either because the lock on the session expired or the receiver was explicitly closed by - * the user or the AMQP link got closed by the library due to network loss or service error. - * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) - * if the lock on the message has expired or the AMQP link with which the message was received is - * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the - * AMQP link got closed by the library due to network loss or service error. - * @throws Error if the message is already settled. To avoid this error check the `isSettled` - * property on the message if you are not sure whether the message is settled. - * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode - * are pre-settled. To avoid this error, update your code to not settle a message which is received - * in this mode. - * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle - * the message in time. The message may or may not have been settled successfully. - * - * @param propertiesToModify The properties of the message to modify while abandoning the message. - * - * @return Promise. - */ - abandon(propertiesToModify?: { [key: string]: any }): Promise; - - /** - * Defers the processing of the message. Save the `sequenceNumber` of the message, in order to - * receive it message again in the future using the `receiveDeferredMessage` method. - * - * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) - * if the AMQP link with which the message was received is no longer alive. This can - * happen either because the lock on the session expired or the receiver was explicitly closed by - * the user or the AMQP link got closed by the library due to network loss or service error. - * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) - * if the lock on the message has expired or the AMQP link with which the message was received is - * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the - * AMQP link got closed by the library due to network loss or service error. - * @throws Error if the message is already settled. To avoid this error check the `isSettled` - * property on the message if you are not sure whether the message is settled. - * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode - * are pre-settled. To avoid this error, update your code to not settle a message which is received - * in this mode. - * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle - * the message in time. The message may or may not have been settled successfully. - * - * @param propertiesToModify The properties of the message to modify while deferring the message - * - * @returns Promise - */ - defer(propertiesToModify?: { [key: string]: any }): Promise; - - /** - * Moves the message to the deadletter sub-queue. To receive a deadletted message, create a new - * QueueClient/SubscriptionClient using the path for the deadletter sub-queue. - * - * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) - * if the AMQP link with which the message was received is no longer alive. This can - * happen either because the lock on the session expired or the receiver was explicitly closed by - * the user or the AMQP link got closed by the library due to network loss or service error. - * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) - * if the lock on the message has expired or the AMQP link with which the message was received is - * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the - * AMQP link got closed by the library due to network loss or service error. - * @throws Error if the message is already settled. To avoid this error check the `isSettled` - * property on the message if you are not sure whether the message is settled. - * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode - * are pre-settled. To avoid this error, update your code to not settle a message which is received - * in this mode. - * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle - * the message in time. The message may or may not have been settled successfully. - * - * @param options The DeadLetter options that can be provided while - * rejecting the message. - * - * @returns Promise - */ - deadLetter(options?: DeadLetterOptions & { [key: string]: any }): Promise; - - /** - * Renews the lock on the message for the duration as specified during the Queue/Subscription - * creation. - * - Check the `lockedUntilUtc` property on the message for the time when the lock expires. - * - If a message is not settled (using either `complete()`, `defer()` or `deadletter()`, - * before its lock expires, then the message lands back in the Queue/Subscription for the next - * receive operation. - * - * @returns Promise - New lock token expiry date and time in UTC format. - * @throws Error if the underlying connection, client or receiver is closed. - * @throws MessagingError if the service returns an error while renewing message lock. - */ - renewLock(): Promise; -} - /** * @internal * @ignore @@ -850,9 +728,9 @@ export function isServiceBusMessage(possible: any): possible is ServiceBusMessag * @internal * @ignore * @class ServiceBusMessageImpl - * @implements {ServiceBusReceivedMessageWithLock} + * @implements {ServiceBusReceivedMessage} */ -export class ServiceBusMessageImpl implements ServiceBusReceivedMessageWithLock { +export class ServiceBusMessageImpl implements ServiceBusReceivedMessage { /** * @property The message body that needs to be sent or is received. */ diff --git a/sdk/servicebus/service-bus/test/auth.spec.ts b/sdk/servicebus/service-bus/test/auth.spec.ts index 2c383287fedc..08a6f373154d 100644 --- a/sdk/servicebus/service-bus/test/auth.spec.ts +++ b/sdk/servicebus/service-bus/test/auth.spec.ts @@ -6,7 +6,6 @@ import chai from "chai"; import { parseConnectionString } from "rhea-promise"; import { ServiceBusReceiver } from "../src/receivers/receiver"; import { ServiceBusClient } from "../src/serviceBusClient"; -import { ServiceBusReceivedMessage } from "../src/serviceBusMessage"; import { getEnvVars } from "./utils/envVarUtils"; import { TestClientType } from "./utils/testUtils"; import { @@ -60,7 +59,7 @@ type UnpackReturnType any> = ReturnType extends P await sender.close(); - let receiver: ServiceBusReceiver; + let receiver: ServiceBusReceiver; if (entities.queue) { receiver = client.createReceiver(entities.queue!, { diff --git a/sdk/servicebus/service-bus/test/backupMessageSettlement.spec.ts b/sdk/servicebus/service-bus/test/backupMessageSettlement.spec.ts index e7df522b9155..c5562ea662fb 100644 --- a/sdk/servicebus/service-bus/test/backupMessageSettlement.spec.ts +++ b/sdk/servicebus/service-bus/test/backupMessageSettlement.spec.ts @@ -1,336 +1,336 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import chai from "chai"; -import chaiAsPromised from "chai-as-promised"; -import { ServiceBusMessage } from "../src"; -import { TestClientType, TestMessage } from "./utils/testUtils"; -import { ServiceBusReceiver } from "../src/receivers/receiver"; -import { ServiceBusSender } from "../src/sender"; -import { - EntityName, - ServiceBusClientForTests, - createServiceBusClientForTests, - testPeekMsgsLength, - getRandomTestClientTypeWithSessions, - getRandomTestClientTypeWithNoSessions -} from "./utils/testutils2"; -import { DispositionType, ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; - -const should = chai.should(); -chai.use(chaiAsPromised); - -const noSessionTestClientType = getRandomTestClientTypeWithNoSessions(); -const withSessionTestClientType = getRandomTestClientTypeWithSessions(); - -describe("Message settlement After Receiver is Closed - Through ManagementLink", () => { - let serviceBusClient: ServiceBusClientForTests; - - let sender: ServiceBusSender; - let receiver: ServiceBusReceiver; - let deadLetterReceiver: ServiceBusReceiver; - let entityNames: EntityName; - - before(() => { - serviceBusClient = createServiceBusClientForTests(); - }); - - after(() => { - return serviceBusClient.test.after(); - }); - - async function beforeEachTest(entityType: TestClientType): Promise { - entityNames = await serviceBusClient.test.createTestEntities(entityType); - receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); - - sender = serviceBusClient.test.addToCleanup( - serviceBusClient.createSender(entityNames.queue ?? entityNames.topic!) - ); - - deadLetterReceiver = serviceBusClient.test.createDeadLetterReceiver(entityNames); - } - - afterEach(async () => { - await serviceBusClient.test.afterEach(); - }); - - async function sendReceiveMsg( - testMessages: ServiceBusMessage - ): Promise { - await sender.sendMessages(testMessages); - const msgs = await receiver.receiveMessages(1); - - should.equal(Array.isArray(msgs), true, "`ReceivedMessages` is not an array"); - should.equal(msgs.length, 1, "Unexpected number of messages"); - should.equal(msgs[0].body, testMessages.body, "MessageBody is different than expected"); - should.equal(msgs[0].messageId, testMessages.messageId, "MessageId is different than expected"); - should.equal(msgs[0].deliveryCount, 0, "DeliveryCount is different than expected"); - - return msgs[0]; - } - - async function testComplete(): Promise { - const testMessages = entityNames.usesSessions - ? TestMessage.getSessionSample() - : TestMessage.getSample(); - const msg = await sendReceiveMsg(testMessages); - await receiver.close(); - let errorWasThrown = false; - try { - await msg.complete(); - } catch (err) { - should.equal( - err.message, - `Failed to ${DispositionType.complete} the message as the AMQP link with which the message was received is no longer alive.`, - "Unexpected error thrown" - ); - errorWasThrown = true; - } - - receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); - if (entityNames.usesSessions) { - should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); - const msgBatch = await receiver.receiveMessages(1); - await msgBatch[0].complete(); - } else { - should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); - } - await testPeekMsgsLength(receiver, 0); - } - - it(noSessionTestClientType + ": complete() removes message", async function(): Promise { - await beforeEachTest(noSessionTestClientType); - await testComplete(); - }); - - it(withSessionTestClientType + ": complete() removes message", async function(): Promise { - await beforeEachTest(withSessionTestClientType); - await testComplete(); - }); - - async function testAbandon(): Promise { - const testMessages = entityNames.usesSessions - ? TestMessage.getSessionSample() - : TestMessage.getSample(); - const msg = await sendReceiveMsg(testMessages); - await receiver.close(); - let errorWasThrown = false; - try { - await msg.abandon(); - } catch (err) { - should.equal( - err.message, - `Failed to ${DispositionType.abandon} the message as the AMQP link with which the message was received is no longer alive.`, - "Unexpected error thrown" - ); - errorWasThrown = true; - } - - if (entityNames.usesSessions) { - should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); - } else { - should.equal(errorWasThrown, false, "Error was thrown for messages without session-id"); - } - receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); - await testPeekMsgsLength(receiver, 1); - - const messageBatch = await receiver.receiveMessages(1); - - await messageBatch[0].complete(); - - await testPeekMsgsLength(receiver, 0); - } - - it( - noSessionTestClientType + ": abandon() retains message with incremented deliveryCount", - async function(): Promise { - await beforeEachTest(noSessionTestClientType); - await testAbandon(); - } - ); - - it( - withSessionTestClientType + ": abandon() retains message with incremented deliveryCount", - async function(): Promise { - await beforeEachTest(withSessionTestClientType); - await testAbandon(); - } - ); - - async function testDefer(): Promise { - const testMessages = entityNames.usesSessions - ? TestMessage.getSessionSample() - : TestMessage.getSample(); - const msg = await sendReceiveMsg(testMessages); - - if (!msg.sequenceNumber) { - throw "Sequence Number can not be null"; - } - const sequenceNumber = msg.sequenceNumber; - await receiver.close(); - let errorWasThrown = false; - try { - await msg.defer(); - } catch (err) { - should.equal( - err.message, - `Failed to ${DispositionType.defer} the message as the AMQP link with which the message was received is no longer alive.`, - "Unexpected error thrown" - ); - errorWasThrown = true; - } - - if (entityNames.usesSessions) { - should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); - } else { - should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); - } - receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); - if (!entityNames.usesSessions) { - const [deferredMsg] = await receiver.receiveDeferredMessages(sequenceNumber); - if (!deferredMsg) { - throw "No message received for sequence number"; - } - await deferredMsg.complete(); - } else { - const messageBatch = await receiver.receiveMessages(1); - await messageBatch[0].complete(); - } - await testPeekMsgsLength(receiver, 0); - } - - it( - noSessionTestClientType + ": defer() moves message to deferred queue", - async function(): Promise { - await beforeEachTest(noSessionTestClientType); - await testDefer(); - } - ); - - it( - withSessionTestClientType + ": defer() moves message to deferred queue", - async function(): Promise { - await beforeEachTest(withSessionTestClientType); - await testDefer(); - } - ); - - async function testDeadletter(): Promise { - const testMessages = entityNames.usesSessions - ? TestMessage.getSessionSample() - : TestMessage.getSample(); - const msg = await sendReceiveMsg(testMessages); - await receiver.close(); - let errorWasThrown = false; - try { - await msg.deadLetter(); - } catch (err) { - should.equal( - err.message, - `Failed to ${DispositionType.deadletter} the message as the AMQP link with which the message was received is no longer alive.`, - "Unexpected error thrown" - ); - errorWasThrown = true; - } - - if (entityNames.usesSessions) { - should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); - } else { - should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); - } - - receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); - - if (!entityNames.usesSessions) { - const deadLetterMsgsBatch = await deadLetterReceiver.receiveMessages(1); - - should.equal( - Array.isArray(deadLetterMsgsBatch), - true, - "`ReceivedMessages` from Deadletter is not an array" - ); - should.equal(deadLetterMsgsBatch.length, 1, "Unexpected number of messages"); - should.equal( - deadLetterMsgsBatch[0].body, - testMessages.body, - "MessageBody is different than expected" - ); - should.equal( - deadLetterMsgsBatch[0].messageId, - testMessages.messageId, - "MessageId is different than expected" - ); - - await deadLetterMsgsBatch[0].complete(); - - await testPeekMsgsLength(deadLetterReceiver, 0); - } else { - const messageBatch = await receiver.receiveMessages(1); - await messageBatch[0].complete(); - - await testPeekMsgsLength(receiver, 0); - } - } - - it( - noSessionTestClientType + ": deadLetter() moves message to deadletter queue", - async function(): Promise { - await beforeEachTest(noSessionTestClientType); - await testDeadletter(); - } - ); - - it( - withSessionTestClientType + ": deadLetter() moves message to deadletter queue", - async function(): Promise { - await beforeEachTest(withSessionTestClientType); - await testDeadletter(); - } - ); - - async function testRenewLock(): Promise { - const testMessages = entityNames.usesSessions - ? TestMessage.getSessionSample() - : TestMessage.getSample(); - const msg = await sendReceiveMsg(testMessages); - await receiver.close(); - let errorWasThrown = false; - try { - const lockedUntilBeforeRenewlock = msg.lockedUntilUtc; - const lockedUntilAfterRenewlock = await msg.renewLock(); - should.equal( - lockedUntilAfterRenewlock > lockedUntilBeforeRenewlock!, - true, - "MessageLock did not get renewed!" - ); - await msg.complete(); - } catch (err) { - should.equal( - err.message, - `Invalid operation on the message, message lock doesn't exist when dealing with sessions`, - "Unexpected error thrown" - ); - errorWasThrown = true; - } - - receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); - if (entityNames.usesSessions) { - should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); - const msgBatch = await receiver.receiveMessages(1); - await msgBatch[0].complete(); - } else { - should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); - } - await testPeekMsgsLength(receiver, 0); - } - - it(noSessionTestClientType + ": Lock renewal for a message", async function(): Promise { - await beforeEachTest(noSessionTestClientType); - await testRenewLock(); - }); - - it(withSessionTestClientType + ": Lock renewal for session", async function(): Promise { - await beforeEachTest(withSessionTestClientType); - await testRenewLock(); - }); -}); +// // Copyright (c) Microsoft Corporation. +// // Licensed under the MIT license. + +// import chai from "chai"; +// import chaiAsPromised from "chai-as-promised"; +// import { ServiceBusMessage } from "../src"; +// import { TestClientType, TestMessage } from "./utils/testUtils"; +// import { ServiceBusReceiver } from "../src/receivers/receiver"; +// import { ServiceBusSender } from "../src/sender"; +// import { +// EntityName, +// ServiceBusClientForTests, +// createServiceBusClientForTests, +// testPeekMsgsLength, +// getRandomTestClientTypeWithSessions, +// getRandomTestClientTypeWithNoSessions +// } from "./utils/testutils2"; +// import { DispositionType, ServiceBusReceivedMessage } from "../src/serviceBusMessage"; + +// const should = chai.should(); +// chai.use(chaiAsPromised); + +// const noSessionTestClientType = getRandomTestClientTypeWithNoSessions(); +// const withSessionTestClientType = getRandomTestClientTypeWithSessions(); + +// describe("Message settlement After Receiver is Closed - Through ManagementLink", () => { +// let serviceBusClient: ServiceBusClientForTests; + +// let sender: ServiceBusSender; +// let receiver: ServiceBusReceiver; +// let deadLetterReceiver: ServiceBusReceiver; +// let entityNames: EntityName; + +// before(() => { +// serviceBusClient = createServiceBusClientForTests(); +// }); + +// after(() => { +// return serviceBusClient.test.after(); +// }); + +// async function beforeEachTest(entityType: TestClientType): Promise { +// entityNames = await serviceBusClient.test.createTestEntities(entityType); +// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + +// sender = serviceBusClient.test.addToCleanup( +// serviceBusClient.createSender(entityNames.queue ?? entityNames.topic!) +// ); + +// deadLetterReceiver = serviceBusClient.test.createDeadLetterReceiver(entityNames); +// } + +// afterEach(async () => { +// await serviceBusClient.test.afterEach(); +// }); + +// async function sendReceiveMsg( +// testMessages: ServiceBusMessage +// ): Promise { +// await sender.sendMessages(testMessages); +// const msgs = await receiver.receiveMessages(1); + +// should.equal(Array.isArray(msgs), true, "`ReceivedMessages` is not an array"); +// should.equal(msgs.length, 1, "Unexpected number of messages"); +// should.equal(msgs[0].body, testMessages.body, "MessageBody is different than expected"); +// should.equal(msgs[0].messageId, testMessages.messageId, "MessageId is different than expected"); +// should.equal(msgs[0].deliveryCount, 0, "DeliveryCount is different than expected"); + +// return msgs[0]; +// } + +// async function testComplete(): Promise { +// const testMessages = entityNames.usesSessions +// ? TestMessage.getSessionSample() +// : TestMessage.getSample(); +// const msg = await sendReceiveMsg(testMessages); +// await receiver.close(); +// let errorWasThrown = false; +// try { +// await msg.complete(); +// } catch (err) { +// should.equal( +// err.message, +// `Failed to ${DispositionType.complete} the message as the AMQP link with which the message was received is no longer alive.`, +// "Unexpected error thrown" +// ); +// errorWasThrown = true; +// } + +// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); +// if (entityNames.usesSessions) { +// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); +// const msgBatch = await receiver.receiveMessages(1); +// await msgBatch[0].complete(); +// } else { +// should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); +// } +// await testPeekMsgsLength(receiver, 0); +// } + +// it(noSessionTestClientType + ": complete() removes message", async function(): Promise { +// await beforeEachTest(noSessionTestClientType); +// await testComplete(); +// }); + +// it(withSessionTestClientType + ": complete() removes message", async function(): Promise { +// await beforeEachTest(withSessionTestClientType); +// await testComplete(); +// }); + +// async function testAbandon(): Promise { +// const testMessages = entityNames.usesSessions +// ? TestMessage.getSessionSample() +// : TestMessage.getSample(); +// const msg = await sendReceiveMsg(testMessages); +// await receiver.close(); +// let errorWasThrown = false; +// try { +// await msg.abandon(); +// } catch (err) { +// should.equal( +// err.message, +// `Failed to ${DispositionType.abandon} the message as the AMQP link with which the message was received is no longer alive.`, +// "Unexpected error thrown" +// ); +// errorWasThrown = true; +// } + +// if (entityNames.usesSessions) { +// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); +// } else { +// should.equal(errorWasThrown, false, "Error was thrown for messages without session-id"); +// } +// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); +// await testPeekMsgsLength(receiver, 1); + +// const messageBatch = await receiver.receiveMessages(1); + +// await messageBatch[0].complete(); + +// await testPeekMsgsLength(receiver, 0); +// } + +// it( +// noSessionTestClientType + ": abandon() retains message with incremented deliveryCount", +// async function(): Promise { +// await beforeEachTest(noSessionTestClientType); +// await testAbandon(); +// } +// ); + +// it( +// withSessionTestClientType + ": abandon() retains message with incremented deliveryCount", +// async function(): Promise { +// await beforeEachTest(withSessionTestClientType); +// await testAbandon(); +// } +// ); + +// async function testDefer(): Promise { +// const testMessages = entityNames.usesSessions +// ? TestMessage.getSessionSample() +// : TestMessage.getSample(); +// const msg = await sendReceiveMsg(testMessages); + +// if (!msg.sequenceNumber) { +// throw "Sequence Number can not be null"; +// } +// const sequenceNumber = msg.sequenceNumber; +// await receiver.close(); +// let errorWasThrown = false; +// try { +// await msg.defer(); +// } catch (err) { +// should.equal( +// err.message, +// `Failed to ${DispositionType.defer} the message as the AMQP link with which the message was received is no longer alive.`, +// "Unexpected error thrown" +// ); +// errorWasThrown = true; +// } + +// if (entityNames.usesSessions) { +// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); +// } else { +// should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); +// } +// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); +// if (!entityNames.usesSessions) { +// const [deferredMsg] = await receiver.receiveDeferredMessages(sequenceNumber); +// if (!deferredMsg) { +// throw "No message received for sequence number"; +// } +// await deferredMsg.complete(); +// } else { +// const messageBatch = await receiver.receiveMessages(1); +// await messageBatch[0].complete(); +// } +// await testPeekMsgsLength(receiver, 0); +// } + +// it( +// noSessionTestClientType + ": defer() moves message to deferred queue", +// async function(): Promise { +// await beforeEachTest(noSessionTestClientType); +// await testDefer(); +// } +// ); + +// it( +// withSessionTestClientType + ": defer() moves message to deferred queue", +// async function(): Promise { +// await beforeEachTest(withSessionTestClientType); +// await testDefer(); +// } +// ); + +// async function testDeadletter(): Promise { +// const testMessages = entityNames.usesSessions +// ? TestMessage.getSessionSample() +// : TestMessage.getSample(); +// const msg = await sendReceiveMsg(testMessages); +// await receiver.close(); +// let errorWasThrown = false; +// try { +// await msg.deadLetter(); +// } catch (err) { +// should.equal( +// err.message, +// `Failed to ${DispositionType.deadletter} the message as the AMQP link with which the message was received is no longer alive.`, +// "Unexpected error thrown" +// ); +// errorWasThrown = true; +// } + +// if (entityNames.usesSessions) { +// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); +// } else { +// should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); +// } + +// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + +// if (!entityNames.usesSessions) { +// const deadLetterMsgsBatch = await deadLetterReceiver.receiveMessages(1); + +// should.equal( +// Array.isArray(deadLetterMsgsBatch), +// true, +// "`ReceivedMessages` from Deadletter is not an array" +// ); +// should.equal(deadLetterMsgsBatch.length, 1, "Unexpected number of messages"); +// should.equal( +// deadLetterMsgsBatch[0].body, +// testMessages.body, +// "MessageBody is different than expected" +// ); +// should.equal( +// deadLetterMsgsBatch[0].messageId, +// testMessages.messageId, +// "MessageId is different than expected" +// ); + +// await deadLetterMsgsBatch[0].complete(); + +// await testPeekMsgsLength(deadLetterReceiver, 0); +// } else { +// const messageBatch = await receiver.receiveMessages(1); +// await messageBatch[0].complete(); + +// await testPeekMsgsLength(receiver, 0); +// } +// } + +// it( +// noSessionTestClientType + ": deadLetter() moves message to deadletter queue", +// async function(): Promise { +// await beforeEachTest(noSessionTestClientType); +// await testDeadletter(); +// } +// ); + +// it( +// withSessionTestClientType + ": deadLetter() moves message to deadletter queue", +// async function(): Promise { +// await beforeEachTest(withSessionTestClientType); +// await testDeadletter(); +// } +// ); + +// async function testRenewLock(): Promise { +// const testMessages = entityNames.usesSessions +// ? TestMessage.getSessionSample() +// : TestMessage.getSample(); +// const msg = await sendReceiveMsg(testMessages); +// await receiver.close(); +// let errorWasThrown = false; +// try { +// const lockedUntilBeforeRenewlock = msg.lockedUntilUtc; +// const lockedUntilAfterRenewlock = await msg.renewLock(); +// should.equal( +// lockedUntilAfterRenewlock > lockedUntilBeforeRenewlock!, +// true, +// "MessageLock did not get renewed!" +// ); +// await msg.complete(); +// } catch (err) { +// should.equal( +// err.message, +// `Invalid operation on the message, message lock doesn't exist when dealing with sessions`, +// "Unexpected error thrown" +// ); +// errorWasThrown = true; +// } + +// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); +// if (entityNames.usesSessions) { +// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); +// const msgBatch = await receiver.receiveMessages(1); +// await msgBatch[0].complete(); +// } else { +// should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); +// } +// await testPeekMsgsLength(receiver, 0); +// } + +// it(noSessionTestClientType + ": Lock renewal for a message", async function(): Promise { +// await beforeEachTest(noSessionTestClientType); +// await testRenewLock(); +// }); + +// it(withSessionTestClientType + ": Lock renewal for session", async function(): Promise { +// await beforeEachTest(withSessionTestClientType); +// await testRenewLock(); +// }); +// }); diff --git a/sdk/servicebus/service-bus/test/batchReceiver.spec.ts b/sdk/servicebus/service-bus/test/batchReceiver.spec.ts index e7d76d0e33a5..413cc682ce7b 100644 --- a/sdk/servicebus/service-bus/test/batchReceiver.spec.ts +++ b/sdk/servicebus/service-bus/test/batchReceiver.spec.ts @@ -18,10 +18,7 @@ import { EntityName, getRandomTestClientType } from "./utils/testutils2"; -import { - ServiceBusReceivedMessage, - ServiceBusReceivedMessageWithLock -} from "../src/serviceBusMessage"; +import { ServiceBusReceivedMessage } from "../src/serviceBusMessage"; import { AbortController } from "@azure/abort-controller"; import { ReceiverEvents } from "rhea-promise"; @@ -35,8 +32,8 @@ const anyRandomTestClientType = getRandomTestClientType(); let serviceBusClient: ServiceBusClientForTests; let entityNames: EntityName; let sender: ServiceBusSender; -let receiver: ServiceBusReceiver; -let deadLetterReceiver: ServiceBusReceiver; +let receiver: ServiceBusReceiver; +let deadLetterReceiver: ServiceBusReceiver; async function beforeEachTest(entityType: TestClientType): Promise { entityNames = await serviceBusClient.test.createTestEntities(entityType); @@ -96,7 +93,7 @@ describe("Batching Receiver", () => { testMessage.body, "Received message body is different than expected" ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); }); it(withSessionTestClientType + ": maxMessageCount defaults to 1", async function(): Promise< @@ -123,7 +120,7 @@ describe("Batching Receiver", () => { testMessage.body, "Received message body is different than expected" ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); }); }); @@ -144,7 +141,7 @@ describe("Batching Receiver", () => { async function sendReceiveMsg( testMessages: ServiceBusMessage - ): Promise { + ): Promise { await sender.sendMessages(testMessages); const msgs = await receiver.receiveMessages(1); @@ -167,7 +164,7 @@ describe("Batching Receiver", () => { : TestMessage.getSample(); const msg = await sendReceiveMsg(testMessages); - await msg.complete(); + await receiver.completeMessage(msg); await testPeekMsgsLength(receiver, 0); } @@ -187,7 +184,7 @@ describe("Batching Receiver", () => { ? TestMessage.getSessionSample() : TestMessage.getSample(); const msg = await sendReceiveMsg(testMessages); - await msg.abandon(); + await receiver.abandonMessage(msg); await testPeekMsgsLength(receiver, 1); @@ -201,7 +198,7 @@ describe("Batching Receiver", () => { "MessageId is different than expected" ); - await messageBatch[0].complete(); + await receiver.completeMessage(messageBatch[0]); await testPeekMsgsLength(receiver, 0); } @@ -245,7 +242,7 @@ describe("Batching Receiver", () => { ); abandonMsgCount++; - await batch[0].abandon(); + await receiver.abandonMessage(batch[0]); } await testPeekMsgsLength(receiver, 0); @@ -269,7 +266,7 @@ describe("Batching Receiver", () => { "MessageId is different than expected" ); - await deadLetterMsgsBatch[0].complete(); + await receiver.completeMessage(deadLetterMsgsBatch[0]); await testPeekMsgsLength(deadLetterReceiver, 0); } @@ -300,7 +297,7 @@ describe("Batching Receiver", () => { throw "Sequence Number can not be null"; } const sequenceNumber = msg.sequenceNumber; - await msg.defer(); + await receiver.deferMessage(msg); const [deferredMsg] = await receiver.receiveDeferredMessages(sequenceNumber); if (!deferredMsg) { @@ -314,7 +311,7 @@ describe("Batching Receiver", () => { ); should.equal(deferredMsg.deliveryCount, 1, "DeliveryCount is different than expected"); - await deferredMsg.complete(); + await receiver.completeMessage(deferredMsg); await testPeekMsgsLength(receiver, 0); } @@ -340,7 +337,7 @@ describe("Batching Receiver", () => { ? TestMessage.getSessionSample() : TestMessage.getSample(); const msg = await sendReceiveMsg(testMessages); - await msg.deadLetter(); + await receiver.deadLetterMessage(msg); await testPeekMsgsLength(receiver, 0); @@ -363,7 +360,7 @@ describe("Batching Receiver", () => { "MessageId is different than expected" ); - await deadLetterMsgsBatch[0].complete(); + await receiver.completeMessage(deadLetterMsgsBatch[0]); await testPeekMsgsLength(deadLetterReceiver, 0); } @@ -400,7 +397,7 @@ describe("Batching Receiver", () => { async function deadLetterMessage( testMessage: ServiceBusMessage - ): Promise { + ): Promise { await sender.sendMessages(testMessage); const batch = await receiver.receiveMessages(1); @@ -413,7 +410,7 @@ describe("Batching Receiver", () => { ); should.equal(batch[0].deliveryCount, 0, "DeliveryCount is different than expected"); - await batch[0].deadLetter(); + await receiver.deadLetterMessage(batch[0]); await testPeekMsgsLength(receiver, 0); @@ -441,7 +438,7 @@ describe("Batching Receiver", () => { async function completeDeadLetteredMessage( testMessage: ServiceBusMessage, - deadletterClient: ServiceBusReceiver, + deadletterClient: ServiceBusReceiver, expectedDeliverCount: number ): Promise { const deadLetterMsgsBatch = await deadLetterReceiver.receiveMessages(1); @@ -463,7 +460,7 @@ describe("Batching Receiver", () => { "DeliveryCount is different than expected" ); - await deadLetterMsgsBatch[0].complete(); + await receiver.completeMessage(deadLetterMsgsBatch[0]); await testPeekMsgsLength(deadletterClient, 0); } @@ -474,7 +471,7 @@ describe("Batching Receiver", () => { const deadLetterMsg = await deadLetterMessage(testMessage); let errorWasThrown = false; - await deadLetterMsg.deadLetter().catch((err) => { + await receiver.deadLetterMessage(deadLetterMsg).catch((err) => { should.equal(err.code, "InvalidOperationError", "Error code is different than expected"); errorWasThrown = true; }); @@ -498,7 +495,7 @@ describe("Batching Receiver", () => { : TestMessage.getSessionSample(); const deadLetterMsg = await deadLetterMessage(testMessage); - await deadLetterMsg.abandon(); + await receiver.abandonMessage(deadLetterMsg); await completeDeadLetteredMessage(testMessage, deadLetterReceiver, 0); } @@ -522,7 +519,7 @@ describe("Batching Receiver", () => { } const sequenceNumber = deadLetterMsg.sequenceNumber; - await deadLetterMsg.defer(); + await receiver.deferMessage(deadLetterMsg); const [deferredMsg] = await deadLetterReceiver.receiveDeferredMessages(sequenceNumber); if (!deferredMsg) { @@ -535,7 +532,7 @@ describe("Batching Receiver", () => { "MessageId is different than expected" ); - await deferredMsg.complete(); + await receiver.completeMessage(deferredMsg); await testPeekMsgsLength(receiver, 0); @@ -690,8 +687,8 @@ describe("Batching Receiver", () => { "MessageId is different than expected" ); - await msgs1[0].complete(); - await msgs2[0].complete(); + await receiver.completeMessage(msgs1[0]); + await receiver.completeMessage(msgs2[0]); } it( @@ -779,7 +776,7 @@ describe("Batching Receiver", () => { "MessageId is different than expected" ); - await batch[0].complete(); + await receiver.completeMessage(batch[0]); } it( @@ -815,7 +812,7 @@ describe("Batching Receiver", () => { "MessageId is different than expected" ); - await batch[0].complete(); + await receiver.completeMessage(batch[0]); await testPeekMsgsLength(receiver, 0); } @@ -881,9 +878,7 @@ describe("Batching Receiver", () => { describe(noSessionTestClientType + ": Batch Receiver - disconnects", function(): void { let serviceBusClient: ServiceBusClientForTests; let sender: ServiceBusSender; - let receiver: - | ServiceBusReceiver - | ServiceBusReceiver; + let receiver: ServiceBusReceiver; async function beforeEachTest( receiveMode: "peekLock" | "receiveAndDelete" = "peekLock" @@ -917,13 +912,11 @@ describe("Batching Receiver", () => { let settledMessageCount = 0; - const messages1 = await (receiver as ServiceBusReceiver< - ServiceBusReceivedMessageWithLock - >).receiveMessages(1, { + const messages1 = await receiver.receiveMessages(1, { maxWaitTimeInMs: 5000 }); for (const message of messages1) { - await message.complete(); + await receiver.completeMessage(message); settledMessageCount++; } @@ -938,21 +931,17 @@ describe("Batching Receiver", () => { }; // Simulate a disconnect being called with a non-retryable error. - (receiver as ServiceBusReceiverImpl)[ - "_context" - ].connection["_connection"].idle(); + (receiver as ServiceBusReceiverImpl)["_context"].connection["_connection"].idle(); // send a second message to trigger the message handler again. await sender.sendMessages(TestMessage.getSample()); // wait for the 2nd message to be received. - const messages2 = await (receiver as ServiceBusReceiver< - ServiceBusReceivedMessageWithLock - >).receiveMessages(1, { + const messages2 = await (receiver as ServiceBusReceiver).receiveMessages(1, { maxWaitTimeInMs: 5000 }); for (const message of messages2) { - await message.complete(); + await receiver.completeMessage(message); settledMessageCount++; } settledMessageCount.should.equal(2, "Unexpected number of settled messages."); @@ -969,12 +958,8 @@ describe("Batching Receiver", () => { // The `receiver_drained` handler is only added after the link is created, // which is a non-blocking task. await receiver.receiveMessages(1, { maxWaitTimeInMs: 1000 }); - const receiverContext = (receiver as ServiceBusReceiverImpl< - ServiceBusReceivedMessageWithLock - >)["_context"]; - const batchingReceiver = (receiver as ServiceBusReceiverImpl)[ - "_batchingReceiver" - ]; + const receiverContext = (receiver as ServiceBusReceiverImpl)["_context"]; + const batchingReceiver = (receiver as ServiceBusReceiverImpl)["_batchingReceiver"]; if (!batchingReceiver || !batchingReceiver.isOpen()) { throw new Error(`Unable to initialize receiver link.`); @@ -1034,12 +1019,8 @@ describe("Batching Receiver", () => { // The `receiver_drained` handler is only added after the link is created, // which is a non-blocking task. await receiver.receiveMessages(1, { maxWaitTimeInMs: 1000 }); - const receiverContext = (receiver as ServiceBusReceiverImpl< - ServiceBusReceivedMessageWithLock - >)["_context"]; - const batchingReceiver = (receiver as ServiceBusReceiverImpl)[ - "_batchingReceiver" - ]; + const receiverContext = (receiver as ServiceBusReceiverImpl)["_context"]; + const batchingReceiver = (receiver as ServiceBusReceiverImpl)["_batchingReceiver"]; if (!batchingReceiver || !batchingReceiver.isOpen()) { throw new Error(`Unable to initialize receiver link.`); @@ -1106,12 +1087,8 @@ describe("Batching Receiver", () => { // The `receiver_drained` handler is only added after the link is created, // which is a non-blocking task. await receiver.receiveMessages(1, { maxWaitTimeInMs: 1000 }); - const receiverContext = (receiver as ServiceBusReceiverImpl)[ - "_context" - ]; - const batchingReceiver = (receiver as ServiceBusReceiverImpl)[ - "_batchingReceiver" - ]; + const receiverContext = (receiver as ServiceBusReceiverImpl)["_context"]; + const batchingReceiver = (receiver as ServiceBusReceiverImpl)["_batchingReceiver"]; if (!batchingReceiver || !batchingReceiver.isOpen()) { throw new Error(`Unable to initialize receiver link.`); @@ -1152,12 +1129,8 @@ describe("Batching Receiver", () => { // The `receiver_drained` handler is only added after the link is created, // which is a non-blocking task. await receiver.receiveMessages(1, { maxWaitTimeInMs: 1000 }); - const receiverContext = (receiver as ServiceBusReceiverImpl< - ServiceBusReceivedMessageWithLock - >)["_context"]; - const batchingReceiver = (receiver as ServiceBusReceiverImpl)[ - "_batchingReceiver" - ]; + const receiverContext = (receiver as ServiceBusReceiverImpl)["_context"]; + const batchingReceiver = (receiver as ServiceBusReceiverImpl)["_batchingReceiver"]; if (!batchingReceiver || !batchingReceiver.isOpen()) { throw new Error(`Unable to initialize receiver link.`); diff --git a/sdk/servicebus/service-bus/test/deferredMessage.spec.ts b/sdk/servicebus/service-bus/test/deferredMessage.spec.ts index e7fdb07e9d37..19ec81f802e2 100644 --- a/sdk/servicebus/service-bus/test/deferredMessage.spec.ts +++ b/sdk/servicebus/service-bus/test/deferredMessage.spec.ts @@ -16,13 +16,13 @@ import { } from "./utils/testutils2"; import { ServiceBusReceiver } from "../src/receivers/receiver"; import { ServiceBusSender } from "../src/sender"; -import { ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; +import { ServiceBusReceivedMessage } from "../src/serviceBusMessage"; describe("Deferred Messages", () => { let serviceBusClient: ReturnType; let sender: ServiceBusSender; - let receiver: ServiceBusReceiver; - let deadLetterReceiver: ServiceBusReceiver; + let receiver: ServiceBusReceiver; + let deadLetterReceiver: ServiceBusReceiver; let entityNames: EntityName; const noSessionTestClientType = getRandomTestClientTypeWithNoSessions(); @@ -61,7 +61,7 @@ describe("Deferred Messages", () => { async function deferMessage( testMessage: ServiceBusMessage, passSequenceNumberInArray: boolean - ): Promise { + ): Promise { await sender.sendMessages(testMessage); const receivedMsgs = await receiver.receiveMessages(1); @@ -78,7 +78,7 @@ describe("Deferred Messages", () => { throw "Sequence Number can not be null"; } const sequenceNumber = receivedMsgs[0].sequenceNumber; - await receivedMsgs[0].defer(); + await receiver.deferMessage(receivedMsgs[0]); const [deferredMsg] = await receiver.receiveDeferredMessages( passSequenceNumberInArray ? [sequenceNumber] : sequenceNumber @@ -121,7 +121,7 @@ describe("Deferred Messages", () => { "MessageId is different than expected" ); - await deferredMsg.complete(); + await receiver.completeMessage(deferredMsg); await testPeekMsgsLength(receiver, 0); } @@ -135,7 +135,7 @@ describe("Deferred Messages", () => { if (!sequenceNumber) { throw "Sequence Number can not be null"; } - await deferredMsg.abandon(); + await receiver.abandonMessage(deferredMsg); await completeDeferredMessage(sequenceNumber, 2, testMessages); } @@ -165,7 +165,7 @@ describe("Deferred Messages", () => { if (!sequenceNumber) { throw "Sequence Number can not be null"; } - await deferredMsg.defer(); + await receiver.deferMessage(deferredMsg); await completeDeferredMessage(sequenceNumber, 2, testMessages); } it( @@ -191,7 +191,7 @@ describe("Deferred Messages", () => { : TestMessage.getSample(); const deferredMsg = await deferMessage(testMessages, true); - await deferredMsg.deadLetter(); + await receiver.deadLetterMessage(deferredMsg); await testPeekMsgsLength(receiver, 0); @@ -210,7 +210,7 @@ describe("Deferred Messages", () => { "MessageId is different than expected" ); - await deadLetterMsgs[0].complete(); + await receiver.completeMessage(deadLetterMsgs[0]); await testPeekMsgsLength(deadLetterReceiver, 0); } @@ -242,13 +242,13 @@ describe("Deferred Messages", () => { throw "Sequence Number can not be null"; } const lockedUntilBeforeRenewlock = deferredMsg.lockedUntilUtc; - const lockedUntilAfterRenewlock = await deferredMsg.renewLock(); + const lockedUntilAfterRenewlock = await receiver.renewMessageLock(deferredMsg); should.equal( lockedUntilAfterRenewlock > lockedUntilBeforeRenewlock!, true, "MessageLock did not get renewed!" ); - await deferredMsg.defer(); + await receiver.deferMessage(deferredMsg); await completeDeferredMessage(sequenceNumber, 2, testMessages); }); }); diff --git a/sdk/servicebus/service-bus/test/internal/receiver.spec.ts b/sdk/servicebus/service-bus/test/internal/receiver.spec.ts index 271fd92cbabf..55ca79c4c8b0 100644 --- a/sdk/servicebus/service-bus/test/internal/receiver.spec.ts +++ b/sdk/servicebus/service-bus/test/internal/receiver.spec.ts @@ -4,7 +4,6 @@ import chai from "chai"; import chaiAsPromised from "chai-as-promised"; import { Receiver, ReceiverEvents, ReceiverOptions } from "rhea-promise"; -import { ServiceBusReceivedMessage, ServiceBusReceivedMessageWithLock } from "../../src"; chai.use(chaiAsPromised); const assert = chai.assert; @@ -89,7 +88,7 @@ describe("Receiver unit tests", () => { let createdRheaReceiver: Receiver | undefined; - const receiverImpl = new ServiceBusReceiverImpl( + const receiverImpl = new ServiceBusReceiverImpl( createConnectionContextForTests({ onCreateReceiverCalled: (receiver) => { createdRheaReceiver = receiver; @@ -226,9 +225,9 @@ describe("Receiver unit tests", () => { await receiverImpl.close(); }); - async function subscribeAndWaitForInitialize< - T extends ServiceBusReceivedMessage | ServiceBusReceivedMessageWithLock - >(receiver: ServiceBusReceiverImpl): Promise> { + async function subscribeAndWaitForInitialize( + receiver: ServiceBusReceiverImpl + ): Promise> { const sub = await new Promise<{ close(): Promise; }>((resolve, reject) => { @@ -240,7 +239,7 @@ describe("Receiver unit tests", () => { reject(err); }, processMessage: async (_msg) => {} - } as InternalMessageHandlers); + } as InternalMessageHandlers); }); assert.exists( diff --git a/sdk/servicebus/service-bus/test/internal/serviceBusClient.spec.ts b/sdk/servicebus/service-bus/test/internal/serviceBusClient.spec.ts index 3a0349b6c616..24d11b3889f1 100644 --- a/sdk/servicebus/service-bus/test/internal/serviceBusClient.spec.ts +++ b/sdk/servicebus/service-bus/test/internal/serviceBusClient.spec.ts @@ -56,7 +56,7 @@ describe("serviceBusClient unit tests", () => { origConnectionContext.config ); - let sessionReceiver: ServiceBusSessionReceiver; + let sessionReceiver: ServiceBusSessionReceiver; if (testEntity.queue) { sessionReceiver = await client.acceptSession(testEntity.queue, "a session id", { @@ -83,7 +83,7 @@ describe("serviceBusClient unit tests", () => { assert.equal(sessionReceiver.entityPath, testEntity.entityPath); assert.equal(sessionReceiver.sessionId, "a session id"); - const impl = sessionReceiver as ServiceBusSessionReceiverImpl; + const impl = sessionReceiver as ServiceBusSessionReceiverImpl; assert.equal(impl["_messageSession"]["maxAutoRenewDurationInMs"], 101); assert.isTrue(abortSignalStuff.abortedPropertyWasChecked); @@ -109,7 +109,7 @@ describe("serviceBusClient unit tests", () => { origConnectionContext.config ); - let sessionReceiver: ServiceBusSessionReceiver; + let sessionReceiver: ServiceBusSessionReceiver; if (testEntity.queue) { sessionReceiver = await client.acceptNextSession(testEntity.queue, { @@ -135,7 +135,7 @@ describe("serviceBusClient unit tests", () => { assert.equal(sessionReceiver.entityPath, testEntity.entityPath); assert.equal(sessionReceiver.sessionId, "session id"); - const impl = sessionReceiver as ServiceBusSessionReceiverImpl; + const impl = sessionReceiver as ServiceBusSessionReceiverImpl; assert.equal(impl["_messageSession"]["maxAutoRenewDurationInMs"], 101); assert.isTrue(abortSignalStuff.abortedPropertyWasChecked); diff --git a/sdk/servicebus/service-bus/test/internal/shared.spec.ts b/sdk/servicebus/service-bus/test/internal/shared.spec.ts index deb98b0ce0d1..b36d4b045051 100644 --- a/sdk/servicebus/service-bus/test/internal/shared.spec.ts +++ b/sdk/servicebus/service-bus/test/internal/shared.spec.ts @@ -39,12 +39,13 @@ describe("shared", () => { [], [ { - id: "hello" + body: "hello", + _amqpAnnotatedMessage: {} } ] ]; - const receiver: Pick, "receiveMessages"> = { + const receiver: Pick = { receiveMessages: async (maxMessageCount, _options) => { assert.equal(maxMessageCount, 1); @@ -68,7 +69,12 @@ describe("shared", () => { } catch (err) { assert.equal("We're okay to end it now", err.message); assert.deepEqual( - [{ id: "hello" }], + [ + { + body: "hello", + _amqpAnnotatedMessage: {} + } + ], allReceivedMessages, "We should only get one message. We don't return anything when the receive returns nothing." ); diff --git a/sdk/servicebus/service-bus/test/invalidParameters.spec.ts b/sdk/servicebus/service-bus/test/invalidParameters.spec.ts index 1a02c4578d64..6868b975fdb5 100644 --- a/sdk/servicebus/service-bus/test/invalidParameters.spec.ts +++ b/sdk/servicebus/service-bus/test/invalidParameters.spec.ts @@ -9,7 +9,6 @@ chai.use(chaiAsPromised); import { TestClientType, TestMessage } from "./utils/testUtils"; import { ServiceBusClientForTests, createServiceBusClientForTests } from "./utils/testutils2"; import { ServiceBusSender } from "../src/sender"; -import { ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; import { ServiceBusClient, ServiceBusSessionReceiver } from "../src"; describe("invalid parameters", () => { @@ -25,7 +24,7 @@ describe("invalid parameters", () => { describe("Invalid parameters in SessionReceiver", function(): void { let sender: ServiceBusSender; - let receiver: ServiceBusSessionReceiver; + let receiver: ServiceBusSessionReceiver; // Since, the below tests never actually make use of any AMQP links, there is no need to create // new sender/receiver clients before each test. Doing it once for each describe block. diff --git a/sdk/servicebus/service-bus/test/managementClient.spec.ts b/sdk/servicebus/service-bus/test/managementClient.spec.ts index ca00481c25d3..30be30bf339f 100644 --- a/sdk/servicebus/service-bus/test/managementClient.spec.ts +++ b/sdk/servicebus/service-bus/test/managementClient.spec.ts @@ -3,7 +3,7 @@ import chai from "chai"; import chaiAsPromised from "chai-as-promised"; -import { ServiceBusReceivedMessageWithLock, ServiceBusSender, ServiceBusReceiver } from "../src"; +import { ServiceBusSender, ServiceBusReceiver } from "../src"; import { TestClientType, TestMessage } from "./utils/testUtils"; import { ServiceBusClientForTests, createServiceBusClientForTests } from "./utils/testutils2"; chai.should(); @@ -12,7 +12,7 @@ chai.use(chaiAsPromised); describe("ManagementClient - disconnects", function(): void { let serviceBusClient: ServiceBusClientForTests; let sender: ServiceBusSender; - let receiver: ServiceBusReceiver; + let receiver: ServiceBusReceiver; async function beforeEachTest(entityType: TestClientType): Promise { const entityNames = await serviceBusClient.test.createTestEntities(entityType); diff --git a/sdk/servicebus/service-bus/test/propsToModify.spec.ts b/sdk/servicebus/service-bus/test/propsToModify.spec.ts index bf27c5512973..7e57950ef5f1 100644 --- a/sdk/servicebus/service-bus/test/propsToModify.spec.ts +++ b/sdk/servicebus/service-bus/test/propsToModify.spec.ts @@ -6,17 +6,13 @@ const should = chai.should(); import { createServiceBusClientForTests } from "./utils/testutils2"; import { TestClientType, TestMessage } from "./utils/testUtils"; -import { - ServiceBusReceivedMessage, - ServiceBusReceivedMessageWithLock, - ServiceBusReceiver -} from "../src"; +import { ServiceBusReceivedMessage, ServiceBusReceiver } from "../src"; describe("dead lettering", () => { let serviceBusClient: ReturnType; - let deadLetterReceiver: ServiceBusReceiver; - let receiver: ServiceBusReceiver; - let receivedMessage: ServiceBusReceivedMessageWithLock; + let deadLetterReceiver: ServiceBusReceiver; + let receiver: ServiceBusReceiver; + let receivedMessage: ServiceBusReceivedMessage; before(() => { serviceBusClient = createServiceBusClientForTests(); @@ -72,13 +68,13 @@ describe("dead lettering", () => { it("dead lettering a deferred message", async () => { await beforeEachTest(TestClientType.UnpartitionedQueue); // defer this message so we can pick it up via the management API - await receivedMessage.defer(); + await receiver.deferMessage(receivedMessage); const [deferredMessage] = await receiver.receiveDeferredMessages( receivedMessage.sequenceNumber! ); - await deferredMessage!.deadLetter({ + await receiver.deadLetterMessage(deferredMessage, { deadLetterErrorDescription: "this is the dead letter error description (was deferred)", deadLetterReason: "this is the dead letter reason (was deferred)", customProperty: "hello, setting this custom property" @@ -94,7 +90,7 @@ describe("dead lettering", () => { it("dead lettering a typical received message", async () => { await beforeEachTest(TestClientType.UnpartitionedQueue); - await receivedMessage.deadLetter({ + await receiver.deadLetterMessage(receivedMessage, { deadLetterErrorDescription: "this is the dead letter error description", deadLetterReason: "this is the dead letter reason", customProperty: "hello, setting this custom property" @@ -114,13 +110,13 @@ describe("dead lettering", () => { it("dead lettering a deferred message - sessions", async () => { await beforeEachTest(TestClientType.UnpartitionedQueueWithSessions); // defer this message so we can pick it up via the management API - await receivedMessage.defer(); + await receiver.deferMessage(receivedMessage); const [deferredMessage] = await receiver.receiveDeferredMessages( receivedMessage.sequenceNumber! ); - await deferredMessage!.deadLetter({ + await receiver.deadLetterMessage(deferredMessage, { deadLetterErrorDescription: "this is the dead letter error description (was deferred)", deadLetterReason: "this is the dead letter reason (was deferred)", customProperty: "hello, setting this custom property" @@ -136,7 +132,7 @@ describe("dead lettering", () => { it("dead lettering a typical received message - sessions", async () => { await beforeEachTest(TestClientType.UnpartitionedQueueWithSessions); - await receivedMessage.deadLetter({ + await receiver.deadLetterMessage(receivedMessage, { deadLetterErrorDescription: "this is the dead letter error description", deadLetterReason: "this is the dead letter reason", customProperty: "hello, setting this custom property" @@ -170,8 +166,8 @@ describe("dead lettering", () => { describe("abandoning", () => { let serviceBusClient: ReturnType; - let receiver: ServiceBusReceiver; - let receivedMessage: ServiceBusReceivedMessageWithLock; + let receiver: ServiceBusReceiver; + let receivedMessage: ServiceBusReceivedMessage; before(() => { serviceBusClient = createServiceBusClientForTests(); @@ -216,13 +212,13 @@ describe("abandoning", () => { it("abandoning a deferred message", async () => { await beforeEachTest(TestClientType.UnpartitionedQueue); // defer this message so we can pick it up via the management API - await receivedMessage.defer(); + await receiver.deferMessage(receivedMessage); const [deferredMessage] = await receiver.receiveDeferredMessages( receivedMessage.sequenceNumber! ); - await deferredMessage!.abandon({ + await receiver.abandonMessage(deferredMessage, { customProperty: "hello, setting this custom property" }); @@ -236,7 +232,7 @@ describe("abandoning", () => { it("abandoning a typical received message", async () => { await beforeEachTest(TestClientType.UnpartitionedQueue); - await receivedMessage.abandon({ + await receiver.abandonMessage(receivedMessage, { customProperty: "hello, setting this custom property" }); @@ -249,13 +245,13 @@ describe("abandoning", () => { it("abandoning a deferred message - sessions", async () => { await beforeEachTest(TestClientType.UnpartitionedQueueWithSessions); // defer this message so we can pick it up via the management API - await receivedMessage.defer(); + await receiver.deferMessage(receivedMessage); const [deferredMessage] = await receiver.receiveDeferredMessages( receivedMessage.sequenceNumber! ); - await deferredMessage!.abandon({ + await receiver.abandonMessage(deferredMessage, { customProperty: "hello, setting this custom property" }); @@ -269,7 +265,7 @@ describe("abandoning", () => { it("abandoning a typical received message - sessions", async () => { await beforeEachTest(TestClientType.UnpartitionedQueueWithSessions); - await receivedMessage.abandon({ + await receiver.abandonMessage(receivedMessage, { customProperty: "hello, setting this custom property" }); @@ -280,7 +276,7 @@ describe("abandoning", () => { }); async function checkAbandonedMessage( - abandonedMessage: ServiceBusReceivedMessageWithLock, + abandonedMessage: ServiceBusReceivedMessage, expected: { customProperty?: string } ) { should.exist(abandonedMessage); @@ -293,8 +289,8 @@ describe("abandoning", () => { describe("deferring", () => { let serviceBusClient: ReturnType; - let receiver: ServiceBusReceiver; - let receivedMessage: ServiceBusReceivedMessageWithLock; + let receiver: ServiceBusReceiver; + let receivedMessage: ServiceBusReceivedMessage; before(() => { serviceBusClient = createServiceBusClientForTests(); @@ -339,13 +335,13 @@ describe("deferring", () => { it("deferring a deferred message", async () => { await beforeEachTest(TestClientType.UnpartitionedQueue); // defer this message so we can pick it up via the management API - await receivedMessage.defer(); + await receiver.deferMessage(receivedMessage); const [deferredMessage] = await receiver.receiveDeferredMessages( receivedMessage.sequenceNumber! ); - await deferredMessage!.defer({ + await receiver.deferMessage(deferredMessage!, { customProperty: "hello, setting this custom property" }); @@ -356,7 +352,7 @@ describe("deferring", () => { it("deferring a typical received message", async () => { await beforeEachTest(TestClientType.UnpartitionedQueue); - await receivedMessage.defer({ + await receiver.deferMessage(receivedMessage, { customProperty: "hello, setting this custom property" }); @@ -368,13 +364,13 @@ describe("deferring", () => { it("deferring a deferred message - sessions", async () => { await beforeEachTest(TestClientType.UnpartitionedQueueWithSessions); // defer this message so we can pick it up via the management API - await receivedMessage.defer(); + await receiver.deferMessage(receivedMessage); const [deferredMessage] = await receiver.receiveDeferredMessages( receivedMessage.sequenceNumber! ); - await deferredMessage!.defer({ + await receiver.deferMessage(deferredMessage, { customProperty: "hello, setting this custom property" }); @@ -385,7 +381,7 @@ describe("deferring", () => { it("deferring a typical received message - sessions", async () => { await beforeEachTest(TestClientType.UnpartitionedQueueWithSessions); - await receivedMessage.defer({ + await receiver.deferMessage(receivedMessage, { customProperty: "hello, setting this custom property" }); diff --git a/sdk/servicebus/service-bus/test/receiveAndDeleteMode.spec.ts b/sdk/servicebus/service-bus/test/receiveAndDeleteMode.spec.ts index b69c4adcf330..173688ecc154 100644 --- a/sdk/servicebus/service-bus/test/receiveAndDeleteMode.spec.ts +++ b/sdk/servicebus/service-bus/test/receiveAndDeleteMode.spec.ts @@ -20,7 +20,7 @@ import { getRandomTestClientTypeWithSessions, getRandomTestClientTypeWithNoSessions } from "./utils/testutils2"; -import { DispositionType, ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; +import { DispositionType } from "../src/serviceBusMessage"; let errorWasThrown: boolean; const noSessionTestClientType = getRandomTestClientTypeWithNoSessions(); @@ -28,7 +28,7 @@ const withSessionTestClientType = getRandomTestClientTypeWithSessions(); describe("receive and delete", () => { let sender: ServiceBusSender; - let receiver: ServiceBusReceiver; + let receiver: ServiceBusReceiver; let serviceBusClient: ServiceBusClientForTests; let entityName: EntityName; @@ -243,17 +243,17 @@ describe("receive and delete", () => { : TestMessage.getSample(); // we have to force this cast - the type system doesn't allow this if you've chosen receiveAndDelete // as your lock mode. - const msg = (await sendReceiveMsg(testMessages)) as ServiceBusReceivedMessageWithLock; + const msg = (await sendReceiveMsg(testMessages)) as ServiceBusReceivedMessage; try { if (operation === DispositionType.complete) { - await msg.complete(); + await receiver.completeMessage(msg); } else if (operation === DispositionType.abandon) { - await msg.abandon(); + await receiver.abandonMessage(msg); } else if (operation === DispositionType.deadletter) { - await msg.deadLetter(); + await receiver.deadLetterMessage(msg); } else if (operation === DispositionType.defer) { - await msg.defer(); + await receiver.deferMessage(msg); } } catch (err) { errorWasThrown = true; @@ -309,7 +309,7 @@ describe("receive and delete", () => { const msg = await sendReceiveMsg(TestMessage.getSample()); // have to cast it - the type system doesn't allow us to call into this method otherwise. - await (msg as ServiceBusReceivedMessageWithLock).renewLock().catch((err) => { + await receiver.renewMessageLock(msg).catch((err) => { should.equal( err.message, getErrorMessageNotSupportedInReceiveAndDeleteMode("renew the lock on the message"), @@ -354,7 +354,7 @@ describe("receive and delete", () => { ); should.equal(msgs[0].deliveryCount, 0, "DeliveryCount is different than expected"); - await (msgs[0] as ServiceBusReceivedMessageWithLock).defer(); + await receiver.deferMessage(msgs[0]); return msgs[0].sequenceNumber!; } @@ -431,7 +431,7 @@ describe("receive and delete", () => { // receive and defer the message const [msg] = await receiver.receiveMessages(1); - await (msg as ServiceBusReceivedMessageWithLock).defer(); + await receiver.deferMessage(msg); const sequenceNumber = msg.sequenceNumber!; await receiver.close(); @@ -458,17 +458,17 @@ describe("receive and delete", () => { const deferredMsg = await testDeferredMessage(testClienttype); // we have to force this cast - the type system doesn't allow this if you've chosen receiveAndDelete // as your lock mode. - const msg = deferredMsg as ServiceBusReceivedMessageWithLock; + const msg = deferredMsg as ServiceBusReceivedMessage; try { if (operation === DispositionType.complete) { - await msg.complete(); + await receiver.completeMessage(msg); } else if (operation === DispositionType.abandon) { - await msg.abandon(); + await receiver.abandonMessage(msg); } else if (operation === DispositionType.deadletter) { - await msg.deadLetter(); + await receiver.deadLetterMessage(msg); } else if (operation === DispositionType.defer) { - await msg.defer(); + await receiver.deferMessage(msg); } } catch (err) { errorWasThrown = true; @@ -516,7 +516,7 @@ describe("receive and delete", () => { // as your lock mode. // have to cast it - the type system doesn't allow us to call into this method otherwise. - await (deferredMsg as ServiceBusReceivedMessageWithLock).renewLock().catch((err) => { + await receiver.renewMessageLock(deferredMsg).catch((err) => { should.equal( err.message, getErrorMessageNotSupportedInReceiveAndDeleteMode("renew the lock on the message"), diff --git a/sdk/servicebus/service-bus/test/renewLock.spec.ts b/sdk/servicebus/service-bus/test/renewLock.spec.ts index cbcd79ae517b..afd4c7119ff9 100644 --- a/sdk/servicebus/service-bus/test/renewLock.spec.ts +++ b/sdk/servicebus/service-bus/test/renewLock.spec.ts @@ -15,7 +15,7 @@ import { } from "./utils/testutils2"; import { ServiceBusReceiver } from "../src/receivers/receiver"; import { ServiceBusSender } from "../src/sender"; -import { ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; +import { ServiceBusReceivedMessage } from "../src/serviceBusMessage"; describe("Message Lock Renewal", () => { let serviceBusClient: ServiceBusClientForTests; @@ -164,7 +164,7 @@ describe("Message Lock Renewal", () => { await delay(5000); if (msgs[0].lockToken) { - await msgs[0].renewLock(); + await receiver.renewMessageLock(msgs[0]); } // Compute expected lock expiry time after renewing lock after 5 seconds @@ -177,7 +177,7 @@ describe("Message Lock Renewal", () => { "After renewlock()" ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); } /** @@ -205,7 +205,7 @@ describe("Message Lock Renewal", () => { await delay(lockDurationInMilliseconds + 1000); let errorWasThrown: boolean = false; - await msgs[0].complete().catch((err) => { + await receiver.completeMessage(msgs[0]).catch((err) => { should.equal(err.code, "MessageLockLostError", "Error code is different than expected"); errorWasThrown = true; }); @@ -214,7 +214,7 @@ describe("Message Lock Renewal", () => { // Clean up any left over messages const unprocessedMsgsBatch = await receiver.receiveMessages(1); - await unprocessedMsgsBatch[0].complete(); + await receiver.completeMessage(unprocessedMsgsBatch[0]); } /** @@ -231,9 +231,7 @@ describe("Message Lock Renewal", () => { const testMessage = TestMessage.getSample(); await sender.sendMessages(testMessage); - async function processMessage( - brokeredMessage: ServiceBusReceivedMessageWithLock - ): Promise { + async function processMessage(brokeredMessage: ServiceBusReceivedMessage): Promise { if (numOfMessagesReceived < 1) { numOfMessagesReceived++; @@ -262,7 +260,7 @@ describe("Message Lock Renewal", () => { ); await delay(5000); - await brokeredMessage.renewLock(); + await receiver.renewMessageLock(brokeredMessage); // Compute expected lock expiry time after renewing lock after 5 seconds expectedLockExpiryTimeUtc.setSeconds(expectedLockExpiryTimeUtc.getSeconds() + 5); @@ -274,7 +272,7 @@ describe("Message Lock Renewal", () => { "After renewlock" ); - await brokeredMessage.complete(); + await receiver.completeMessage(brokeredMessage); } } @@ -330,7 +328,7 @@ describe("Message Lock Renewal", () => { await delay(options.delayBeforeAttemptingToCompleteMessageInSeconds * 1000); try { - await actualMessage.complete(); + await receiver.completeMessage(actualMessage); if (options.willCompleteFail) { should.fail("complete() should throw an error"); @@ -355,9 +353,9 @@ describe("Message Lock Renewal", () => { } async function receiveSingleMessageUsingSpecificReceiveMethod( - receiver: ServiceBusReceiver, + receiver: ServiceBusReceiver, type: "subscribe" | "receive" | "iterator" - ): Promise { + ): Promise { switch (type) { case "subscribe": { return await new Promise((resolve, reject) => { diff --git a/sdk/servicebus/service-bus/test/renewLockSessions.spec.ts b/sdk/servicebus/service-bus/test/renewLockSessions.spec.ts index 4ff29be85979..92ce38c4b035 100644 --- a/sdk/servicebus/service-bus/test/renewLockSessions.spec.ts +++ b/sdk/servicebus/service-bus/test/renewLockSessions.spec.ts @@ -14,11 +14,11 @@ import { } from "./utils/testutils2"; import { ServiceBusSender } from "../src/sender"; import { ServiceBusSessionReceiver } from "../src/receivers/sessionReceiver"; -import { ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; +import { ServiceBusReceivedMessage } from "../src/serviceBusMessage"; describe("Session Lock Renewal", () => { let sender: ServiceBusSender; - let receiver: ServiceBusSessionReceiver; + let receiver: ServiceBusSessionReceiver; let sessionId: string; let serviceBusClient: ServiceBusClientForTests; @@ -133,7 +133,7 @@ describe("Session Lock Renewal", () => { */ async function testBatchReceiverManualLockRenewalHappyCase( sender: ServiceBusSender, - receiver: ServiceBusSessionReceiver + receiver: ServiceBusSessionReceiver ): Promise { const testMessage = getTestMessage(); testMessage.body = `testBatchReceiverManualLockRenewalHappyCase-${Date.now().toString()}`; @@ -172,7 +172,7 @@ describe("Session Lock Renewal", () => { "After renewlock()" ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); } /** @@ -181,7 +181,7 @@ describe("Session Lock Renewal", () => { async function testBatchReceiverManualLockRenewalErrorOnLockExpiry( entityType: TestClientType, sender: ServiceBusSender, - receiver: ServiceBusSessionReceiver + receiver: ServiceBusSessionReceiver ): Promise { const testMessage = getTestMessage(); testMessage.body = `testBatchReceiverManualLockRenewalErrorOnLockExpiry-${Date.now().toString()}`; @@ -197,7 +197,7 @@ describe("Session Lock Renewal", () => { await delay(lockDurationInMilliseconds + 1000); let errorWasThrown: boolean = false; - await msgs[0].complete().catch((err) => { + await receiver.completeMessage(msgs[0]).catch((err) => { should.equal(err.code, "SessionLockLostError", "Error code is different than expected"); errorWasThrown = true; }); @@ -212,7 +212,7 @@ describe("Session Lock Renewal", () => { const unprocessedMsgsBatch = await receiver.receiveMessages(1); should.equal(unprocessedMsgsBatch[0].deliveryCount, 1, "Unexpected deliveryCount"); - await unprocessedMsgsBatch[0].complete(); + await receiver.completeMessage(unprocessedMsgsBatch[0]); } /** @@ -220,14 +220,14 @@ describe("Session Lock Renewal", () => { */ async function testStreamingReceiverManualLockRenewalHappyCase( sender: ServiceBusSender, - receiver: ServiceBusSessionReceiver + receiver: ServiceBusSessionReceiver ): Promise { let numOfMessagesReceived = 0; const testMessage = getTestMessage(); testMessage.body = `testStreamingReceiverManualLockRenewalHappyCase-${Date.now().toString()}`; await sender.sendMessages(testMessage); - async function processMessage(brokeredMessage: ServiceBusReceivedMessageWithLock) { + async function processMessage(brokeredMessage: ServiceBusReceivedMessage) { if (numOfMessagesReceived < 1) { numOfMessagesReceived++; @@ -268,7 +268,7 @@ describe("Session Lock Renewal", () => { "After renewlock()" ); - await brokeredMessage.complete(); + await receiver.completeMessage(brokeredMessage); } } @@ -296,7 +296,7 @@ describe("Session Lock Renewal", () => { async function testAutoLockRenewalConfigBehavior( sender: ServiceBusSender, - receiver: ServiceBusSessionReceiver, + receiver: ServiceBusSessionReceiver, options: AutoLockRenewalTestOptions ): Promise { let numOfMessagesReceived = 0; @@ -305,11 +305,9 @@ describe("Session Lock Renewal", () => { await sender.sendMessages(testMessage); let sessionLockLostErrorThrown = false; - const messagesReceived: ServiceBusReceivedMessageWithLock[] = []; + const messagesReceived: ServiceBusReceivedMessage[] = []; - async function processMessage( - brokeredMessage: ServiceBusReceivedMessageWithLock - ): Promise { + async function processMessage(brokeredMessage: ServiceBusReceivedMessage): Promise { if (numOfMessagesReceived < 1) { numOfMessagesReceived++; @@ -359,7 +357,7 @@ describe("Session Lock Renewal", () => { should.equal(messagesReceived.length, 1, "Mismatch in number of messages received"); let errorWasThrown: boolean = false; - await messagesReceived[0].complete().catch((err) => { + await receiver.completeMessage(messagesReceived[0]).catch((err) => { should.equal(err.code, "SessionLockLostError", "Error code is different than expected"); errorWasThrown = true; }); diff --git a/sdk/servicebus/service-bus/test/retries.spec.ts b/sdk/servicebus/service-bus/test/retries.spec.ts index 8c10ed7fb903..0ef11180eb06 100644 --- a/sdk/servicebus/service-bus/test/retries.spec.ts +++ b/sdk/servicebus/service-bus/test/retries.spec.ts @@ -5,7 +5,6 @@ import chai from "chai"; import chaiAsPromised from "chai-as-promised"; chai.use(chaiAsPromised); const should = chai.should(); -import { ServiceBusReceivedMessageWithLock } from "../src"; import { TestClientType, TestMessage } from "./utils/testUtils"; import { ServiceBusClientForTests, createServiceBusClientForTests } from "./utils/testutils2"; import { ServiceBusSender, ServiceBusSenderImpl } from "../src/sender"; @@ -21,9 +20,7 @@ import { InternalMessageHandlers } from "../src/models"; describe("Retries - ManagementClient", () => { let sender: ServiceBusSender; - let receiver: - | ServiceBusReceiver - | ServiceBusSessionReceiver; + let receiver: ServiceBusReceiver | ServiceBusSessionReceiver; let serviceBusClient: ServiceBusClientForTests; const defaultMaxRetries = 2; let numberOfTimesManagementClientInvoked: number; @@ -144,11 +141,11 @@ describe("Retries - ManagementClient", () => { }); describe("Session Receiver Retries", () => { - let sessionReceiver: ServiceBusSessionReceiver; + let sessionReceiver: ServiceBusSessionReceiver; beforeEach(async () => { numberOfTimesManagementClientInvoked = 0; await beforeEachTest(TestClientType.UnpartitionedQueueWithSessions); - sessionReceiver = receiver as ServiceBusSessionReceiver; + sessionReceiver = receiver as ServiceBusSessionReceiver; }); afterEach(async () => { await afterEachTest(); @@ -309,7 +306,7 @@ describe("Retries - MessageSender", () => { }); describe("Retries - Receive methods", () => { - let receiver: ServiceBusReceiver; + let receiver: ServiceBusReceiver; let serviceBusClient: ServiceBusClientForTests; const defaultMaxRetries = 2; let numberOfTimesTried: number; @@ -346,9 +343,7 @@ describe("Retries - Receive methods", () => { if (receiver instanceof ServiceBusSessionReceiverImpl) { // Mocking `_messageSession.receiveMessages()` to throw the error and fail - (receiver as ServiceBusSessionReceiverImpl)[ - "_messageSession" - ].receiveMessages = fakeFunction; + (receiver as ServiceBusSessionReceiverImpl)["_messageSession"].receiveMessages = fakeFunction; } else { // Mocking batchingReceiver.receive to throw the error and fail const batchingReceiver = BatchingReceiver.create( @@ -361,9 +356,7 @@ describe("Retries - Receive methods", () => { ); batchingReceiver.isOpen = () => true; batchingReceiver.receive = fakeFunction; - (receiver as ServiceBusReceiverImpl)[ - "_batchingReceiver" - ] = batchingReceiver; + (receiver as ServiceBusReceiverImpl)["_batchingReceiver"] = batchingReceiver; } } @@ -419,9 +412,7 @@ describe("Retries - Receive methods", () => { describe("Retries - onDetached", () => { let sender: ServiceBusSender; - let receiver: - | ServiceBusReceiver - | ServiceBusSessionReceiver; + let receiver: ServiceBusReceiver | ServiceBusSessionReceiver; let serviceBusClient: ServiceBusClientForTests; const defaultMaxRetries = 2; let numberOfTimesOnDetachedInvoked: number; @@ -490,12 +481,12 @@ describe("Retries - onDetached", () => { async processError(err) { reject(err); } - } as InternalMessageHandlers); + } as InternalMessageHandlers); }); await subscribeInitializedPromise; - const streamingReceiver = (receiver as ServiceBusReceiverImpl)["_streamingReceiver"]!; + const streamingReceiver = (receiver as ServiceBusReceiverImpl)["_streamingReceiver"]!; should.exist(streamingReceiver); streamingReceiver["init"] = fakeFunction; diff --git a/sdk/servicebus/service-bus/test/sendAndSchedule.spec.ts b/sdk/servicebus/service-bus/test/sendAndSchedule.spec.ts index 765221ffd9f6..f7ccca57d1e6 100644 --- a/sdk/servicebus/service-bus/test/sendAndSchedule.spec.ts +++ b/sdk/servicebus/service-bus/test/sendAndSchedule.spec.ts @@ -19,7 +19,6 @@ import { getRandomTestClientType } from "./utils/testutils2"; import { ServiceBusSender } from "../src/sender"; -import { ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; import { AbortController } from "@azure/abort-controller"; import { SpanGraph, TestSpan } from "@azure/core-tracing"; import { setTracerForTest } from "./utils/misc"; @@ -31,7 +30,7 @@ const anyRandomTestClientType = getRandomTestClientType(); describe("Sender Tests", () => { let sender: ServiceBusSender; - let receiver: ServiceBusReceiver; + let receiver: ServiceBusReceiver; let serviceBusClient: ServiceBusClientForTests; let entityName: EntityName; @@ -75,7 +74,7 @@ describe("Sender Tests", () => { entityName.isPartitioned ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); await testPeekMsgsLength(receiver, 0); } @@ -133,8 +132,8 @@ describe("Sender Tests", () => { ); } - await msgs[0].complete(); - await msgs[1].complete(); + await receiver.completeMessage(msgs[0]); + await receiver.completeMessage(msgs[1]); await testPeekMsgsLength(receiver, 0); } @@ -170,7 +169,7 @@ describe("Sender Tests", () => { should.equal(msgs[0].body, testMessage.body, "MessageBody is different than expected"); should.equal(msgs[0].messageId, testMessage.messageId, "MessageId is different than expected"); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); await testPeekMsgsLength(receiver, 0); } @@ -211,8 +210,8 @@ describe("Sender Tests", () => { "MessageId of second message is different than expected" ); - await msgs[0].complete(); - await msgs[1].complete(); + await receiver.completeMessage(msgs[0]); + await receiver.completeMessage(msgs[1]); await testPeekMsgsLength(receiver, 0); } @@ -326,14 +325,14 @@ describe("Sender Tests", () => { messages[sequenceNumbers.indexOf(seqNum)].body, "Message body did not match though the sequence numbers matched!" ); - await msgWithSeqNum?.complete(); + await receiver.completeMessage(msgWithSeqNum!); } await testPeekMsgsLength(receiver, 0); }); async function testReceivedMsgsLength( - receiver: ServiceBusReceiver, + receiver: ServiceBusReceiver, expectedReceivedMsgsLength: number ): Promise { const receivedMsgs = await receiver.receiveMessages(expectedReceivedMsgsLength + 1, { diff --git a/sdk/servicebus/service-bus/test/serviceBusClient.spec.ts b/sdk/servicebus/service-bus/test/serviceBusClient.spec.ts index 5b9a9d559200..fd241c8af92c 100644 --- a/sdk/servicebus/service-bus/test/serviceBusClient.spec.ts +++ b/sdk/servicebus/service-bus/test/serviceBusClient.spec.ts @@ -8,7 +8,7 @@ import * as dotenv from "dotenv"; import Long from "long"; import { MessagingError, ServiceBusClient, ServiceBusSessionReceiver } from "../src"; import { ServiceBusSender } from "../src/sender"; -import { DispositionType, ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; +import { DispositionType, ServiceBusReceivedMessage } from "../src/serviceBusMessage"; import { getReceiverClosedErrorMsg, getSenderClosedErrorMsg } from "../src/util/errors"; import { EnvVarNames, getEnvVars, isNode } from "../test/utils/envVarUtils"; import { checkWithTimeout, isMessagingError, TestClientType, TestMessage } from "./utils/testUtils"; @@ -80,7 +80,7 @@ describe("Random scheme in the endpoint from connection string", function(): voi should.equal(msgs[0].body, testMessages.body, "MessageBody is different than expected"); should.equal(msgs[0].messageId, testMessages.messageId, "MessageId is different than expected"); should.equal(msgs[0].deliveryCount, 0, "DeliveryCount is different than expected"); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); await testPeekMsgsLength(receiver, 0); @@ -359,8 +359,8 @@ describe("Test ServiceBusClient with TokenCredentials", function(): void { describe("Errors after close()", function(): void { let sbClient: ServiceBusClientForTests; let sender: ServiceBusSender; - let receiver: ServiceBusReceiver; - let receivedMessage: ServiceBusReceivedMessageWithLock; + let receiver: ServiceBusReceiver; + let receivedMessage: ServiceBusReceivedMessage; let entityName: EntityName; afterEach(async () => { @@ -419,16 +419,16 @@ describe("Errors after close()", function(): void { try { switch (operation) { case DispositionType.complete: - await receivedMessage.complete(); + await receiver.completeMessage(receivedMessage); break; case DispositionType.abandon: - await receivedMessage.abandon(); + await receiver.abandonMessage(receivedMessage); break; case DispositionType.defer: - await receivedMessage.defer(); + await receiver.deferMessage(receivedMessage); break; case DispositionType.deadletter: - await receivedMessage.deadLetter(); + await receiver.deadLetterMessage(receivedMessage); break; default: @@ -579,9 +579,7 @@ describe("Errors after close()", function(): void { */ async function testSessionReceiver(expectedErrorMsg: string): Promise { await testReceiver(expectedErrorMsg); - const sessionReceiver = receiver as ServiceBusSessionReceiver< - ServiceBusReceivedMessageWithLock - >; + const sessionReceiver = receiver as ServiceBusSessionReceiver; let errorPeek: string = ""; await sessionReceiver.peekMessages(1).catch((err) => { diff --git a/sdk/servicebus/service-bus/test/sessionsRequiredCleanEntityTests.spec.ts b/sdk/servicebus/service-bus/test/sessionsRequiredCleanEntityTests.spec.ts index fc276673e19b..a2c8c6160aa1 100644 --- a/sdk/servicebus/service-bus/test/sessionsRequiredCleanEntityTests.spec.ts +++ b/sdk/servicebus/service-bus/test/sessionsRequiredCleanEntityTests.spec.ts @@ -11,7 +11,6 @@ import { import { ServiceBusSender } from "../src/sender"; import { ServiceBusMessage, ServiceBusSessionReceiver } from "../src"; import { TestMessage } from "./utils/testUtils"; -import { ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; const should = chai.should(); // NOTE: these tests should be reworked, if possible. Since they need to be deterministic @@ -23,7 +22,7 @@ const should = chai.should(); describe("sessions tests - requires completely clean entity for each test", () => { let serviceBusClient: ServiceBusClientForTests; let sender: ServiceBusSender; - let receiver: ServiceBusSessionReceiver; + let receiver: ServiceBusSessionReceiver; const testClientType = getRandomTestClientTypeWithSessions(); @@ -113,7 +112,7 @@ describe("sessions tests - requires completely clean entity for each test", () "SessionId is different than expected" ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); } it(testClientType + " - Peek Session with sessionId", async function(): Promise { @@ -166,7 +165,7 @@ describe("sessions tests - requires completely clean entity for each test", () true, "Received Message doesnt match any of the test messages" ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); await receiver.close(); // get the next available session ID rather than specifying one @@ -186,7 +185,7 @@ describe("sessions tests - requires completely clean entity for each test", () true, "Received Message doesnt match any of the test messages" ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); await testPeekMsgsLength(receiver, 0); } @@ -239,7 +238,7 @@ describe("sessions tests - requires completely clean entity for each test", () true, "Received Message doesnt match expected test message" ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); const peekedMsgsInSession = await receiver.peekMessages(1); should.equal(peekedMsgsInSession.length, 0, "Unexpected number of messages peeked"); diff --git a/sdk/servicebus/service-bus/test/sessionsTests.spec.ts b/sdk/servicebus/service-bus/test/sessionsTests.spec.ts index 2a9f7bda1749..c62b248ee03d 100644 --- a/sdk/servicebus/service-bus/test/sessionsTests.spec.ts +++ b/sdk/servicebus/service-bus/test/sessionsTests.spec.ts @@ -18,7 +18,6 @@ import { testPeekMsgsLength, getRandomTestClientTypeWithSessions } from "./utils/testutils2"; -import { ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; import { AbortController } from "@azure/abort-controller"; let unexpectedError: Error | undefined; @@ -32,7 +31,7 @@ async function processError(err: Error): Promise { describe("session tests", () => { let serviceBusClient: ServiceBusClientForTests; let sender: ServiceBusSender; - let receiver: ServiceBusSessionReceiver; + let receiver: ServiceBusSessionReceiver; const testClientType = getRandomTestClientTypeWithSessions(); async function beforeEachTest(sessionId?: string): Promise { @@ -151,7 +150,7 @@ describe("session tests", () => { testMessage.messageId, "MessageId is different than expected" ); - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); await testPeekMsgsLength(receiver, 0); }); @@ -183,14 +182,14 @@ describe("session tests", () => { receivedMsgs = []; receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { should.equal(msg.body, testMessage.body, "MessageBody is different than expected"); should.equal( msg.messageId, testMessage.messageId, "MessageId is different than expected" ); - await msg.complete(); + await receiver.completeMessage(msg); receivedMsgs.push(msg); }, processError @@ -259,7 +258,7 @@ describe("session tests", () => { should.equal(testState, "new_state", "SessionState is different than expected"); await receiver.setSessionState(""); // clearing the session-state - await msgs[0].complete(); + await receiver.completeMessage(msgs[0]); await testPeekMsgsLength(receiver, 0); }); @@ -368,7 +367,7 @@ describe.skip("SessionReceiver - disconnects", function(): void { console.log(`Received a message`); messageHandlerCount++; try { - await message.complete(); + await receiver.completeMessage(message); settledMessageCount++; } catch (err) { receivedErrors.push(err); diff --git a/sdk/servicebus/service-bus/test/smoketest.spec.ts b/sdk/servicebus/service-bus/test/smoketest.spec.ts index 0022e403ac9c..c27fd8c83b7f 100644 --- a/sdk/servicebus/service-bus/test/smoketest.spec.ts +++ b/sdk/servicebus/service-bus/test/smoketest.spec.ts @@ -8,7 +8,6 @@ import chaiAsPromised from "chai-as-promised"; import { getEntityNameFromConnectionString } from "../src/constructorHelpers"; import { ServiceBusClientForTests, createServiceBusClientForTests } from "./utils/testutils2"; import { ServiceBusSender } from "../src/sender"; -import { ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; chai.use(chaiAsPromised); const assert = chai.assert; @@ -53,8 +52,8 @@ describe("Sample scenarios for track 2", () => { const receivedBodies: string[] = []; receiver.subscribe({ - async processMessage(message: ServiceBusReceivedMessageWithLock): Promise { - await message.complete(); + async processMessage(message: ServiceBusReceivedMessage): Promise { + await receiver.completeMessage(message); receivedBodies.push(message.body); }, async processError(err: Error): Promise { @@ -103,11 +102,11 @@ describe("Sample scenarios for track 2", () => { } try { - await message.complete(); + await receiver.completeMessage(message); receivedBodies.push(message.body); break; } catch (err) { - await message.abandon(); + await receiver.abandonMessage(message); throw err; } } @@ -208,8 +207,8 @@ describe("Sample scenarios for track 2", () => { const receivedBodies: string[] = []; receiver.subscribe({ - async processMessage(message: ServiceBusReceivedMessageWithLock): Promise { - await message.complete(); + async processMessage(message: ServiceBusReceivedMessage): Promise { + await receiver.completeMessage(message); receivedBodies.push(message.body); }, async processError(err: Error): Promise { @@ -265,11 +264,11 @@ describe("Sample scenarios for track 2", () => { } try { - await message.complete(); + await receiver.completeMessage(message); receivedBodies.push(message.body); break; } catch (err) { - await message.abandon(); + await receiver.abandonMessage(message); throw err; } } @@ -416,7 +415,7 @@ describe("Sample scenarios for track 2", () => { for await (const message of receiver.getMessageIterator()) { receivedBodies.push(message.body); - await message.complete(); + await receiver.completeMessage(message); break; } @@ -474,7 +473,7 @@ async function waitAndValidate( expectedMessage: string, receivedBodies: string[], errors: string[], - receiver: ServiceBusReceiver + receiver: ServiceBusReceiver ): Promise { const maxChecks = 20; let numChecks = 0; diff --git a/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts b/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts index 1bac3a7e4a2a..ceda5abeffa5 100644 --- a/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts +++ b/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts @@ -8,11 +8,7 @@ import { getAlreadyReceivingErrorMsg } from "../src/util/errors"; import { TestMessage, checkWithTimeout, TestClientType } from "./utils/testUtils"; import { StreamingReceiver } from "../src/core/streamingReceiver"; -import { - DispositionType, - ServiceBusReceivedMessageWithLock, - ServiceBusMessageImpl -} from "../src/serviceBusMessage"; +import { DispositionType, ServiceBusMessageImpl } from "../src/serviceBusMessage"; import { ServiceBusReceiver } from "../src/receivers/receiver"; import { ServiceBusSender } from "../src/sender"; import { @@ -44,10 +40,8 @@ async function processError(err: Error): Promise { describe("Streaming Receiver Tests", () => { let serviceBusClient: ServiceBusClientForTests; let sender: ServiceBusSender; - let receiver: - | ServiceBusReceiver - | ServiceBusReceiver; - let deadLetterReceiver: ServiceBusReceiver; + let receiver: ServiceBusReceiver; + let deadLetterReceiver: ServiceBusReceiver; let entityNames: EntityName; before(() => { @@ -130,10 +124,10 @@ describe("Streaming Receiver Tests", () => { const testMessage = TestMessage.getSample(); await sender.sendMessages(testMessage); - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { receivedMsgs.push(msg); should.equal(msg.body, testMessage.body, "MessageBody is different than expected"); should.equal( @@ -154,7 +148,7 @@ describe("Streaming Receiver Tests", () => { await testPeekMsgsLength(receiver, 1); should.equal(receivedMsgs.length, 1, "Unexpected number of messages"); - await receivedMsgs[0].complete(); + await receiver.completeMessage(receivedMsgs[0]); should.equal(unexpectedError, undefined, unexpectedError && unexpectedError.message); await testPeekMsgsLength(receiver, 0); @@ -271,17 +265,17 @@ describe("Streaming Receiver Tests", () => { const testMessage = TestMessage.getSample(); await sender.sendMessages(testMessage); - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { should.equal(msg.body, testMessage.body, "MessageBody is different than expected"); should.equal( msg.messageId, testMessage.messageId, "MessageId is different than expected" ); - await msg.complete(); + await receiver.completeMessage(msg); receivedMsgs.push(msg); }, processError @@ -322,13 +316,13 @@ describe("Streaming Receiver Tests", () => { receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { should.equal( msg.deliveryCount, checkDeliveryCount, "DeliveryCount is different than expected" ); - await msg.abandon(); + await receiver.abandonMessage(msg); checkDeliveryCount++; }, processError @@ -359,7 +353,7 @@ describe("Streaming Receiver Tests", () => { "MessageId is different than expected" ); - await deadLetterMsgs[0].complete(); + await receiver.completeMessage(deadLetterMsgs[0]); await testPeekMsgsLength(deadLetterReceiver, 0); }); @@ -381,8 +375,8 @@ describe("Streaming Receiver Tests", () => { receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { - await msg.defer(); + async processMessage(msg: ServiceBusReceivedMessage) { + await receiver.deferMessage(msg); sequenceNum = msg.sequenceNumber; }, processError @@ -414,7 +408,7 @@ describe("Streaming Receiver Tests", () => { ); should.equal(deferredMsgs[0].deliveryCount, 1, "DeliveryCount is different than expected"); - await (deferredMsgs[0] as ServiceBusReceivedMessageWithLock).complete(); + await receiver.completeMessage(deferredMsgs[0] as ServiceBusReceivedMessage); await testPeekMsgsLength(receiver, 0); } @@ -446,8 +440,8 @@ describe("Streaming Receiver Tests", () => { receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { - await msg.deadLetter(); + async processMessage(msg: ServiceBusReceivedMessage) { + await receiver.deadLetterMessage(msg); receivedMsgs.push(msg); }, processError @@ -471,7 +465,7 @@ describe("Streaming Receiver Tests", () => { "MessageId is different than expected" ); - await deadLetterMsgs[0].complete(); + await receiver.completeMessage(deadLetterMsgs[0]); await testPeekMsgsLength(deadLetterReceiver, 0); } @@ -496,8 +490,8 @@ describe("Streaming Receiver Tests", () => { const expectedErrorMessage = getAlreadyReceivingErrorMsg(receiver.entityPath); receiver.subscribe({ - async processMessage(msg: ServiceBusReceivedMessageWithLock) { - await msg.complete(); + async processMessage(msg: ServiceBusReceivedMessage) { + await receiver.completeMessage(msg); }, processError }); @@ -561,9 +555,9 @@ describe("Streaming Receiver Tests", () => { async function testSettlement(operation: DispositionType): Promise { const testMessage = TestMessage.getSample(); await sender.sendMessages(testMessage); - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe({ - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { receivedMsgs.push(msg); return Promise.resolve(); }, @@ -599,13 +593,13 @@ describe("Streaming Receiver Tests", () => { await testPeekMsgsLength(receiver, 0); if (operation === DispositionType.complete) { - await receivedMsgs[0].complete().catch((err) => testError(err, operation)); + await receiver.completeMessage(receivedMsgs[0]).catch((err) => testError(err, operation)); } else if (operation === DispositionType.abandon) { - await receivedMsgs[0].abandon().catch((err) => testError(err, operation)); + await receiver.abandonMessage(receivedMsgs[0]).catch((err) => testError(err, operation)); } else if (operation === DispositionType.deadletter) { - await receivedMsgs[0].deadLetter().catch((err) => testError(err, operation)); + await receiver.deadLetterMessage(receivedMsgs[0]).catch((err) => testError(err, operation)); } else if (operation === DispositionType.defer) { - await receivedMsgs[0].defer().catch((err) => testError(err, operation)); + await receiver.deferMessage(receivedMsgs[0]).catch((err) => testError(err, operation)); } should.equal(errorWasThrown, true, "Error thrown flag must be true"); @@ -637,11 +631,11 @@ describe("Streaming Receiver Tests", () => { await sender.sendMessages(TestMessage.getSample()); const errorMessage = "Will we see this error message?"; let streamingReceiverName: string | undefined; - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe({ - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { streamingReceiverName = (receiver as any)._streamingReceiver.name; - await msg.complete(); + await receiver.completeMessage(msg); receivedMsgs.push(msg); throw new Error(errorMessage); }, @@ -772,7 +766,7 @@ describe("Streaming Receiver Tests", () => { receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { if (receivedMsgs.length === 1) { if ((!maxConcurrentCalls || maxConcurrentCalls === 1) && settledMsgs.length === 0) { throw new Error( @@ -789,7 +783,7 @@ describe("Streaming Receiver Tests", () => { receivedMsgs.push(msg); await delay(2000); - await msg.complete(); + await receiver.completeMessage(msg); settledMsgs.push(msg); }, processError @@ -834,13 +828,13 @@ describe("Streaming Receiver Tests", () => { } await sender.sendMessages(batch); - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe( { - async processMessage(brokeredMessage: ServiceBusReceivedMessageWithLock) { + async processMessage(brokeredMessage: ServiceBusReceivedMessage) { receivedMsgs.push(brokeredMessage); - await brokeredMessage.complete(); + await receiver.completeMessage(brokeredMessage); }, processError }, @@ -904,7 +898,7 @@ describe("Streaming Receiver Tests", () => { // and will still be settleable). await subscriber.close(); - await messages[0].complete(); + await receiver.completeMessage(messages[0]); messages.pop(); await sender.sendMessages({ @@ -928,9 +922,7 @@ describe("Streaming Receiver Tests", () => { describe(testClientType + ": Streaming - onDetached", function(): void { let serviceBusClient: ServiceBusClientForTests; let sender: ServiceBusSender; - let receiver: - | ServiceBusReceiver - | ServiceBusReceiver; + let receiver: ServiceBusReceiver | ServiceBusReceiver; before(() => { serviceBusClient = createServiceBusClientForTests(); @@ -1115,9 +1107,7 @@ describe(testClientType + ": Streaming - onDetached", function(): void { describe(testClientType + ": Streaming - disconnects", function(): void { let serviceBusClient: ServiceBusClientForTests; let sender: ServiceBusSender; - let receiver: - | ServiceBusReceiver - | ServiceBusReceiver; + let receiver: ServiceBusReceiver; before(() => { serviceBusClient = createServiceBusClientForTests(); @@ -1164,10 +1154,10 @@ describe(testClientType + ": Streaming - disconnects", function(): void { // Start the receiver. receiver.subscribe({ - async processMessage(message: ServiceBusReceivedMessageWithLock) { + async processMessage(message: ServiceBusReceivedMessage) { messageHandlerCount++; try { - await message.complete(); + await receiver.completeMessage(message); settledMessageCount++; } catch (err) { receivedErrors.push(err); @@ -1214,16 +1204,16 @@ describe(testClientType + ": Streaming - disconnects", function(): void { }); export function singleMessagePromise( - receiver: ServiceBusReceiver + receiver: ServiceBusReceiver ): Promise<{ - subscriber: ReturnType["subscribe"]>; - messages: ServiceBusReceivedMessageWithLock[]; + subscriber: ReturnType; + messages: ServiceBusReceivedMessage[]; }> { - const messages: ServiceBusReceivedMessageWithLock[] = []; + const messages: ServiceBusReceivedMessage[] = []; return new Promise<{ - subscriber: ReturnType["subscribe"]>; - messages: ServiceBusReceivedMessageWithLock[]; + subscriber: ReturnType; + messages: ServiceBusReceivedMessage[]; }>((resolve, reject) => { const subscriber = receiver.subscribe( { diff --git a/sdk/servicebus/service-bus/test/streamingReceiverSessions.spec.ts b/sdk/servicebus/service-bus/test/streamingReceiverSessions.spec.ts index 2513a43ec10a..f346a576d2b9 100644 --- a/sdk/servicebus/service-bus/test/streamingReceiverSessions.spec.ts +++ b/sdk/servicebus/service-bus/test/streamingReceiverSessions.spec.ts @@ -6,7 +6,7 @@ import chaiAsPromised from "chai-as-promised"; import { ServiceBusReceivedMessage, delay } from "../src"; import { getAlreadyReceivingErrorMsg } from "../src/util/errors"; import { TestClientType, TestMessage, checkWithTimeout } from "./utils/testUtils"; -import { DispositionType, ServiceBusReceivedMessageWithLock } from "../src/serviceBusMessage"; +import { DispositionType } from "../src/serviceBusMessage"; import { ServiceBusSessionReceiver, ServiceBusSessionReceiverImpl @@ -27,10 +27,8 @@ chai.use(chaiAsPromised); describe("Streaming with sessions", () => { let sender: ServiceBusSender; - let receiver: - | ServiceBusSessionReceiver - | ServiceBusSessionReceiver; - let deadLetterReceiver: ServiceBusReceiver; + let receiver: ServiceBusSessionReceiver; + let deadLetterReceiver: ServiceBusReceiver; let errorWasThrown: boolean; let unexpectedError: Error | undefined; let serviceBusClient: ServiceBusClientForTests; @@ -123,7 +121,7 @@ describe("Streaming with sessions", () => { // and will still be settleable). await subscriber.close(); - await messages[0].complete(); + await receiver.completeMessage(messages[0]); messages.pop(); await sender.sendMessages({ @@ -198,10 +196,10 @@ describe("Streaming with sessions", () => { > { const testMessage = TestMessage.getSessionSample(); await sender.sendMessages(testMessage); - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { receivedMsgs.push(msg); should.equal(msg.body, testMessage.body, "MessageBody is different than expected"); should.equal( @@ -221,7 +219,7 @@ describe("Streaming with sessions", () => { await testPeekMsgsLength(receiver, 1); - await receivedMsgs[0].complete(); + await receiver.completeMessage(receivedMsgs[0]); should.equal(unexpectedError, undefined, unexpectedError && unexpectedError.message); should.equal(receivedMsgs.length, 1, "Unexpected number of messages"); @@ -242,17 +240,17 @@ describe("Streaming with sessions", () => { const testMessage = TestMessage.getSessionSample(); await sender.sendMessages(testMessage); - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { should.equal(msg.body, testMessage.body, "MessageBody is different than expected"); should.equal( msg.messageId, testMessage.messageId, "MessageId is different than expected" ); - await msg.complete(); + await receiver.completeMessage(msg); receivedMsgs.push(msg); }, processError @@ -297,14 +295,10 @@ describe("Streaming with sessions", () => { receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { - return msg.abandon().then(() => { + async processMessage(msg: ServiceBusReceivedMessage) { + return receiver.abandonMessage(msg).then(() => { abandonFlag = 1; - if ( - (receiver as ServiceBusSessionReceiverImpl)[ - "_isReceivingMessages" - ]() - ) { + if ((receiver as ServiceBusSessionReceiverImpl)["_isReceivingMessages"]()) { return receiver.close(); } return Promise.resolve(); @@ -318,11 +312,7 @@ describe("Streaming with sessions", () => { const msgAbandonCheck = await checkWithTimeout(() => abandonFlag === 1); should.equal(msgAbandonCheck, true, "Abandoning the message results in a failure"); - if ( - (receiver as ServiceBusSessionReceiverImpl)[ - "_isReceivingMessages" - ]() - ) { + if ((receiver as ServiceBusSessionReceiverImpl)["_isReceivingMessages"]()) { await receiver.close(); } @@ -338,7 +328,7 @@ describe("Streaming with sessions", () => { "MessageId is different than expected" ); should.equal(receivedMsgs[0].deliveryCount, 1, "DeliveryCount is different than expected"); - await (receivedMsgs[0] as ServiceBusReceivedMessageWithLock).complete(); + await receiver.completeMessage(receivedMsgs[0] as ServiceBusReceivedMessage); await testPeekMsgsLength(receiver, 0); } it("abandon() retains message with incremented deliveryCount(with sessions)", async function(): Promise< @@ -370,8 +360,8 @@ describe("Streaming with sessions", () => { let sequenceNum: any = 0; receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { - await msg.defer(); + async processMessage(msg: ServiceBusReceivedMessage) { + await receiver.deferMessage(msg); sequenceNum = msg.sequenceNumber; }, processError @@ -401,7 +391,7 @@ describe("Streaming with sessions", () => { ); should.equal(deferredMsg.deliveryCount, 1, "DeliveryCount is different than expected"); - await (deferredMsg as ServiceBusReceivedMessageWithLock).complete(); + await receiver.completeMessage(deferredMsg as ServiceBusReceivedMessage); await testPeekMsgsLength(receiver, 0); } it("defer() moves message to deferred queue(with sessions)", async function(): Promise { @@ -431,8 +421,8 @@ describe("Streaming with sessions", () => { let msgCount = 0; receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { - await msg.deadLetter(); + async processMessage(msg: ServiceBusReceivedMessage) { + await receiver.deadLetterMessage(msg); msgCount++; }, processError @@ -456,7 +446,7 @@ describe("Streaming with sessions", () => { "MessageId is different than expected" ); - await deadLetterMsgs[0].complete(); + await receiver.completeMessage(deadLetterMsgs[0]); await testPeekMsgsLength(deadLetterReceiver, 0); } @@ -485,8 +475,8 @@ describe("Streaming with sessions", () => { TestMessage.sessionId ); receiver.subscribe({ - async processMessage(msg: ServiceBusReceivedMessageWithLock) { - return msg.complete(); + async processMessage(msg: ServiceBusReceivedMessage) { + return receiver.completeMessage(msg); }, processError }); @@ -555,9 +545,9 @@ describe("Streaming with sessions", () => { const testMessage = TestMessage.getSessionSample(); await sender.sendMessages(testMessage); - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe({ - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { receivedMsgs.push(msg); return Promise.resolve(); }, @@ -593,13 +583,15 @@ describe("Streaming with sessions", () => { await testPeekMsgsLength(receiver, 0); if (operation === DispositionType.complete) { - await receivedMsgs[0].complete().catch((err) => testError(err, operation)); + await receiver.completeMessage(receivedMsgs[0]).catch((err) => testError(err, operation)); } else if (operation === DispositionType.abandon) { - await receivedMsgs[0].abandon().catch((err) => testError(err, operation)); + await receiver.abandonMessage(receivedMsgs[0]).catch((err) => testError(err, operation)); } else if (operation === DispositionType.deadletter) { - await receivedMsgs[0].deadLetter().catch((err) => testError(err, operation)); + await receiver + .deadLetterMessage(receivedMsgs[0]) + .catch((err) => testError(err, operation)); } else if (operation === DispositionType.defer) { - await receivedMsgs[0].defer().catch((err) => testError(err, operation)); + await receiver.deferMessage(receivedMsgs[0]).catch((err) => testError(err, operation)); } should.equal(errorWasThrown, true, "Error thrown flag must be true"); @@ -633,10 +625,10 @@ describe("Streaming with sessions", () => { await sender.sendMessages(testMessage); const errorMessage = "Will we see this error message?"; - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe({ - async processMessage(msg: ServiceBusReceivedMessageWithLock) { - await msg.complete(); + async processMessage(msg: ServiceBusReceivedMessage) { + await receiver.completeMessage(msg); receivedMsgs.push(msg); throw new Error(errorMessage); }, @@ -691,12 +683,12 @@ describe("Streaming with sessions", () => { } await sender.sendMessages(batchMessageToSend); - const settledMsgs: ServiceBusReceivedMessageWithLock[] = []; - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const settledMsgs: ServiceBusReceivedMessage[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe( { - async processMessage(msg: ServiceBusReceivedMessageWithLock) { + async processMessage(msg: ServiceBusReceivedMessage) { if (receivedMsgs.length === 1) { if ((!maxConcurrentCalls || maxConcurrentCalls === 1) && settledMsgs.length === 0) { throw new Error( @@ -713,7 +705,7 @@ describe("Streaming with sessions", () => { receivedMsgs.push(msg); await delay(2000); - await msg.complete(); + await receiver.completeMessage(msg); settledMsgs.push(msg); }, processError @@ -769,13 +761,13 @@ describe("Streaming with sessions", () => { } await sender.sendMessages(batch); - const receivedMsgs: ServiceBusReceivedMessageWithLock[] = []; + const receivedMsgs: ServiceBusReceivedMessage[] = []; receiver.subscribe( { - async processMessage(brokeredMessage: ServiceBusReceivedMessageWithLock) { + async processMessage(brokeredMessage: ServiceBusReceivedMessage) { receivedMsgs.push(brokeredMessage); - await brokeredMessage.complete(); + await receiver.completeMessage(brokeredMessage); }, processError }, diff --git a/sdk/servicebus/service-bus/test/utils/testutils2.ts b/sdk/servicebus/service-bus/test/utils/testutils2.ts index 4ab7146fefab..a3e6e1776d93 100644 --- a/sdk/servicebus/service-bus/test/utils/testutils2.ts +++ b/sdk/servicebus/service-bus/test/utils/testutils2.ts @@ -22,11 +22,7 @@ import { verifyMessageCount } from "./managementUtils"; import chai from "chai"; -import { - ServiceBusReceivedMessage, - ServiceBusReceivedMessageWithLock, - ServiceBusMessage -} from "../../src/serviceBusMessage"; +import { ServiceBusReceivedMessage, ServiceBusMessage } from "../../src/serviceBusMessage"; dotenv.config(); const env = getEnvVars(); @@ -128,7 +124,7 @@ async function createTestEntities( return relatedEntities; } -export async function drainAllMessages(receiver: ServiceBusReceiver<{}>): Promise { +export async function drainAllMessages(receiver: ServiceBusReceiver) { while (true) { const messages = await receiver.receiveMessages(10, { maxWaitTimeInMs: 1000 }); @@ -220,9 +216,7 @@ export class ServiceBusTestHelpers { entityNames: EntityName, sentMessages: ServiceBusMessage[] ): Promise { - let receiver: - | ServiceBusReceiver - | ServiceBusSessionReceiver; + let receiver: ServiceBusReceiver | ServiceBusSessionReceiver; let receivedMsgs: ServiceBusReceivedMessage[]; if (!entityNames.usesSessions) { receiver = await this.createReceiveAndDeleteReceiver(entityNames); @@ -332,7 +326,7 @@ export class ServiceBusTestHelpers { async createPeekLockReceiver( entityNames: Omit, "isPartitioned">, options?: CreateReceiverOptions<"peekLock"> - ): Promise> { + ): Promise { if (entityNames.usesSessions) { // if you're creating a receiver this way then you'll just use the default // session ID for your receiver. @@ -377,7 +371,7 @@ export class ServiceBusTestHelpers { entityNames: Omit, "isPartitioned">, sessionId: string, options?: AcceptSessionOptions<"peekLock"> - ): Promise> { + ): Promise { if (!entityNames.usesSessions) { throw new TypeError( "Not a session-full entity - can't create a session receiver type for it" @@ -407,7 +401,7 @@ export class ServiceBusTestHelpers { entityNames: Omit, "isPartitioned"> & { sessionId?: string; } - ): Promise> { + ): Promise { // TODO: we should generate a random ID here - there's no harm in // creating as many sessions as we wish. Some tests will need to change. const sessionId = entityNames.sessionId ?? TestMessage.sessionId; @@ -440,9 +434,7 @@ export class ServiceBusTestHelpers { } } - createDeadLetterReceiver( - entityNames: ReturnType - ): ServiceBusReceiver { + createDeadLetterReceiver(entityNames: ReturnType): ServiceBusReceiver { return this.addToCleanup( entityNames.queue ? this._serviceBusClient.createReceiver(entityNames.queue, { @@ -470,12 +462,9 @@ async function purgeForTestClientType( serviceBusClient: ServiceBusClient, testClientType: TestClientType ): Promise { - let receiver: - | ServiceBusReceiver - | ServiceBusSessionReceiver - | undefined; + let receiver: ServiceBusReceiver | ServiceBusSessionReceiver | undefined; const entityPaths = getEntityNames(testClientType); - let deadLetterReceiver: ServiceBusReceiver; + let deadLetterReceiver: ServiceBusReceiver; if (entityPaths.queue) { receiver = serviceBusClient.createReceiver(entityPaths.queue, "receiveAndDelete"); @@ -514,9 +503,7 @@ export function createServiceBusClientForTests( return serviceBusClient; } -export async function drainReceiveAndDeleteReceiver( - receiver: ServiceBusReceiver<{}> -): Promise { +export async function drainReceiveAndDeleteReceiver(receiver: ServiceBusReceiver): Promise { try { while (true) { const messages = await receiver.receiveMessages(10, { maxWaitTimeInMs: 1000 }); @@ -541,7 +528,7 @@ function connectionString() { } export async function testPeekMsgsLength( - peekableReceiver: ServiceBusReceiver, + peekableReceiver: ServiceBusReceiver, expectedPeekLength: number ): Promise { const peekedMsgs = await peekableReceiver.peekMessages(expectedPeekLength + 1); From a4d73e4bdf0276b902203e7fdd874588ffee3a81 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Tue, 20 Oct 2020 17:50:29 -0700 Subject: [PATCH 2/8] Revert change to body in amqpannotatedmessage --- sdk/servicebus/service-bus/review/service-bus.api.md | 2 +- sdk/servicebus/service-bus/src/serviceBusMessage.ts | 2 +- sdk/servicebus/service-bus/test/internal/shared.spec.ts | 4 ++-- 3 files changed, 4 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 862638085a71..48a10f9fc512 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -34,7 +34,7 @@ export interface AmqpAnnotatedMessage { applicationProperties?: { [key: string]: any; }; - body?: any; + body: any; deliveryAnnotations?: { [key: string]: any; }; diff --git a/sdk/servicebus/service-bus/src/serviceBusMessage.ts b/sdk/servicebus/service-bus/src/serviceBusMessage.ts index df6b4b20db53..291dc4c9c499 100644 --- a/sdk/servicebus/service-bus/src/serviceBusMessage.ts +++ b/sdk/servicebus/service-bus/src/serviceBusMessage.ts @@ -249,7 +249,7 @@ export interface AmqpAnnotatedMessage { /** * The message body. */ - body?: any; + body: any; } /** diff --git a/sdk/servicebus/service-bus/test/internal/shared.spec.ts b/sdk/servicebus/service-bus/test/internal/shared.spec.ts index b36d4b045051..57148b2cc510 100644 --- a/sdk/servicebus/service-bus/test/internal/shared.spec.ts +++ b/sdk/servicebus/service-bus/test/internal/shared.spec.ts @@ -40,7 +40,7 @@ describe("shared", () => { [ { body: "hello", - _amqpAnnotatedMessage: {} + _amqpAnnotatedMessage: { body: "hello" } } ] ]; @@ -72,7 +72,7 @@ describe("shared", () => { [ { body: "hello", - _amqpAnnotatedMessage: {} + _amqpAnnotatedMessage: { body: "hello" } } ], allReceivedMessages, From eb4a3950a893aedc2e50f8c55c89ee71fc96a0c4 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Tue, 20 Oct 2020 19:12:51 -0700 Subject: [PATCH 3/8] Clean up --- .../service-bus/src/receivers/receiver.ts | 14 +++++++------- sdk/servicebus/service-bus/src/serviceBusClient.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sdk/servicebus/service-bus/src/receivers/receiver.ts b/sdk/servicebus/service-bus/src/receivers/receiver.ts index 64c86327a6e2..3eff40de89b8 100644 --- a/sdk/servicebus/service-bus/src/receivers/receiver.ts +++ b/sdk/servicebus/service-bus/src/receivers/receiver.ts @@ -439,7 +439,7 @@ export class ServiceBusReceiverImpl implements ServiceBusReceiver { options ?? {} ); - return (receivedMessages as unknown) as ServiceBusReceivedMessage[]; + return receivedMessages; }; const config: RetryConfig = { connectionHost: this._context.config.host, @@ -554,7 +554,7 @@ export class ServiceBusReceiverImpl implements ServiceBusReceiver { const processError = wrapProcessErrorHandler(handlers); - const internalMessageHandlers = handlers as InternalMessageHandlers | undefined; + const internalMessageHandlers = handlers as InternalMessageHandlers; this._registerMessageHandler( async () => { @@ -577,12 +577,12 @@ export class ServiceBusReceiverImpl implements ServiceBusReceiver { }; } - async completeMessage(message: ServiceBusReceivedMessage): Promise { + completeMessage(message: ServiceBusReceivedMessage): Promise { const msgImpl = message as ServiceBusMessageImpl; return msgImpl.complete(); } - async abandonMessage( + abandonMessage( message: ServiceBusReceivedMessage, propertiesToModify?: { [key: string]: any } ): Promise { @@ -590,7 +590,7 @@ export class ServiceBusReceiverImpl implements ServiceBusReceiver { return msgImpl.abandon(propertiesToModify); } - async deferMessage( + deferMessage( message: ServiceBusReceivedMessage, propertiesToModify?: { [key: string]: any } ): Promise { @@ -598,7 +598,7 @@ export class ServiceBusReceiverImpl implements ServiceBusReceiver { return msgImpl.defer(propertiesToModify); } - async deadLetterMessage( + deadLetterMessage( message: ServiceBusReceivedMessage, options?: DeadLetterOptions & { [key: string]: any } ): Promise { @@ -606,7 +606,7 @@ export class ServiceBusReceiverImpl implements ServiceBusReceiver { return msgImpl.deadLetter(options); } - async renewMessageLock(message: ServiceBusReceivedMessage): Promise { + renewMessageLock(message: ServiceBusReceivedMessage): Promise { const msgImpl = message as ServiceBusMessageImpl; return msgImpl.renewLock(); } diff --git a/sdk/servicebus/service-bus/src/serviceBusClient.ts b/sdk/servicebus/service-bus/src/serviceBusClient.ts index 8a9f0beb17b3..31956b7d686c 100644 --- a/sdk/servicebus/service-bus/src/serviceBusClient.ts +++ b/sdk/servicebus/service-bus/src/serviceBusClient.ts @@ -205,7 +205,7 @@ export class ServiceBusClient { | CreateReceiverOptions<"peekLock"> | string, options3?: CreateReceiverOptions<"receiveAndDelete"> | CreateReceiverOptions<"peekLock"> - ): ServiceBusReceiver | ServiceBusReceiver { + ): ServiceBusReceiver { validateEntityPath(this._connectionContext.config, queueOrTopicName1); // NOTE: we don't currently have any options for this kind of receiver but From 41eef8fb729b44cd614fe7864b4d4c05e5050e5b Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Tue, 20 Oct 2020 20:26:49 -0700 Subject: [PATCH 4/8] Fix streaming receiver tests --- sdk/servicebus/service-bus/test/streamingReceiver.spec.ts | 2 +- .../service-bus/test/streamingReceiverSessions.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts b/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts index ceda5abeffa5..027d947d776e 100644 --- a/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts +++ b/sdk/servicebus/service-bus/test/streamingReceiver.spec.ts @@ -898,7 +898,7 @@ describe("Streaming Receiver Tests", () => { // and will still be settleable). await subscriber.close(); - await receiver.completeMessage(messages[0]); + await actualReceiver.completeMessage(messages[0]); messages.pop(); await sender.sendMessages({ diff --git a/sdk/servicebus/service-bus/test/streamingReceiverSessions.spec.ts b/sdk/servicebus/service-bus/test/streamingReceiverSessions.spec.ts index f346a576d2b9..12d21cb09237 100644 --- a/sdk/servicebus/service-bus/test/streamingReceiverSessions.spec.ts +++ b/sdk/servicebus/service-bus/test/streamingReceiverSessions.spec.ts @@ -121,7 +121,7 @@ describe("Streaming with sessions", () => { // and will still be settleable). await subscriber.close(); - await receiver.completeMessage(messages[0]); + await actualReceiver.completeMessage(messages[0]); messages.pop(); await sender.sendMessages({ From 11c467b6ee3d2d44d0c781d14e9b172d1a56ac0d Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 21 Oct 2020 18:16:40 -0700 Subject: [PATCH 5/8] Remove obsolete casting --- .../test/receiveAndDeleteMode.spec.ts | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/sdk/servicebus/service-bus/test/receiveAndDeleteMode.spec.ts b/sdk/servicebus/service-bus/test/receiveAndDeleteMode.spec.ts index 173688ecc154..85aa858596bb 100644 --- a/sdk/servicebus/service-bus/test/receiveAndDeleteMode.spec.ts +++ b/sdk/servicebus/service-bus/test/receiveAndDeleteMode.spec.ts @@ -241,9 +241,7 @@ describe("receive and delete", () => { const testMessages = entityName.usesSessions ? TestMessage.getSessionSample() : TestMessage.getSample(); - // we have to force this cast - the type system doesn't allow this if you've chosen receiveAndDelete - // as your lock mode. - const msg = (await sendReceiveMsg(testMessages)) as ServiceBusReceivedMessage; + const msg = await sendReceiveMsg(testMessages); try { if (operation === DispositionType.complete) { @@ -308,7 +306,6 @@ describe("receive and delete", () => { async function testRenewLock(): Promise { const msg = await sendReceiveMsg(TestMessage.getSample()); - // have to cast it - the type system doesn't allow us to call into this method otherwise. await receiver.renewMessageLock(msg).catch((err) => { should.equal( err.message, @@ -456,19 +453,16 @@ describe("receive and delete", () => { operation: DispositionType ): Promise { const deferredMsg = await testDeferredMessage(testClienttype); - // we have to force this cast - the type system doesn't allow this if you've chosen receiveAndDelete - // as your lock mode. - const msg = deferredMsg as ServiceBusReceivedMessage; try { if (operation === DispositionType.complete) { - await receiver.completeMessage(msg); + await receiver.completeMessage(deferredMsg); } else if (operation === DispositionType.abandon) { - await receiver.abandonMessage(msg); + await receiver.abandonMessage(deferredMsg); } else if (operation === DispositionType.deadletter) { - await receiver.deadLetterMessage(msg); + await receiver.deadLetterMessage(deferredMsg); } else if (operation === DispositionType.defer) { - await receiver.deferMessage(msg); + await receiver.deferMessage(deferredMsg); } } catch (err) { errorWasThrown = true; @@ -512,10 +506,7 @@ describe("receive and delete", () => { async function testRenewLock(testClienttype: TestClientType): Promise { const deferredMsg = await testDeferredMessage(testClienttype); - // we have to force this cast - the type system doesn't allow this if you've chosen receiveAndDelete - // as your lock mode. - // have to cast it - the type system doesn't allow us to call into this method otherwise. await receiver.renewMessageLock(deferredMsg).catch((err) => { should.equal( err.message, From 3ec99efacab643ad6fa9ddae7c225ebbbb7231b2 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 21 Oct 2020 18:18:23 -0700 Subject: [PATCH 6/8] jsdoc update for settlement methods as per feedback --- .../service-bus/src/receivers/receiver.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sdk/servicebus/service-bus/src/receivers/receiver.ts b/sdk/servicebus/service-bus/src/receivers/receiver.ts index 3eff40de89b8..66d643e95d57 100644 --- a/sdk/servicebus/service-bus/src/receivers/receiver.ts +++ b/sdk/servicebus/service-bus/src/receivers/receiver.ts @@ -140,14 +140,14 @@ export interface ServiceBusReceiver { * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) * if the AMQP link with which the message was received is no longer alive. This can * happen either because the lock on the session expired or the receiver was explicitly closed by - * the user or the AMQP link got closed by the library due to network loss or service error. + * the user or the AMQP link is closed by the library due to network loss or service error. * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) * if the lock on the message has expired or the AMQP link with which the message was received is * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the * AMQP link got closed by the library due to network loss or service error. * @throws Error if the message is already settled. To avoid this error check the `isSettled` * property on the message if you are not sure whether the message is settled. - * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode + * @throws Error if used in `receiveAndDelete` mode because all messages received in this mode * are pre-settled. To avoid this error, update your code to not settle a message which is received * in this mode. * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle @@ -163,14 +163,14 @@ export interface ServiceBusReceiver { * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) * if the AMQP link with which the message was received is no longer alive. This can * happen either because the lock on the session expired or the receiver was explicitly closed by - * the user or the AMQP link got closed by the library due to network loss or service error. + * the user or the AMQP link is closed by the library due to network loss or service error. * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) * if the lock on the message has expired or the AMQP link with which the message was received is * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the * AMQP link got closed by the library due to network loss or service error. * @throws Error if the message is already settled. To avoid this error check the `isSettled` * property on the message if you are not sure whether the message is settled. - * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode + * @throws Error if used in `receiveAndDelete` mode because all messages received in this mode * are pre-settled. To avoid this error, update your code to not settle a message which is received * in this mode. * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle @@ -191,14 +191,14 @@ export interface ServiceBusReceiver { * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) * if the AMQP link with which the message was received is no longer alive. This can * happen either because the lock on the session expired or the receiver was explicitly closed by - * the user or the AMQP link got closed by the library due to network loss or service error. + * the user or the AMQP link is closed by the library due to network loss or service error. * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) * if the lock on the message has expired or the AMQP link with which the message was received is * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the * AMQP link got closed by the library due to network loss or service error. * @throws Error if the message is already settled. To avoid this error check the `isSettled` * property on the message if you are not sure whether the message is settled. - * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode + * @throws Error if used in `receiveAndDelete` mode because all messages received in this mode * are pre-settled. To avoid this error, update your code to not settle a message which is received * in this mode. * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle @@ -219,14 +219,14 @@ export interface ServiceBusReceiver { * @throws Error with name `SessionLockLostError` (for messages from a Queue/Subscription with sessions enabled) * if the AMQP link with which the message was received is no longer alive. This can * happen either because the lock on the session expired or the receiver was explicitly closed by - * the user or the AMQP link got closed by the library due to network loss or service error. + * the user or the AMQP link is closed by the library due to network loss or service error. * @throws Error with name `MessageLockLostError` (for messages from a Queue/Subscription with sessions not enabled) * if the lock on the message has expired or the AMQP link with which the message was received is * no longer alive. The latter can happen if the receiver was explicitly closed by the user or the * AMQP link got closed by the library due to network loss or service error. * @throws Error if the message is already settled. To avoid this error check the `isSettled` * property on the message if you are not sure whether the message is settled. - * @throws Error if used in `ReceiveAndDelete` mode because all messages received in this mode + * @throws Error if used in `receiveAndDelete` mode because all messages received in this mode * are pre-settled. To avoid this error, update your code to not settle a message which is received * in this mode. * @throws Error with name `ServiceUnavailableError` if Service Bus does not acknowledge the request to settle From cef80ad47ea4a9e3d3b519da4be12f0be09c3ee1 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 21 Oct 2020 18:27:25 -0700 Subject: [PATCH 7/8] Formatting --- sdk/servicebus/service-bus/review/service-bus.api.md | 2 +- sdk/servicebus/service-bus/src/util/connectionStringUtils.ts | 4 +--- 2 files changed, 2 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 d9921f541210..42978068dc48 100644 --- a/sdk/servicebus/service-bus/review/service-bus.api.md +++ b/sdk/servicebus/service-bus/review/service-bus.api.md @@ -192,7 +192,7 @@ export interface GetMessageIteratorOptions extends OperationOptionsBase { } // @public -export interface MessageHandlers { +export interface MessageHandlers { processError(args: ProcessErrorArgs): Promise; processMessage(message: ServiceBusReceivedMessage): Promise; } diff --git a/sdk/servicebus/service-bus/src/util/connectionStringUtils.ts b/sdk/servicebus/service-bus/src/util/connectionStringUtils.ts index 16a944f053e1..f5a447afe04f 100644 --- a/sdk/servicebus/service-bus/src/util/connectionStringUtils.ts +++ b/sdk/servicebus/service-bus/src/util/connectionStringUtils.ts @@ -71,9 +71,7 @@ export function parseServiceBusConnectionString( ); } } else if (parsedResult.SharedAccessKey && !parsedResult.SharedAccessKeyName) { - throw new Error( - "Connection string with SharedAccessKey should have SharedAccessKeyName." - ); + throw new Error("Connection string with SharedAccessKey should have SharedAccessKeyName."); } else if (!parsedResult.SharedAccessKey && parsedResult.SharedAccessKeyName) { throw new Error( "Connection string with SharedAccessKeyName should have SharedAccessKey as well." From 52b585f2bf2ece6a3b2ef1bf46e9facbc512ad9c Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Wed, 21 Oct 2020 19:37:58 -0700 Subject: [PATCH 8/8] Enable non session backupMessageSettlement tests --- .../test/backupMessageSettlement.spec.ts | 729 ++++++++++-------- 1 file changed, 395 insertions(+), 334 deletions(-) diff --git a/sdk/servicebus/service-bus/test/backupMessageSettlement.spec.ts b/sdk/servicebus/service-bus/test/backupMessageSettlement.spec.ts index c5562ea662fb..4cfbbfd2838f 100644 --- a/sdk/servicebus/service-bus/test/backupMessageSettlement.spec.ts +++ b/sdk/servicebus/service-bus/test/backupMessageSettlement.spec.ts @@ -1,336 +1,397 @@ -// // Copyright (c) Microsoft Corporation. -// // Licensed under the MIT license. - -// import chai from "chai"; -// import chaiAsPromised from "chai-as-promised"; -// import { ServiceBusMessage } from "../src"; -// import { TestClientType, TestMessage } from "./utils/testUtils"; -// import { ServiceBusReceiver } from "../src/receivers/receiver"; -// import { ServiceBusSender } from "../src/sender"; -// import { -// EntityName, -// ServiceBusClientForTests, -// createServiceBusClientForTests, -// testPeekMsgsLength, -// getRandomTestClientTypeWithSessions, -// getRandomTestClientTypeWithNoSessions -// } from "./utils/testutils2"; -// import { DispositionType, ServiceBusReceivedMessage } from "../src/serviceBusMessage"; - -// const should = chai.should(); -// chai.use(chaiAsPromised); - -// const noSessionTestClientType = getRandomTestClientTypeWithNoSessions(); +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; +import { ServiceBusMessage } from "../src"; +import { TestClientType, TestMessage } from "./utils/testUtils"; +import { ServiceBusReceiver, ServiceBusReceiverImpl } from "../src/receivers/receiver"; +import { ServiceBusSender } from "../src/sender"; +import { + EntityName, + ServiceBusClientForTests, + createServiceBusClientForTests, + testPeekMsgsLength, + // getRandomTestClientTypeWithSessions, + getRandomTestClientTypeWithNoSessions +} from "./utils/testutils2"; +import { + DispositionType, + ServiceBusMessageImpl, + ServiceBusReceivedMessage +} from "../src/serviceBusMessage"; + +const should = chai.should(); +chai.use(chaiAsPromised); + +const noSessionTestClientType = getRandomTestClientTypeWithNoSessions(); // const withSessionTestClientType = getRandomTestClientTypeWithSessions(); -// describe("Message settlement After Receiver is Closed - Through ManagementLink", () => { -// let serviceBusClient: ServiceBusClientForTests; - -// let sender: ServiceBusSender; -// let receiver: ServiceBusReceiver; -// let deadLetterReceiver: ServiceBusReceiver; -// let entityNames: EntityName; - -// before(() => { -// serviceBusClient = createServiceBusClientForTests(); -// }); - -// after(() => { -// return serviceBusClient.test.after(); -// }); - -// async function beforeEachTest(entityType: TestClientType): Promise { -// entityNames = await serviceBusClient.test.createTestEntities(entityType); -// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); - -// sender = serviceBusClient.test.addToCleanup( -// serviceBusClient.createSender(entityNames.queue ?? entityNames.topic!) -// ); - -// deadLetterReceiver = serviceBusClient.test.createDeadLetterReceiver(entityNames); -// } - -// afterEach(async () => { -// await serviceBusClient.test.afterEach(); -// }); - -// async function sendReceiveMsg( -// testMessages: ServiceBusMessage -// ): Promise { -// await sender.sendMessages(testMessages); -// const msgs = await receiver.receiveMessages(1); - -// should.equal(Array.isArray(msgs), true, "`ReceivedMessages` is not an array"); -// should.equal(msgs.length, 1, "Unexpected number of messages"); -// should.equal(msgs[0].body, testMessages.body, "MessageBody is different than expected"); -// should.equal(msgs[0].messageId, testMessages.messageId, "MessageId is different than expected"); -// should.equal(msgs[0].deliveryCount, 0, "DeliveryCount is different than expected"); - -// return msgs[0]; -// } - -// async function testComplete(): Promise { -// const testMessages = entityNames.usesSessions -// ? TestMessage.getSessionSample() -// : TestMessage.getSample(); -// const msg = await sendReceiveMsg(testMessages); -// await receiver.close(); -// let errorWasThrown = false; -// try { -// await msg.complete(); -// } catch (err) { -// should.equal( -// err.message, -// `Failed to ${DispositionType.complete} the message as the AMQP link with which the message was received is no longer alive.`, -// "Unexpected error thrown" -// ); -// errorWasThrown = true; -// } - -// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); -// if (entityNames.usesSessions) { -// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); -// const msgBatch = await receiver.receiveMessages(1); -// await msgBatch[0].complete(); -// } else { -// should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); -// } -// await testPeekMsgsLength(receiver, 0); -// } - -// it(noSessionTestClientType + ": complete() removes message", async function(): Promise { -// await beforeEachTest(noSessionTestClientType); -// await testComplete(); -// }); - -// it(withSessionTestClientType + ": complete() removes message", async function(): Promise { -// await beforeEachTest(withSessionTestClientType); -// await testComplete(); -// }); - -// async function testAbandon(): Promise { -// const testMessages = entityNames.usesSessions -// ? TestMessage.getSessionSample() -// : TestMessage.getSample(); -// const msg = await sendReceiveMsg(testMessages); -// await receiver.close(); -// let errorWasThrown = false; -// try { -// await msg.abandon(); -// } catch (err) { -// should.equal( -// err.message, -// `Failed to ${DispositionType.abandon} the message as the AMQP link with which the message was received is no longer alive.`, -// "Unexpected error thrown" -// ); -// errorWasThrown = true; -// } - -// if (entityNames.usesSessions) { -// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); -// } else { -// should.equal(errorWasThrown, false, "Error was thrown for messages without session-id"); -// } -// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); -// await testPeekMsgsLength(receiver, 1); - -// const messageBatch = await receiver.receiveMessages(1); - -// await messageBatch[0].complete(); - -// await testPeekMsgsLength(receiver, 0); -// } - -// it( -// noSessionTestClientType + ": abandon() retains message with incremented deliveryCount", -// async function(): Promise { -// await beforeEachTest(noSessionTestClientType); -// await testAbandon(); -// } -// ); - -// it( -// withSessionTestClientType + ": abandon() retains message with incremented deliveryCount", -// async function(): Promise { -// await beforeEachTest(withSessionTestClientType); -// await testAbandon(); -// } -// ); - -// async function testDefer(): Promise { -// const testMessages = entityNames.usesSessions -// ? TestMessage.getSessionSample() -// : TestMessage.getSample(); -// const msg = await sendReceiveMsg(testMessages); - -// if (!msg.sequenceNumber) { -// throw "Sequence Number can not be null"; -// } -// const sequenceNumber = msg.sequenceNumber; -// await receiver.close(); -// let errorWasThrown = false; -// try { -// await msg.defer(); -// } catch (err) { -// should.equal( -// err.message, -// `Failed to ${DispositionType.defer} the message as the AMQP link with which the message was received is no longer alive.`, -// "Unexpected error thrown" -// ); -// errorWasThrown = true; -// } - -// if (entityNames.usesSessions) { -// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); -// } else { -// should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); -// } -// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); -// if (!entityNames.usesSessions) { -// const [deferredMsg] = await receiver.receiveDeferredMessages(sequenceNumber); -// if (!deferredMsg) { -// throw "No message received for sequence number"; -// } -// await deferredMsg.complete(); -// } else { -// const messageBatch = await receiver.receiveMessages(1); -// await messageBatch[0].complete(); -// } -// await testPeekMsgsLength(receiver, 0); -// } - -// it( -// noSessionTestClientType + ": defer() moves message to deferred queue", -// async function(): Promise { -// await beforeEachTest(noSessionTestClientType); -// await testDefer(); -// } -// ); - -// it( -// withSessionTestClientType + ": defer() moves message to deferred queue", -// async function(): Promise { -// await beforeEachTest(withSessionTestClientType); -// await testDefer(); -// } -// ); - -// async function testDeadletter(): Promise { -// const testMessages = entityNames.usesSessions -// ? TestMessage.getSessionSample() -// : TestMessage.getSample(); -// const msg = await sendReceiveMsg(testMessages); -// await receiver.close(); -// let errorWasThrown = false; -// try { -// await msg.deadLetter(); -// } catch (err) { -// should.equal( -// err.message, -// `Failed to ${DispositionType.deadletter} the message as the AMQP link with which the message was received is no longer alive.`, -// "Unexpected error thrown" -// ); -// errorWasThrown = true; -// } - -// if (entityNames.usesSessions) { -// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); -// } else { -// should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); -// } - -// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); - -// if (!entityNames.usesSessions) { -// const deadLetterMsgsBatch = await deadLetterReceiver.receiveMessages(1); - -// should.equal( -// Array.isArray(deadLetterMsgsBatch), -// true, -// "`ReceivedMessages` from Deadletter is not an array" -// ); -// should.equal(deadLetterMsgsBatch.length, 1, "Unexpected number of messages"); -// should.equal( -// deadLetterMsgsBatch[0].body, -// testMessages.body, -// "MessageBody is different than expected" -// ); -// should.equal( -// deadLetterMsgsBatch[0].messageId, -// testMessages.messageId, -// "MessageId is different than expected" -// ); - -// await deadLetterMsgsBatch[0].complete(); - -// await testPeekMsgsLength(deadLetterReceiver, 0); -// } else { -// const messageBatch = await receiver.receiveMessages(1); -// await messageBatch[0].complete(); - -// await testPeekMsgsLength(receiver, 0); -// } -// } - -// it( -// noSessionTestClientType + ": deadLetter() moves message to deadletter queue", -// async function(): Promise { -// await beforeEachTest(noSessionTestClientType); -// await testDeadletter(); -// } -// ); - -// it( -// withSessionTestClientType + ": deadLetter() moves message to deadletter queue", -// async function(): Promise { -// await beforeEachTest(withSessionTestClientType); -// await testDeadletter(); -// } -// ); - -// async function testRenewLock(): Promise { -// const testMessages = entityNames.usesSessions -// ? TestMessage.getSessionSample() -// : TestMessage.getSample(); -// const msg = await sendReceiveMsg(testMessages); -// await receiver.close(); -// let errorWasThrown = false; -// try { -// const lockedUntilBeforeRenewlock = msg.lockedUntilUtc; -// const lockedUntilAfterRenewlock = await msg.renewLock(); -// should.equal( -// lockedUntilAfterRenewlock > lockedUntilBeforeRenewlock!, -// true, -// "MessageLock did not get renewed!" -// ); -// await msg.complete(); -// } catch (err) { -// should.equal( -// err.message, -// `Invalid operation on the message, message lock doesn't exist when dealing with sessions`, -// "Unexpected error thrown" -// ); -// errorWasThrown = true; -// } - -// receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); -// if (entityNames.usesSessions) { -// should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); -// const msgBatch = await receiver.receiveMessages(1); -// await msgBatch[0].complete(); -// } else { -// should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); -// } -// await testPeekMsgsLength(receiver, 0); -// } - -// it(noSessionTestClientType + ": Lock renewal for a message", async function(): Promise { -// await beforeEachTest(noSessionTestClientType); -// await testRenewLock(); -// }); - -// it(withSessionTestClientType + ": Lock renewal for session", async function(): Promise { -// await beforeEachTest(withSessionTestClientType); -// await testRenewLock(); -// }); -// }); +describe("Message settlement After Receiver is Closed - Through ManagementLink", () => { + let serviceBusClient: ServiceBusClientForTests; + + let sender: ServiceBusSender; + let receiver: ServiceBusReceiver; + let deadLetterReceiver: ServiceBusReceiver; + let entityNames: EntityName; + + before(() => { + serviceBusClient = createServiceBusClientForTests(); + }); + + after(() => { + return serviceBusClient.test.after(); + }); + + async function beforeEachTest(entityType: TestClientType): Promise { + entityNames = await serviceBusClient.test.createTestEntities(entityType); + receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + + sender = serviceBusClient.test.addToCleanup( + serviceBusClient.createSender(entityNames.queue ?? entityNames.topic!) + ); + + deadLetterReceiver = serviceBusClient.test.createDeadLetterReceiver(entityNames); + } + + afterEach(async () => { + await serviceBusClient.test.afterEach(); + }); + + async function sendReceiveMsg( + testMessages: ServiceBusMessage + ): Promise { + await sender.sendMessages(testMessages); + const msgs = await receiver.receiveMessages(1); + + should.equal(Array.isArray(msgs), true, "`ReceivedMessages` is not an array"); + should.equal(msgs.length, 1, "Unexpected number of messages"); + should.equal(msgs[0].body, testMessages.body, "MessageBody is different than expected"); + should.equal(msgs[0].messageId, testMessages.messageId, "MessageId is different than expected"); + should.equal(msgs[0].deliveryCount, 0, "DeliveryCount is different than expected"); + + return msgs[0]; + } + + async function testComplete(): Promise { + const testMessages = entityNames.usesSessions + ? TestMessage.getSessionSample() + : TestMessage.getSample(); + const msg = await sendReceiveMsg(testMessages); + const msgDeliveryLink = (msg as ServiceBusMessageImpl).delivery.link.name; + + if (entityNames.usesSessions) { + await (receiver as ServiceBusReceiverImpl)["_context"].messageSessions[ + msgDeliveryLink + ].close(); + } else { + await (receiver as ServiceBusReceiverImpl)["_context"].messageReceivers[ + msgDeliveryLink + ].close(); + } + + let errorWasThrown = false; + try { + await receiver.completeMessage(msg); + } catch (err) { + should.equal( + err.message, + `Failed to ${DispositionType.complete} the message as the AMQP link with which the message was received is no longer alive.`, + "Unexpected error thrown" + ); + errorWasThrown = true; + } + + receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + if (entityNames.usesSessions) { + should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); + receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + const msgBatch = await receiver.receiveMessages(1); + await receiver.completeMessage(msgBatch[0]); + } else { + should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); + } + await testPeekMsgsLength(receiver, 0); + } + + it(noSessionTestClientType + ": complete() removes message", async function(): Promise { + await beforeEachTest(noSessionTestClientType); + await testComplete(); + }); + + // it(withSessionTestClientType + ": complete() removes message", async function(): Promise { + // await beforeEachTest(withSessionTestClientType); + // await testComplete(); + // }); + + async function testAbandon(): Promise { + const testMessages = entityNames.usesSessions + ? TestMessage.getSessionSample() + : TestMessage.getSample(); + const msg = await sendReceiveMsg(testMessages); + const msgDeliveryLink = (msg as ServiceBusMessageImpl).delivery.link.name; + + if (entityNames.usesSessions) { + await (receiver as ServiceBusReceiverImpl)["_context"].messageSessions[ + msgDeliveryLink + ].close(); + } else { + await (receiver as ServiceBusReceiverImpl)["_context"].messageReceivers[ + msgDeliveryLink + ].close(); + } + + let errorWasThrown = false; + try { + await receiver.abandonMessage(msg); + } catch (err) { + should.equal( + err.message, + `Failed to ${DispositionType.abandon} the message as the AMQP link with which the message was received is no longer alive.`, + "Unexpected error thrown" + ); + errorWasThrown = true; + } + + if (entityNames.usesSessions) { + should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); + } else { + should.equal(errorWasThrown, false, "Error was thrown for messages without session-id"); + } + receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + await testPeekMsgsLength(receiver, 1); + + const messageBatch = await receiver.receiveMessages(1); + + await receiver.completeMessage(messageBatch[0]); + + await testPeekMsgsLength(receiver, 0); + } + + it( + noSessionTestClientType + ": abandon() retains message with incremented deliveryCount", + async function(): Promise { + await beforeEachTest(noSessionTestClientType); + await testAbandon(); + } + ); + + // it( + // withSessionTestClientType + ": abandon() retains message with incremented deliveryCount", + // async function(): Promise { + // await beforeEachTest(withSessionTestClientType); + // await testAbandon(); + // } + // ); + + async function testDefer(): Promise { + const testMessages = entityNames.usesSessions + ? TestMessage.getSessionSample() + : TestMessage.getSample(); + const msg = await sendReceiveMsg(testMessages); + + if (!msg.sequenceNumber) { + throw "Sequence Number can not be null"; + } + const sequenceNumber = msg.sequenceNumber; + const msgDeliveryLink = (msg as ServiceBusMessageImpl).delivery.link.name; + + if (entityNames.usesSessions) { + await (receiver as ServiceBusReceiverImpl)["_context"].messageSessions[ + msgDeliveryLink + ].close(); + } else { + await (receiver as ServiceBusReceiverImpl)["_context"].messageReceivers[ + msgDeliveryLink + ].close(); + } + + let errorWasThrown = false; + try { + await receiver.deferMessage(msg); + } catch (err) { + should.equal( + err.message, + `Failed to ${DispositionType.defer} the message as the AMQP link with which the message was received is no longer alive.`, + "Unexpected error thrown" + ); + errorWasThrown = true; + } + + if (entityNames.usesSessions) { + should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); + } else { + should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); + } + receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + if (!entityNames.usesSessions) { + const [deferredMsg] = await receiver.receiveDeferredMessages(sequenceNumber); + if (!deferredMsg) { + throw "No message received for sequence number"; + } + await receiver.completeMessage(deferredMsg); + } else { + const messageBatch = await receiver.receiveMessages(1); + await receiver.completeMessage(messageBatch[0]); + } + await testPeekMsgsLength(receiver, 0); + } + + it( + noSessionTestClientType + ": defer() moves message to deferred queue", + async function(): Promise { + await beforeEachTest(noSessionTestClientType); + await testDefer(); + } + ); + + // it( + // withSessionTestClientType + ": defer() moves message to deferred queue", + // async function(): Promise { + // await beforeEachTest(withSessionTestClientType); + // await testDefer(); + // } + // ); + + async function testDeadletter(): Promise { + const testMessages = entityNames.usesSessions + ? TestMessage.getSessionSample() + : TestMessage.getSample(); + const msg = await sendReceiveMsg(testMessages); + await receiver.close(); + const msgDeliveryLink = (msg as ServiceBusMessageImpl).delivery.link.name; + + if (entityNames.usesSessions) { + await (receiver as ServiceBusReceiverImpl)["_context"].messageSessions[ + msgDeliveryLink + ].close(); + } else { + await (receiver as ServiceBusReceiverImpl)["_context"].messageReceivers[ + msgDeliveryLink + ].close(); + } + + let errorWasThrown = false; + try { + await receiver.deadLetterMessage(msg); + } catch (err) { + should.equal( + err.message, + `Failed to ${DispositionType.deadletter} the message as the AMQP link with which the message was received is no longer alive.`, + "Unexpected error thrown" + ); + errorWasThrown = true; + } + + if (entityNames.usesSessions) { + should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); + } else { + should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); + } + + receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + + if (!entityNames.usesSessions) { + const deadLetterMsgsBatch = await deadLetterReceiver.receiveMessages(1); + + should.equal( + Array.isArray(deadLetterMsgsBatch), + true, + "`ReceivedMessages` from Deadletter is not an array" + ); + should.equal(deadLetterMsgsBatch.length, 1, "Unexpected number of messages"); + should.equal( + deadLetterMsgsBatch[0].body, + testMessages.body, + "MessageBody is different than expected" + ); + should.equal( + deadLetterMsgsBatch[0].messageId, + testMessages.messageId, + "MessageId is different than expected" + ); + + await receiver.completeMessage(deadLetterMsgsBatch[0]); + + await testPeekMsgsLength(deadLetterReceiver, 0); + } else { + const messageBatch = await receiver.receiveMessages(1); + await receiver.completeMessage(messageBatch[0]); + + await testPeekMsgsLength(receiver, 0); + } + } + + it( + noSessionTestClientType + ": deadLetter() moves message to deadletter queue", + async function(): Promise { + await beforeEachTest(noSessionTestClientType); + await testDeadletter(); + } + ); + + // it( + // withSessionTestClientType + ": deadLetter() moves message to deadletter queue", + // async function(): Promise { + // await beforeEachTest(withSessionTestClientType); + // await testDeadletter(); + // } + // ); + + async function testRenewLock(): Promise { + const testMessages = entityNames.usesSessions + ? TestMessage.getSessionSample() + : TestMessage.getSample(); + const msg = await sendReceiveMsg(testMessages); + const msgDeliveryLink = (msg as ServiceBusMessageImpl).delivery.link.name; + + if (entityNames.usesSessions) { + await (receiver as ServiceBusReceiverImpl)["_context"].messageSessions[ + msgDeliveryLink + ].close(); + } else { + await (receiver as ServiceBusReceiverImpl)["_context"].messageReceivers[ + msgDeliveryLink + ].close(); + } + + let errorWasThrown = false; + try { + const lockedUntilBeforeRenewlock = msg.lockedUntilUtc; + const lockedUntilAfterRenewlock = await receiver.renewMessageLock(msg); + should.equal( + lockedUntilAfterRenewlock > lockedUntilBeforeRenewlock!, + true, + "MessageLock did not get renewed!" + ); + await receiver.completeMessage(msg); + } catch (err) { + should.equal( + err.message, + `Invalid operation on the message, message lock doesn't exist when dealing with sessions`, + "Unexpected error thrown" + ); + errorWasThrown = true; + } + + receiver = await serviceBusClient.test.createPeekLockReceiver(entityNames); + if (entityNames.usesSessions) { + should.equal(errorWasThrown, true, "Error was not thrown for messages with session-id"); + const msgBatch = await receiver.receiveMessages(1); + await receiver.completeMessage(msgBatch[0]); + } else { + should.equal(errorWasThrown, false, "Error was thrown for sessions without session-id"); + } + await testPeekMsgsLength(receiver, 0); + } + + it(noSessionTestClientType + ": Lock renewal for a message", async function(): Promise { + await beforeEachTest(noSessionTestClientType); + await testRenewLock(); + }); + + // it(withSessionTestClientType + ": Lock renewal for session", async function(): Promise { + // await beforeEachTest(withSessionTestClientType); + // await testRenewLock(); + // }); +});