-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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] Filling the gaps for AmqpAnnotatedMessage #14786
Changes from all commits
1889176
e26cab7
af37a7b
dcd7a10
2f3cf88
cd9a69d
4f016bb
43793b1
4eedc8d
d14dbf3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
import chai from "chai"; | ||
import chaiAsPromised from "chai-as-promised"; | ||
import { ServiceBusSender } from "../../src"; | ||
import { ServiceBusReceiver } from "../../src/receivers/receiver"; | ||
import { | ||
ServiceBusClientForTests, | ||
createServiceBusClientForTests, | ||
testPeekMsgsLength, | ||
EntityName, | ||
getRandomTestClientType | ||
} from "../public/utils/testutils2"; | ||
import { AmqpAnnotatedMessage } from "@azure/core-amqp"; | ||
import { generateUuid } from "@azure/core-http"; | ||
|
||
const should = chai.should(); | ||
chai.use(chaiAsPromised); | ||
const assert = chai.assert; | ||
|
||
const anyRandomTestClientType = getRandomTestClientType(); | ||
|
||
let serviceBusClient: ServiceBusClientForTests; | ||
let entityNames: EntityName; | ||
let sender: ServiceBusSender; | ||
let receiver: ServiceBusReceiver; | ||
const sessionId = "session-1"; | ||
|
||
function afterEachTest(): Promise<void> { | ||
return serviceBusClient.test.afterEach(); | ||
} | ||
|
||
function getSampleAmqpAnnotatedMessage(randomTag?: string): AmqpAnnotatedMessage { | ||
if (randomTag == null) { | ||
randomTag = Math.random().toString(); | ||
} | ||
|
||
return { | ||
body: `message body ${randomTag}`, | ||
bodyType: "data", | ||
header: { | ||
deliveryCount: 10, // TODO: Doesn't make sense to set on the message to be sent, should this be removed for sending? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove deliveryCount from the AmqpAnnotatedMessage for send side? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm....this is an interesting problem we don't have with ServiceBusMessage, now that I think about it, since we make a distinction between a sendable message and a received message. For now I'd say it's fine. A received AmqpAnnotatedMessage should also be immediately sendable so it should work, and we can just do a quick check to make sure that we aren't in some way dependent on those fields. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @JoshLove-msft @yunhaoling @hemanttanwar what are you guys doing here? |
||
durable: false, | ||
firstAcquirer: false, | ||
priority: 20, | ||
timeToLive: 100000 | ||
}, | ||
applicationProperties: { | ||
propOne: 1, | ||
propTwo: "two", | ||
propThree: true, | ||
propFour: Date() | ||
}, | ||
// deliveryAnnotations - TODO: should this be removed for sending? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove deliveryAnnotations from the AmqpAnnotatedMessage for send side? |
||
footer: { | ||
propFooter: "foot" | ||
}, | ||
messageAnnotations: { propMsgAnnotate: "annotation" }, | ||
properties: { | ||
contentEncoding: "application/json; charset=utf-8", | ||
correlationId: randomTag, | ||
messageId: generateUuid() | ||
} | ||
}; | ||
} | ||
|
||
describe("AmqpAnnotatedMessage", function(): void { | ||
before(() => { | ||
serviceBusClient = createServiceBusClientForTests(); | ||
}); | ||
|
||
after(() => { | ||
return serviceBusClient.test.after(); | ||
}); | ||
|
||
afterEach(async () => { | ||
await afterEachTest(); | ||
}); | ||
|
||
async function receiveMsg(testMessage: AmqpAnnotatedMessage) { | ||
receiver = await serviceBusClient.test.createReceiveAndDeleteReceiver({ | ||
...entityNames, | ||
sessionId | ||
}); | ||
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, testMessage.body, "Unexpected body on the received message"); | ||
should.equal( | ||
msgs[0]._rawAmqpMessage.messageAnnotations!["propMsgAnnotate"], | ||
testMessage.messageAnnotations!["propMsgAnnotate"], | ||
"Unexpected messageAnnotations on the received message" | ||
); | ||
assert.deepEqualExcluding( | ||
msgs[0]._rawAmqpMessage, | ||
testMessage, | ||
["deliveryAnnotations", "body", "messageAnnotations", "header", "properties"], | ||
"Unexpected on the AmqpAnnotatedMessage" | ||
); | ||
assert.deepEqualExcluding( | ||
msgs[0]._rawAmqpMessage.header!, | ||
testMessage.header!, | ||
["deliveryCount"], | ||
"Unexpected header on the AmqpAnnotatedMessage" | ||
); | ||
assert.deepEqualExcluding( | ||
msgs[0]._rawAmqpMessage.properties!, | ||
testMessage.properties!, | ||
["creationTime", "absoluteExpiryTime", "groupId"], | ||
"Unexpected properties on the AmqpAnnotatedMessage" | ||
); | ||
assert.equal( | ||
msgs[0]._rawAmqpMessage.properties!.groupId, | ||
testMessage.properties!.groupId, | ||
"Unexpected session-id on the AmqpAnnotatedMessage" | ||
); | ||
} | ||
|
||
it( | ||
anyRandomTestClientType + ": send, receive, verify props, and complete()", | ||
async function(): Promise<void> { | ||
entityNames = await serviceBusClient.test.createTestEntities(anyRandomTestClientType); | ||
|
||
const testMessage: AmqpAnnotatedMessage = getSampleAmqpAnnotatedMessage(); | ||
testMessage.properties = { | ||
...testMessage.properties, | ||
groupId: entityNames.usesSessions ? sessionId : undefined | ||
}; | ||
sender = serviceBusClient.test.addToCleanup( | ||
serviceBusClient.createSender(entityNames.queue ?? entityNames.topic!) | ||
); | ||
await sender.sendMessages(testMessage); | ||
await receiveMsg(testMessage); | ||
|
||
await testPeekMsgsLength(receiver, 0); | ||
} | ||
); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have custom logic for absolute_expiry_time for ServiceBusMessage
...we should do the same for AmqpAnnotatedMessage? (.NET has the same logic too!)
@JoshLove-msft
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pinging @yunhaoling @hemanttanwar to make sure the same logic is present in Java/Python too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't have this in python, for service bus message (and annotated message), we don't calculate
absolute_expiry_time
based onttl
.two questions:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gets applied to every message that is being sent(during the translation of SBMessage to the internal AMQP message).
Not from the spec, service-bus service has a bug that required us to add this(/cc @JoshLove-msft). Clemens is also involved here, it's better to reach out to him and get approval if we're changing anything here.
For JS especially,