Stream: subscriptions
Topic: Argonaut call is on!
Josh Mandel (Dec 11 2019 at 18:06):
Argonaut subscriptions call is on! (http://bit.ly/argo19-subscriptions has links/notes)
Gino Canessa (Dec 11 2019 at 20:38):
For those on the call (or otherwise interested), the branch build finished. Here are the links to the current Subscription and SubscriptionTopic.
Please keep in mind they are WIP (pushed at time to attempt to have them for the call), but any and all feedback is greatly appreciated.
Isaac Vetter (Dec 17 2019 at 22:55):
Hey Gino, I really like your WIP! I'm closely reading through it. Let me know if you'd prefer these comments as jira issues.
Isaac Vetter (Dec 17 2019 at 22:56):
Do these two sentences contradict one another?
Subscription resources are not intended to be secure storage for secrets (e.g., OAuth Client ID or Tokens, etc.). Implementers MAY use their judgement on including limited-use secrets (e.g., a token supplied in Subscription.channel.header to verify that a message is from the desired source).
Further, you're effectively mandating that FHIR servers aren't able to decide if this is a feature they want to support, through this statement. FHIR Servers should be empowered to not support storing credentials in a Subscription resource (because it's poor practice and probably shouldn't be done at all).
Each channel.header value SHALL be conveyed as an HTTP request header.
Isaac Vetter (Dec 17 2019 at 23:02):
The subscriber then initiates a Web Socket connection to the server, at a URL advertised in the FHIR server's Capability statement (subscriptions/webSocketUrl (todo)). A simple protocol is used to listen for notifications:
FHIRcast followed DICOMWeb here by returning the wss url in the Content-Location HTTP header of the response to a subscription request. (See PR). Note that this also enables the "ticketing" security approach, which also provides a mechanism for addressing the limited number of connection per wss url.
Gino Canessa (Dec 17 2019 at 23:04):
Thanks Isaac - that's exactly why I post them!
That wasn't the intention, so I need to rework it.
The language was supposed to call out that the Subscription resource (by default) is just like any other resource, so we don't want people assuming secrets are fine there (e.g., everyone who has access to the subscription resources can then impersonate the server to various third parties). If servers DO want to implement secure storage, allow for limited-use secrets, or even just assume/pretend it's fine, that is up to them.
Isaac Vetter (Dec 17 2019 at 23:06):
Is Handshake required to be supported by servers?
There's no SHALL at https://build.fhir.org/subscription.html#handshake-notification, bu reading http://build.fhir.org/branches/argonaut-subscription/subscription.html#errors, it seems like a server is required to go through the requested -> active status change.
Isaac Vetter (Dec 17 2019 at 23:07):
Is this:
Servers implementing Subscriptions are responsible for complying with their policies on information logging.
a sentence useful to implementers?
Gino Canessa (Dec 17 2019 at 23:08):
For websockets, we're playing with that and some variations. I haven't fleshed out the docs more on it yet, but there are some modifications being considered as well (e.g., can a single wss connection register multiple subscriptions).
One thought is a generic endpoint, and using client messages to auth each subscription. This gives the benefit that auth can be renewed/expired in the same session.
Josh Mandel (Dec 17 2019 at 23:08):
Re: content-location
response headers, this is nice if the request is a websub request... but for a POST Subscription
or PUT Subscription/:id
request, does:
"Content-Location indicates the direct URL to use to access the resource, without further content negotiation in the future"
(from MDN docs) fit the bill?
Isaac Vetter (Dec 17 2019 at 23:09):
Message Types.
You've defined 5 different message types (Empty Notification, id-only Notification, full Notification, Heartbeat, Handshake) with distinct meanings and purposes; yet a subscriber is required to decipher the contents of the notification's subscription-event-count
in order to determine what type they're receiving. It would be a lot cleaner to simply have another extension of notificationType, with the following values: Notification, Handshake, heartbeat
Note that in your well-written examples, you've used the Bundle.id as a shorthand for your own convenience, to do exactly this.
Josh Mandel (Dec 17 2019 at 23:10):
I feel like it's a little bit off; might think about modeling a web socket URL as a property of SubscriptionStatus
, or a bunch of other options Gino's looking intto.
Gino Canessa (Dec 17 2019 at 23:10):
I believe the Handshake was left as optional for servers, but clients need to support/ignore it (same with Heartbeat messages). I'll go through my notes to check and make sure it's clearer in the docs.
Gino Canessa (Dec 17 2019 at 23:13):
Message Types.
You've defined 5 different message types (Empty Notification, id-only Notification, full Notification, Heartbeat, Handshake) with distinct meanings and purposes; yet a subscriber is required to decipher the contents of the notification's
subscription-event-count
in order to determine what type they're receiving. It would be a lot cleaner to simply have another extension of notificationType, with the following values: Notification, Handshake, heartbeatNote that in your well-written examples, you've used the Bundle.id as a shorthand for your own convenience, to do exactly this.
I like this. Part of the issue was the number of extensions we were creating, but since we're breaking all those fields out into a new resource (I believe SubscriptionStatus
is winning), it isn't so bad.
Isaac Vetter (Dec 17 2019 at 23:13):
<retracted> Gino'd already fixed this! My oversight.
Gino Canessa (Dec 17 2019 at 23:13):
In particular, by setting the type to heartbeat
or handshake
, various fields can be left out entirely without worry.
Isaac Vetter (Dec 17 2019 at 23:15):
email: Notifications are sent via SMTP/S, S/MIME, or Direct to the Subscription.channel.endpoint email URI (e.g., mailto:...)
Note that Direct supports two comm protocols: SMTP and IHE XDR (which is SOAP+ebXML+IHE). Do you intend for XDR to be a supported messaging
channel within email
? I don't think that you do. You should clarify for Direct over SMTP to be supported and not Direct over IHE XDR/XDM.
Gino Canessa (Dec 17 2019 at 23:17):
- You should clarify for handshake (just as you do for heartbeat) that handshake doesn't "incrementing the subscription event count."
Hmm.. I thought it did, but it looks like it got missed. Good catch!
- I'm still not 100% certain if a notification's
subscription-event-count
should be incremented to account for entries included in that notification.
OK, needs more clarification. The relevant part there is in 2.46.6.4:
The subscription-event-count extension indicates the number of unique events that have triggered notification attempts on this Subscription PRIOR to the current notification being sent.
Isaac Vetter (Dec 17 2019 at 23:20):
Gino - my bad, you're right! I'd written that feedback against the build.fhir.org version and missed that you'd already updated it. Great work!
Isaac Vetter (Dec 17 2019 at 23:20):
I'd encourage you to explain the rationale for including eventCount
in the Subscription resource, as well as the notification, in the new "Managing Subscriptions and Error" section. (e.g. a client may query the subscription resource to validate that it has/has not missed a notification ... ).
Isaac Vetter (Dec 17 2019 at 23:22):
Relation to FHIRcast
Would you consider adding an additional bullet like this:
- FHIRcast synchronizes a user's session by communicating that a UI event occurred, such as a patient chart being opened or closed. Subscriptions communicates clinical or business events or changes in data, such as a patient admit.
FHIRcast is a HTTP-based framework
We're adding websocket support in February, so HTTP isn't entirely accurate.
FHIRcast is designed to be used by multiple applications on the same device. Subscriptions are designed to be used by multiple distinct systems
What about something like this:
FHIRcast is designed to be used by multiple applications perhaps with the same user and typically on the same device. Subscriptions are designed to be used by multiple distinct systems, often outside of a workflow.
Isaac Vetter (Dec 17 2019 at 23:24):
Typos
will result in higher computational costs on the server (e.g., processing queries when there are no state changes).
I don't think you should say "will result in", I think that "may result in" would be correct.
Three misspellings:
- Sercurity
- notificaiton
- alwayhs
Gino Canessa (Dec 17 2019 at 23:29):
re: FHIRCast, sounds good to me. My goal is to clearly convey what's the same and what's different so that people know which tool is better for their use. If there's anything additional that could be useful to include there, please let me know - my understanding of FHIRCast is based on reading the specs as I worked on various presentations =)
Gino Canessa (Dec 17 2019 at 23:36):
blah, why doesn't VS code spell check my random text in XML docs?
Isaac Vetter (Dec 18 2019 at 17:49):
Gino, the example for SubscriptionTopic describes using Group as a filter in the documentation element, but there isn't actually a corresponding canFilterBy:
"documentation": "Matching based on the Patient (subject) of an Encounter ."
Is something like this correct?
"canFilterBy": [ { "searchParamName": "patient", "matchType": [ "=", "in", "not-in" ], "documentation": "Matching based on the Patient's group membership (in/not-in)." }, { "searchParamName": "group", "matchType": [ "in", "not-in" ], "documentation": "Matching based on the Patient (subject) of an Encounter or based on the Patient's group membership (in/not-in)." } ]
Gino Canessa (Dec 18 2019 at 18:10):
The version on the site works because of R5 changes to the :in
modifier per J#22690 . I don't think it's been completed, but it was approved and we built up the examples and reference implementation assuming it.
The issue with what you propose is that it requires implicit knowledge on mapping Encounter.subject (when Patient) as the member of a Group. One of the goals was to make these work generically (e.g., computably defined SubscriptionTopics can be added to a server which supports them).
On the flip side, discussions around this were wary of allowing too much in the filters, since they should be lightweight (more complex interactions can be covered in SubscriptionTopics).
Thoughts?
Isaac Vetter (Dec 18 2019 at 18:30):
discussions around this were wary of allowing too much in the filters, since they should be lightweight (more complex interactions can be covered in SubscriptionTopics).
Makes sense, Gino. What would a SubscriptionTopic for an admission on a patient who belonged to a group look like?
Gino Canessa (Dec 18 2019 at 20:12):
Hmm.. good point. I'll have to think on this a bit.
Gino Canessa (Dec 18 2019 at 21:03):
Ok, got my head straight now. First, definitely need better documentation around this :grinning:
Moving on, the field searchParamName
was renamed from name
, but after discussions here I'm thinking about changing it again (sigh) to searchParameter
since that is much clearer about what it is.
To use your example of searching for group membership before/without :in
:
"canFilterBy": [ { "searchParamName": "patient", "matchType": [ "=", ], "documentation": "Matching based on 'patient' reference (Encounter.subject, where subject is of type Patient)." }, { "searchParamName": "patient._has:Group:member:_id", "matchType": [ "=", ], "documentation": "Matching based on the 'patient' reference existing in a group by unique id." } ]
Essentially, searchParamName
is the left-hand-side of a search KVP. So, you could also have values like patient.birthdate
, patient.name
, etc. The Group membership query looked particularly ugly, which is why we asked for the :in
modifier changes in J#22690 (and people wanted to support it without worrying about generic_has
support).
To clean up from what I was commenting on earlier - implementers wanted to reuse search tooling, but not be committed to things like _include
or complicated and/or queries.
Does that make sense?
Grahame Grieve (Dec 19 2019 at 21:09):
an aside: https://www.tbray.org/ongoing/When/201x/2019/12/18/Content-based-filtering - Don't know if there are any lessons for us there
Gino Canessa (Dec 19 2019 at 21:55):
an aside: https://www.tbray.org/ongoing/When/201x/2019/12/18/Content-based-filtering - Don't know if there are any lessons for us there
That's interesting. If I'm reading correctly, the argument is that basing the filtering off the output format decouples it from the source events. Makes the filtering more generic, but requires servers to change where they do it (e.g., generate the output for the event, then filter). Novel.
In general, we have tried to avoid adding another type of search/filter language into FHIR though.
Grahame Grieve (Dec 19 2019 at 22:01):
out is related to source events of course. And there's benefit in filtering based on things you don't see.
Gino Canessa (Dec 19 2019 at 22:03):
Yep. I do like how it changes the conversation into events in isolation and what can be done in that context.
Nobody would suggest searching a data store based on evaluated JSON object comparisons, but if you are only looking at one event it's possible.
Last updated: Apr 12 2022 at 19:14 UTC