Skip to content

Commit 21969bb

Browse files
[Service Bus] ATOM API: Allow configuring the rule with createSubscription (Azure#12495)
### Issue Azure#12345 Adding support to allow configuring the rule with createSubscription by taking the [XML request](https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/servicebus/Azure.Messaging.ServiceBus/tests/SessionRecords/ServiceBusManagementClientLiveTests/BasicRuleCrudOperationsAsync.json#L66-L71) from .NET SDK as reference. (Thanks @JoshLove-msft)
1 parent 17a3aed commit 21969bb

File tree

8 files changed

+236
-151
lines changed

8 files changed

+236
-151
lines changed

sdk/servicebus/service-bus/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66

77
- The `ServiceBusError.reason` field has been renamed `ServiceBusError.code`.
88
The `code` field can be used to differentiate what caused a `ServiceBusError` to be thrown.
9-
- Numbers passed in `applicationProperties` of the correlation rule filter and `sqlParameters` under SQLRuleFilter will now be serialized as "double"(used to be "int") while sending the requests. The "double" and "int" values in the response will now be deserialized as "number"("double" wasn't supported before).
9+
- Numbers passed in `applicationProperties` of the correlation rule filter and `sqlParameters` under SQLRuleFilter will now be serialized as "double"(used to be "int") while sending the requests. The "double" and "int" values in the response will now be deserialized as "number"("double" wasn't supported before).
1010
[PR 12349](https://github.com/Azure/azure-sdk-for-js/pull/12349)
11+
- `ServiceBusAdministrationClient.createSubscription` now supports configuring default rule at the time of creating the subscription.
12+
[PR 12495](https://github.com/Azure/azure-sdk-for-js/pull/12495)
1113

1214
## 7.0.0-preview.8 (2020-11-04)
1315

sdk/servicebus/service-bus/review/service-bus.api.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ export interface CreateSubscriptionOptions extends OperationOptions {
8383
deadLetteringOnFilterEvaluationExceptions?: boolean;
8484
deadLetteringOnMessageExpiration?: boolean;
8585
defaultMessageTimeToLive?: string;
86+
defaultRuleOptions?: {
87+
name: string;
88+
filter?: SqlRuleFilter | CorrelationRuleFilter;
89+
action?: SqlRuleAction;
90+
};
8691
enableBatchedOperations?: boolean;
8792
forwardDeadLetteredMessagesTo?: string;
8893
forwardTo?: string;
@@ -508,7 +513,7 @@ export interface SubscriptionProperties {
508513
status: EntityStatus;
509514
readonly subscriptionName: string;
510515
readonly topicName: string;
511-
userMetadata: string;
516+
userMetadata?: string;
512517
}
513518

514519
// @public

sdk/servicebus/service-bus/src/index.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ export { ServiceBusClientOptions } from "./constructorHelpers";
1212
export { CorrelationRuleFilter } from "./core/managementClient";
1313
export {
1414
CreateMessageBatchOptions,
15-
ServiceBusReceiverOptions,
16-
ServiceBusSessionReceiverOptions,
1715
GetMessageIteratorOptions,
1816
MessageHandlers,
19-
ProcessErrorArgs,
2017
PeekMessagesOptions,
18+
ProcessErrorArgs,
2119
ReceiveMessagesOptions,
20+
ServiceBusReceiverOptions,
21+
ServiceBusSessionReceiverOptions,
2222
SubscribeOptions
2323
} from "./models";
2424
export { OperationOptionsBase, TryAddOptions } from "./modelsToBeSharedWithEventHubs";
@@ -44,19 +44,19 @@ export {
4444
} from "./serializers/topicResourceSerializer";
4545
export {
4646
EntitiesResponse,
47-
WithResponse,
48-
ServiceBusAdministrationClient
47+
ServiceBusAdministrationClient,
48+
WithResponse
4949
} from "./serviceBusAtomManagementClient";
5050
export { ServiceBusClient } from "./serviceBusClient";
51+
export { isServiceBusError, ServiceBusError, ServiceBusErrorCode } from "./serviceBusError";
5152
export {
5253
DeadLetterOptions,
53-
ServiceBusReceivedMessage,
54-
ServiceBusMessage
54+
ServiceBusMessage,
55+
ServiceBusReceivedMessage
5556
} from "./serviceBusMessage";
5657
export { ServiceBusMessageBatch } from "./serviceBusMessageBatch";
57-
export { AuthorizationRule, EntityStatus, EntityAvailabilityStatus } from "./util/utils";
5858
export {
5959
parseServiceBusConnectionString,
6060
ServiceBusConnectionStringProperties
6161
} from "./util/connectionStringUtils";
62-
export { isServiceBusError, ServiceBusError, ServiceBusErrorCode } from "./serviceBusError";
62+
export { AuthorizationRule, EntityAvailabilityStatus, EntityStatus } from "./util/utils";

sdk/servicebus/service-bus/src/serializers/ruleResourceSerializer.ts

Lines changed: 80 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -157,79 +157,101 @@ export interface SqlRuleFilter {
157157
/**
158158
* @internal
159159
* @ignore
160-
* RuleResourceSerializer for serializing / deserializing Rule entities
160+
*
161+
* @interface InternalRuleOptions
161162
*/
162-
export class RuleResourceSerializer implements AtomXmlSerializer {
163-
serialize(rule: RuleProperties): object {
164-
const resource: { Name: any; Filter: any; Action: any } = {
165-
Filter: {},
166-
Action: {},
167-
Name: rule.name
168-
};
163+
export interface InternalRuleOptions {
164+
Name: string;
165+
Filter: any;
166+
Action: any;
167+
}
168+
169+
/**
170+
* @internal
171+
* @ignore
172+
*
173+
* @param {CreateRuleOptions} rule
174+
*/
175+
export function buildInternalRuleResource(rule: CreateRuleOptions): InternalRuleOptions {
176+
const resource: InternalRuleOptions = {
177+
Filter: {},
178+
Action: {},
179+
Name: rule.name
180+
};
169181

170-
if (rule.filter == undefined) {
171-
// Defaults to creating a true filter if none specified
182+
if (rule.filter == undefined) {
183+
// Defaults to creating a true filter if none specified
184+
resource.Filter = {
185+
SqlExpression: "1=1"
186+
};
187+
resource.Filter[Constants.XML_METADATA_MARKER] = {
188+
"p4:type": "SqlFilter",
189+
"xmlns:p4": "http://www.w3.org/2001/XMLSchema-instance"
190+
};
191+
} else {
192+
if (rule.filter.hasOwnProperty("sqlExpression")) {
193+
const sqlFilter: SqlRuleFilter = rule.filter as SqlRuleFilter;
172194
resource.Filter = {
173-
SqlExpression: "1=1"
195+
SqlExpression: sqlFilter.sqlExpression,
196+
Parameters: buildInternalRawKeyValuePairs(sqlFilter.sqlParameters, "sqlParameters")
174197
};
175198
resource.Filter[Constants.XML_METADATA_MARKER] = {
176199
"p4:type": "SqlFilter",
177200
"xmlns:p4": "http://www.w3.org/2001/XMLSchema-instance"
178201
};
179202
} else {
180-
if (rule.filter.hasOwnProperty("sqlExpression")) {
181-
const sqlFilter: SqlRuleFilter = rule.filter as SqlRuleFilter;
182-
resource.Filter = {
183-
SqlExpression: sqlFilter.sqlExpression,
184-
Parameters: buildInternalRawKeyValuePairs(sqlFilter.sqlParameters, "sqlParameters")
185-
};
186-
resource.Filter[Constants.XML_METADATA_MARKER] = {
187-
"p4:type": "SqlFilter",
188-
"xmlns:p4": "http://www.w3.org/2001/XMLSchema-instance"
189-
};
190-
} else {
191-
const correlationFilter: CorrelationRuleFilter = rule.filter as CorrelationRuleFilter;
192-
193-
resource.Filter = {
194-
CorrelationId: correlationFilter.correlationId,
195-
Label: correlationFilter.subject,
196-
To: correlationFilter.to,
197-
ReplyTo: correlationFilter.replyTo,
198-
ReplyToSessionId: correlationFilter.replyToSessionId,
199-
ContentType: correlationFilter.contentType,
200-
SessionId: correlationFilter.sessionId,
201-
MessageId: correlationFilter.messageId,
202-
Properties: buildInternalRawKeyValuePairs(
203-
correlationFilter.applicationProperties,
204-
"applicationProperties"
205-
)
206-
};
207-
resource.Filter[Constants.XML_METADATA_MARKER] = {
208-
"p4:type": "CorrelationFilter",
209-
"xmlns:p4": "http://www.w3.org/2001/XMLSchema-instance"
210-
};
211-
}
212-
}
203+
const correlationFilter: CorrelationRuleFilter = rule.filter as CorrelationRuleFilter;
213204

214-
if (rule.action == undefined || rule.action.sqlExpression == undefined) {
215-
// Defaults to creating an empty rule action instance if none specified
216-
resource.Action = {};
217-
resource.Action[Constants.XML_METADATA_MARKER] = {
218-
"p4:type": "EmptyRuleAction",
219-
"xmlns:p4": "http://www.w3.org/2001/XMLSchema-instance"
220-
};
221-
} else {
222-
resource.Action = {
223-
SqlExpression: rule.action.sqlExpression,
224-
Parameters: buildInternalRawKeyValuePairs(rule.action.sqlParameters, "sqlParameters")
205+
resource.Filter = {
206+
CorrelationId: correlationFilter.correlationId,
207+
Label: correlationFilter.subject,
208+
To: correlationFilter.to,
209+
ReplyTo: correlationFilter.replyTo,
210+
ReplyToSessionId: correlationFilter.replyToSessionId,
211+
ContentType: correlationFilter.contentType,
212+
SessionId: correlationFilter.sessionId,
213+
MessageId: correlationFilter.messageId,
214+
Properties: buildInternalRawKeyValuePairs(
215+
correlationFilter.applicationProperties,
216+
"applicationProperties"
217+
)
225218
};
226-
resource.Action[Constants.XML_METADATA_MARKER] = {
227-
"p4:type": "SqlRuleAction",
219+
resource.Filter[Constants.XML_METADATA_MARKER] = {
220+
"p4:type": "CorrelationFilter",
228221
"xmlns:p4": "http://www.w3.org/2001/XMLSchema-instance"
229222
};
230223
}
224+
}
225+
226+
if (rule.action == undefined || rule.action.sqlExpression == undefined) {
227+
// Defaults to creating an empty rule action instance if none specified
228+
resource.Action = {};
229+
resource.Action[Constants.XML_METADATA_MARKER] = {
230+
"p4:type": "EmptyRuleAction",
231+
"xmlns:p4": "http://www.w3.org/2001/XMLSchema-instance"
232+
};
233+
} else {
234+
resource.Action = {
235+
SqlExpression: rule.action.sqlExpression,
236+
Parameters: buildInternalRawKeyValuePairs(rule.action.sqlParameters, "sqlParameters")
237+
};
238+
resource.Action[Constants.XML_METADATA_MARKER] = {
239+
"p4:type": "SqlRuleAction",
240+
"xmlns:p4": "http://www.w3.org/2001/XMLSchema-instance"
241+
};
242+
}
243+
244+
return resource;
245+
}
231246

232-
return serializeToAtomXmlRequest("RuleDescription", resource);
247+
/**
248+
* @internal
249+
* @ignore
250+
* RuleResourceSerializer for serializing / deserializing Rule entities
251+
*/
252+
export class RuleResourceSerializer implements AtomXmlSerializer {
253+
serialize(rule: RuleProperties): object {
254+
return serializeToAtomXmlRequest("RuleDescription", buildInternalRuleResource(rule));
233255
}
234256

235257
async deserialize(response: HttpOperationResponse): Promise<HttpOperationResponse> {

sdk/servicebus/service-bus/src/serializers/subscriptionResourceSerializer.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license.
33

44
import { HttpOperationResponse, OperationOptions } from "@azure/core-http";
5+
import { CorrelationRuleFilter } from "..";
56
import {
67
AtomXmlSerializer,
78
deserializeAtomXmlResponse,
@@ -18,6 +19,12 @@ import {
1819
getStringOrUndefined,
1920
getDate
2021
} from "../util/utils";
22+
import {
23+
buildInternalRuleResource,
24+
InternalRuleOptions,
25+
SqlRuleAction,
26+
SqlRuleFilter
27+
} from "./ruleResourceSerializer";
2128

2229
/**
2330
* @internal
@@ -40,6 +47,9 @@ export function buildSubscriptionOptions(
4047
DeadLetteringOnFilterEvaluationExceptions: getStringOrUndefined(
4148
subscription.deadLetteringOnFilterEvaluationExceptions
4249
),
50+
DefaultRuleDescription: subscription.defaultRuleOptions
51+
? buildInternalRuleResource(subscription.defaultRuleOptions)
52+
: undefined,
4353
MaxDeliveryCount: getStringOrUndefined(subscription.maxDeliveryCount),
4454
EnableBatchedOperations: getStringOrUndefined(subscription.enableBatchedOperations),
4555
Status: getStringOrUndefined(subscription.status),
@@ -178,6 +188,30 @@ export interface CreateSubscriptionOptions extends OperationOptions {
178188
*/
179189
deadLetteringOnFilterEvaluationExceptions?: boolean;
180190

191+
/**
192+
* Represents the options to create the default rule for the subscription.
193+
*/
194+
defaultRuleOptions?: {
195+
/**
196+
* Name of the rule
197+
*/
198+
name: string;
199+
200+
/**
201+
* Defines the filter expression that the rule evaluates. For `SqlRuleFilter` input,
202+
* the expression string is interpreted as a SQL92 expression which must
203+
* evaluate to True or False. Only one between a `CorrelationRuleFilter` or
204+
* a `SqlRuleFilter` can be defined.
205+
*/
206+
filter?: SqlRuleFilter | CorrelationRuleFilter;
207+
208+
/**
209+
* The SQL like expression that can be executed on the message should the
210+
* associated filter apply.
211+
*/
212+
action?: SqlRuleAction;
213+
};
214+
181215
/**
182216
* The maximum delivery count of messages after which if it is still not settled,
183217
* gets moved to the dead-letter sub-queue.
@@ -327,7 +361,7 @@ export interface SubscriptionProperties {
327361
* Used to specify textual content such as tags, labels, etc.
328362
* Value must not exceed 1024 bytes encoded in utf-8.
329363
*/
330-
userMetadata: string;
364+
userMetadata?: string;
331365

332366
/**
333367
* Absolute URL or the name of the queue or topic the dead-lettered
@@ -458,6 +492,8 @@ export interface InternalSubscriptionOptions {
458492
* Availability status of the messaging entity.
459493
*/
460494
EntityAvailabilityStatus?: string;
495+
496+
DefaultRuleDescription?: InternalRuleOptions;
461497
}
462498

463499
/**

sdk/servicebus/service-bus/src/util/constants.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,6 @@ export const ENABLE_SUBSCRIPTION_PARTITIONING = "EnableSubscriptionPartitioning"
120120
*/
121121
export const FILTER_MESSAGES_BEFORE_PUBLISHING = "FilteringMessagesBeforePublishing";
122122

123-
/**
124-
* Indicates the default rule description.
125-
*
126-
* @internal
127-
* @ignore
128-
*/
129-
export const DEFAULT_RULE_DESCRIPTION = "DefaultRuleDescription";
130-
131123
/**
132124
* The entity's size in bytes.
133125
*

0 commit comments

Comments
 (0)