Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Service Bus] Bug Fix: Correlation Rule Filter with the "label" doesn't filter the messages #13069

Merged
15 commits merged into from
Jan 7, 2021
Merged
2 changes: 2 additions & 0 deletions sdk/servicebus/service-bus/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
- Updates documentation for `ServiceBusMessage` to call out that the `body` field
must be converted to a byte array or `Buffer` when cross-language
compatibility while receiving events is required.
- [Bug Fix] Correlation Rule Filter with the "label" set using the `createRule()` method doesn't filter the messages to the subscription.
The bug has been fixed in [PR 13069](https://github.com/Azure/azure-sdk-for-js/pull/13069), also fixes the related issues where the messages are not filtered when a subset of properties are set in the correlation filter.

## 7.0.0 (2020-11-23)

Expand Down
52 changes: 43 additions & 9 deletions sdk/servicebus/service-bus/src/util/atomXmlHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,47 @@ export async function executeAtomXmlOperation(
return serializer.deserialize(response);
}

/**
* This helper method returns true if an object is JSON, returns false otherwise.
*/
export function isJSONObject(value: any): boolean {
// `value.constructor === {}.constructor` differentiates among the "object"s,
// would filter the JSON objects and won't match any array or other kinds of objects

// -------------------------------------------------------------------------------
// Few examples | typeof obj ==="object" | obj.constructor==={}.constructor
// -------------------------------------------------------------------------------
// {abc:1} | true | true
// ["a","b"] | true | false
// [{"a":1},{"b":2}] | true | false
// new Date() | true | false
// 123 | false | false
// -------------------------------------------------------------------------------
return typeof value === "object" && value.constructor === {}.constructor;
}

/**
* @internal
* @hidden
* The key-value pairs having undefined/null as the values would lead to the empty tags in the serialized XML request.
* Empty tags in the request body is problematic because of the following reasons.
* - ATOM based management operations throw a "Bad Request" error if empty tags are included in the XML request body at top level.
* - At the inner levels, Service assigns the empty strings as values to the empty tags instead of throwing an error.
*
* This method recursively removes the key-value pairs with undefined/null as the values from the request object that is to be serialized.
*
* @param {{ [key: string]: any }} resource
*/
export function sanitizeSerializableObject(resource: { [key: string]: any }) {
Object.keys(resource).forEach(function(property) {
if (resource[property] == undefined) {
delete resource[property];
} else if (isJSONObject(resource[property])) {
sanitizeSerializableObject(resource[property]);
}
});
}

/**
* @internal
* @hidden
Expand All @@ -103,15 +144,8 @@ export async function executeAtomXmlOperation(
export function serializeToAtomXmlRequest(resourceName: string, resource: any): object {
const content: any = {};

// The top level key value pairs having undefined/null as the value are removed in order to address issue where the Service Bus'
// ATOM based management operations throw a "Bad Request" error if empty tags are included in the xml request body at top level.
const processedResource = Object.assign({}, resource);
Object.keys(processedResource).forEach(function(property) {
if (processedResource[property] == undefined) {
delete processedResource[property];
}
});
content[resourceName] = processedResource;
content[resourceName] = Object.assign({}, resource);
sanitizeSerializableObject(content[resourceName]);

content[resourceName][Constants.XML_METADATA_MARKER] = {
xmlns: "http://schemas.microsoft.com/netservices/2010/10/servicebus/connect",
Expand Down
Loading