Repository navigation
Replies: 2 comments
TriageVerdict: this is a reproducible bug in Is this a misuse of humus?No. The end user writes The end user did what the docs ask. The package doc says "Who a message came from is best told by its UserID", and its example trusts "the end user's own services, which connect as the user orders-api" ( The strongest argument for misuse is that the end user can trust something else. Is it a feature request?No. It contradicts what humus promises:
Together they promise that a scenario can go from one of the end user's services to the next over RabbitMQ, trusted by The gap is between two proposals. #765 gave Any fix changes the API. A Is it reproducible?Yes. I wrote three container tests that extend
A job's
A
RabbitMQ's half. A message published with amqp091 and no One claim of the report is too strong. "Forwarding a scenario over RabbitMQ between humus services never works" holds for a consumer that trusts by Why
So the No test reached this. The unit tests' stand-in implements no part of AMQP. #938's container test publishes with amqp091 and sets the #960 is filed to fix it:
|
|
Fixed in #962, merged as 41e53e2.
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
What happens
A
queue/rabbitmqPublishercan't set a message'suser-id. So every message a humus service publishes arrives with an emptyMessage.UserID, and a consumer whoseTrustScenariotrusts byUserID, as the package doc and the Failure injection page recommend, strips every failure scenario a humus service publishes or forwards.PublisherSettings.ForwardScenariostill puts the scenario in the message'sbaggageheader. No consumer can trust it, though, so forwarding a scenario over RabbitMQ between humus services never works.The docs' own example shows it. It trusts "the end user's own services, which connect as
orders-api", withm.UserID == "orders-api". Iforders-apiis a humus service, none of its messages carry auser-id, so that func trusts none of them.Why
rabbitmq.Publishinghas no field for AMQP'suser-idproperty (publisher.go#L42-L91), and its conversion to amqp091'sPublishingsets noUserId(publisher.go#L96-L118).TrustScenariowith the delivery'sMessage(faults.go#L34-L44), whoseUserIDis the delivery'suser-id(message.go#L68-L69).user-idonly when a publisher sets it. A message without one is accepted with none.How it was found
While prototyping the RabbitMQ processor walkthrough, against RabbitMQ 4.3.6 in a container. A humus App ran
rabbitmq.NewServicewith aTrustScenarioofm.UserID == <the test's login>, underhumus.WithFaultsandjsonscenario. Its Processor republished each delivery with aPublisherwhoseForwardScenariowas set.UserIdset to the trusted login, reachedProcesswith its scenario.Publisher's copy of it carried the scenario in itsbaggageheader, but arrived with an emptyUserID, so the Service stripped it.Neither the unit tests nor the container tests publish with a humus
Publisherto a Service that trusts byUserID, so they don't reach this.The docs
doc.go#L732-L744) and the Failure injection page's RabbitMQ:UserIDrecommend trusting byUserID, with the end user's own services as the example. That holds only for publishers that aren't humus services.Expected
A humus
Publishercan publish a message whoseuser-idRabbitMQ validates against the Publisher's login. A consumer can then trust what a humus service publishes and forwards. Some ways to get there:UserIDfield onPublishing, passed through as amqp091'sUserId. A publish whoseuser-idisn't the connection's user is refused by RabbitMQ, which the Publisher reports as a failure that isn't retried;Publisherthat sets every message'suser-idto the user it logged in as. That needs no new field, but a Publisher that logs in with a client certificate, through amqp091'sExternalAuth, doesn't know its user's name.Either way:
Publisher's message, with its scenario forwarded, trusted by a Service'sTrustScenarioonUserID;user-id.The fix adds to
queue/rabbitmq's API. It changes nothing for a message published without auser-id,TrustScenario's default, or the Publisher's retries for other failures.References
All reactions