Stream: hapi
Topic: general auditevent generator
Jens Villadsen (Jul 30 2019 at 07:49):
Has anyone in the HAPI community done some of the grunt interceptor code work publicly that generates proper auditevents when poking the HAPI FHIR server?
Grahame Grieve (Jul 30 2019 at 07:50):
I've done it in my server. It's similar logic, but I haven't done it in HAPI. Is that at all relevant?
Jens Villadsen (Jul 30 2019 at 07:52):
yes, hence the question. Besides being able to generate an audit log, I ( and maybe others) are in the need to runtime send an audit log to national services
Grahame Grieve (Jul 30 2019 at 07:53):
right. So if the question is about the HAPI integration part, anything I did on my server is irrelevant. but if it's about the auditevent side, then the logic is basically the same...
Jens Villadsen (Jul 30 2019 at 07:53):
I found https://github.com/nhsconnect/careconnect-reference-implementation/blob/020665c5216ae614402f46d7f01bce9228d231e5/cc-core/src/main/java/uk/org/hl7/fhir/core/Stu3/CareConnectAuditEvent.java and https://github.com/jamesagnew/hapi-fhir/blob/f7029b9a0f91da772499a8cbdba4ee8f8994dd10/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/interceptor/AuditingInterceptor.java in where I may find inspiration
Jens Villadsen (Jul 30 2019 at 07:53):
Its the auditevent generation on the server side I'm fishing for
Grahame Grieve (Jul 30 2019 at 07:54):
which vesrion?
Jens Villadsen (Jul 30 2019 at 07:54):
STU3
Grahame Grieve (Jul 30 2019 at 07:55):
https://github.com/grahamegrieve/fhirserver/blob/master/Server/FHIR.Server.OperationsR3.pas#L599 - different language and server framework, but the logic should be similar and applicable
Jens Villadsen (Jul 30 2019 at 07:55):
I believe @Kevin Mayfield is the author of one of those
Grahame Grieve (Jul 30 2019 at 07:58):
some parameters to that call:
- session - links to information about the client and any authentication provided
- intreqid - intrernal unique id for the request
- extreqid - client provided id using the relevant X- header
- ip - IP of the client (not sure what that doesn't come from the session)
Jens Villadsen (Jul 30 2019 at 07:58):
@Grahame Grieve something like that, yes. Now that function/method is some 140 lines ... including testcode that probably would accumulate to some 500-1000 lines that I wondered if already existed in some other project that I could use
Grahame Grieve (Jul 30 2019 at 07:59):
I don't know of any. Just trying to help here ;-)
Jens Villadsen (Jul 30 2019 at 07:59):
I know
Jens Villadsen (Jul 30 2019 at 07:59):
And its appreciated
Jens Villadsen (Jul 30 2019 at 07:59):
But as most developers of nature, I'm lazy
Jens Villadsen (Jul 30 2019 at 08:00):
and want quality at the same time
Grahame Grieve (Jul 30 2019 at 08:00):
naturally
Jens Villadsen (Jul 30 2019 at 08:01):
I'll guess I'll have to do a (non-existing) brush up on my Delphi ;)
Grahame Grieve (Jul 30 2019 at 08:03):
not a lot of deep pascal knowledge required there; most of your questions will be about the implied knowledge of the server framework, not the langauge. ask away....
Jens Villadsen (Jul 30 2019 at 08:08):
Yep ... I'll let you know
Kevin Mayfield (Jul 30 2019 at 08:16):
We didn't finish that code. We put in a stub (best guess) to form a basis for future work.
Jens Villadsen (Jul 30 2019 at 08:18):
@Kevin Mayfield I had a feeling of that. I couldn't find much coverage of it neither. And the "System.out.println(operationOutcome.getIssue().get(0).getCode());" gave it away
Jens Villadsen (Jul 30 2019 at 08:21):
@Grahame Grieve how does one select among http://build.fhir.org/valueset-audit-event-action.html - more specifically R vs. E. Isn't it sort of expected that information that is searched for ('E') is also read ('R')?
Kevin Mayfield (Jul 30 2019 at 08:21):
:) we intended to build AuditEvent on top of the logs in elastic.
Jens Villadsen (Jul 30 2019 at 08:25):
@Kevin Mayfield interesting. Do you intend to store it separately afterwards?
Grahame Grieve (Jul 30 2019 at 09:57):
I don’t recall, and don’t have the code in front of me right now. but search is read, for me, usually.
Grahame Grieve (Jul 30 2019 at 09:57):
Execute is a $operation
Jens Villadsen (Jul 30 2019 at 11:04):
pasted image @Grahame Grieve
Jens Villadsen (Jul 30 2019 at 11:04):
query/search => E
Jens Villadsen (Jul 30 2019 at 11:07):
May I suggest that the sentence is then rephrased
Jens Villadsen (Jul 30 2019 at 11:07):
to omit the query/search thingy
Grahame Grieve (Jul 30 2019 at 11:34):
make a task for... Security, I think (@John Moehrke)
John Moehrke (Jul 30 2019 at 18:38):
which way are we wanting? I see the spec today as saying that a query is an action == execute... this is what the text, codes, and examples say... right?
Grahame Grieve (Jul 30 2019 at 19:31):
@John Moehrke - we don't agree. FHIR Search is primarily a wide spread read, not an execute.
John Moehrke (Jul 30 2019 at 19:33):
okay. I can understand that. It was just not clear in the zulip discussion thread what the conclusion was.. So the CR would switch all mentions (narrative, model, codes, and examples).
Grahame Grieve (Jul 30 2019 at 19:35):
yes. though it might switch examples to actual execute examples
John Moehrke (Jul 30 2019 at 19:36):
yes we need an execute example... likely one of the many operations we now have. Right?
John Moehrke (Jul 30 2019 at 19:36):
I can bring in the audit example from IHE PIXm, which is an operation
Grahame Grieve (Jul 30 2019 at 19:37):
yes, any $operation is clearly an execute
John Moehrke (Jul 30 2019 at 19:44):
The difficulty we do need to deal with is that AuditEvent is derived from DICOM AuditMessage, which defined these vocabulary. In that specification they do describe query as a form of execute -- http://dicom.nema.org/medical/dicom/current/output/html/part15.html#sect_A.5.3.10
Grahame Grieve (Jul 30 2019 at 19:46):
FHIR search is not query. I think that's the difference. We should be able to clarify that. a _query (or the mpi operation) can be called a query. See http://hl7.org/fhir/search.html#query
John Moehrke (Jul 30 2019 at 19:49):
I am missing some elegant difference you imply between query and search...
John Moehrke (Jul 30 2019 at 19:51):
I think we should move this discussion to a broader stream than HAPI
Grahame Grieve (Jul 30 2019 at 19:51):
sure
Jens Villadsen (Jul 30 2019 at 19:59):
Wow ... Had forgot about the query param
Jens Villadsen (Jul 30 2019 at 21:28):
@John Moehrke let me know where you move it to
Jens Villadsen (Aug 01 2019 at 07:40):
While we're at the query/search discussion: Couldn't the https://www.hl7.org/fhir/operation-patient-match.html just as well have been expressed as a 'query' profile then?
Grahame Grieve (Aug 01 2019 at 07:42):
it could have been, yes. In fact, the very first cut, it was. But there's more than a few people who don't like _query and it was kind of a style question, in the end.
Jens Villadsen (Aug 01 2019 at 11:35):
okay @Grahame Grieve - let me know when you open up the 'query vs search'-distinction-terminology discussion ... its of interest for me as well
Grahame Grieve (Aug 01 2019 at 11:58):
well, that'll be up to @John Moehrke I think
Brian Postlethwaite (Aug 01 2019 at 12:17):
The patient match can take up to a whole patient resource, not just the fields that happen to be in the search parameters. A query style wouldn't meet that. So you could be more careful on matching the names in the resource.
Jens Villadsen (Apr 22 2020 at 10:19):
back to this: @John Moehrke, @Grahame Grieve never moved the discussion (or at least it is not present in this discussion). Bottom line is that http://build.fhir.org/auditevent.html#6.4.4.4 still lists search and search-type as 'E' where it IMHO better fits to 'R'. Should I make a CR on this or should it be moved to another stream first?
Grahame Grieve (Apr 22 2020 at 12:21):
#implementers I guess. but search is R for me not E
John Moehrke (Apr 22 2020 at 12:47):
The discussion has happened. Search/Query do not identify the instance in the request, one must execute a search on the parameters provided to get the result. This is why search/query is an execute. The discussion did result in a clarification in the section pointed at, that explains this.
Agent for logged in user, if available, and one object with a query element. The Execute action is used as the server must execute the search parameters to get the results, whereas a Read action identifies a specific object.
I have not heard any reason why this conclusion is so difficult to live with. Can this be explained, other than a rhetorical argument about the HTTP GET verb?
Jens Villadsen (Apr 22 2020 at 13:18):
While it does not identify a single resource it identifies multiple resources - as such I would even call it multiple reads - which I would simply to an 'R', not an 'E'
John Moehrke (Apr 22 2020 at 13:27):
there is indeed a degenerate query on the _id that could be seen as identical to a read. but this does produce a bundle , and as an exception does not invalidate the dominant fact that the query parameters do not identify objects, but rather parameters that must be searched on to discover the results.
Jens Villadsen (Apr 22 2020 at 13:41):
query parameters do not identify objects
indeed query parameters identifies objects. If I search a database for all males named ' @John Moehrke ' I'm pretty sure those objects are identified, aren't they?
John Moehrke (Apr 22 2020 at 14:05):
no, they were 'found' at a moment in time. But they are not known. As in a DELETE operation seconds after that query will produce nothing. Yet a GET on an ID will be clear what it was that was retrieved regardless of the DELETE operation.
Jens Villadsen (Apr 22 2020 at 14:07):
everything is found in a moment of time
Jens Villadsen (Apr 22 2020 at 14:08):
and at that time they will be identified with those parameters
Jens Villadsen (Apr 22 2020 at 14:09):
and at that time they are known
John Moehrke (Apr 22 2020 at 14:10):
can you explain what is wrong with Execute? I have explained that consensus (actually multiple standards organizations) have agreed it is execute.
John Moehrke (Apr 22 2020 at 14:10):
I simply have not heard any reason why execute is problematic
Jens Villadsen (Apr 22 2020 at 14:10):
'R' simply fits better to the picture
Jens Villadsen (Apr 22 2020 at 14:11):
multiple standard organizations would have multiple takes on it
Jens Villadsen (Apr 22 2020 at 14:11):
ask those that standardize SQL
John Moehrke (Apr 22 2020 at 14:11):
and AuditEvent is designed for multiple uses
Jens Villadsen (Apr 22 2020 at 14:11):
sure
Jens Villadsen (Apr 22 2020 at 14:11):
which basically means that multiple uses would have multiple takes on it
Jens Villadsen (Apr 22 2020 at 14:12):
everything is an 'execute' if you go deep enough
Jens Villadsen (Apr 22 2020 at 14:12):
i think
Jens Villadsen (Apr 22 2020 at 14:12):
it is a matter of abstraction
John Moehrke (Apr 22 2020 at 14:12):
or one person has a different view than others
Jens Villadsen (Apr 22 2020 at 14:12):
and from my point of view (and maybe others) 'R' fits better into the picture
Jens Villadsen (Apr 22 2020 at 14:13):
sure
Jens Villadsen (Apr 22 2020 at 14:14):
maybe only @Grahame Grieve and me thinks 'R' is a better fit. That might be plausible
John Moehrke (Apr 22 2020 at 14:52):
there are historic reasons, companion standards reasons, modeling reasons, etc... that up against the only argument against "R fits better into the picture". Which is a very REST flavor of FHIR specific viewpoint (picture). Given this is your answer to what is wrong with "E", I am not persuaded.
Jens Villadsen (Apr 22 2020 at 16:05):
Just to be clear: in your book, searching for multiple entites resulting in the return of multiple instances that are associated to that search is not a read of data?
John Moehrke (Apr 22 2020 at 16:33):
you are correct that in FHIR the results of a search is not just a list of id values. more reason that a search is an Execute, as one must understand the search must be looked at to understand what was exposed. Good point as to why E is correct.
Jens Villadsen (Apr 22 2020 at 17:20):
So if the result is in a bundle, it is E?
Jens Villadsen (Apr 22 2020 at 19:15):
(besides searching using _id)
Jens Villadsen (Apr 23 2020 at 19:33):
@John Moehrke
John Moehrke (Apr 24 2020 at 14:08):
I don't think that is a good definition of a query / search... especially given document bundles, message bundles, and collection bundles.. so, no.
Jens Villadsen (Apr 24 2020 at 14:22):
Given the context of a REST interface, would that change anything?
John Moehrke (Apr 24 2020 at 14:28):
as in a "searchset" bundle? well, yes a searchset bundle is the result of a search. / query. It also indicates this could be the result of an operation (clearly an Execute, right?), or a "message". Where I think the "message" here means a message bundle that had a search request in it, but that is not clear. http://build.fhir.org/codesystem-bundle-type.html#bundle-type-searchset
John Moehrke (Apr 24 2020 at 14:29):
but, a failed search / query does not result in a searchset bundle... and it too must be recorded as an Execute ... so searchset bundle is not sufficient clarification
Jens Villadsen (Apr 24 2020 at 14:32):
maybe 'R' is too narrow and 'E' is to wide. I my mind, 'E' is what cannot be categorized as neither CRU or D.
Jens Villadsen (Apr 24 2020 at 14:32):
E is: hey service, please fetch all y, extrapolate to x and combine with z
Jens Villadsen (Apr 24 2020 at 14:33):
or: hey service, please read from a third party register and do the fuzzy logic transformation for me
Jens Villadsen (Apr 24 2020 at 14:35):
searching is neither of those ... searching is ... well, search based on some optional filtering and restriction requirements
Jens Villadsen (Apr 24 2020 at 14:37):
I don't see searching as a way of transforming og altering data - which an execute would do - as it is anything else.
Jens Villadsen (Apr 24 2020 at 14:38):
what would your take be on that @John Moehrke
Keith Boone (Apr 24 2020 at 14:40):
Much of what is really useful in FHIR Search is "extrapolate to x [include, revinclude]", combine with (:in=ValueSet), and similar.
The set of required/optional parameters is really important. I know of few EHRs which would allow a user to search for Observation?code=X without specifying patient/subject also, unless it's a special kind of system that is allow to search across patients (e.g. for quality measurement).
A lot of what is in FHIR search isn't just read these things, it's "give me this view"
Jens Villadsen (Apr 24 2020 at 14:43):
@Keith Boone -yet the search does not transform the data. you ask for at set of filtered observations - and you get observations in return
Jens Villadsen (Apr 24 2020 at 14:43):
they will still be observations
Jens Villadsen (Apr 24 2020 at 14:44):
you do not transform nor manipulate it (besides including other items as mean of optimization)
John Moehrke (Apr 24 2020 at 14:45):
filtering is transforming... it is reducing the results based on the filter criteria
Jens Villadsen (Apr 24 2020 at 14:45):
how can filtering be transforming?
Jens Villadsen (Apr 24 2020 at 14:46):
reducing the set is filtering
Jens Villadsen (Apr 24 2020 at 14:48):
filtering on a search on observations still only gives you observations - it doesn't give you organizations, right?
Keith Boone (Apr 24 2020 at 14:53):
I think about it from a database permissions perspective. These kinds of searches with these parameters are allowed by people in this roles, those kinds of searches with those parameters are allowed by those others in that kind of role. This first "Search" with a fixed set of parameters is akin to a Stored procedure with one set of parameters, on which Role 1 has Execute privileges, but role 2 has not, while the second is allowed to be executed by both roles.
We can get hung up on whether R or E is right or wrong. That's actually less material than why or what impact it has on software that's being implemented and/or has been implemented. What's the use of E going to impact that is so fundamentally frustrating for use of it in audits is what I'd like to understand. Because changing the use of now is going to impact existing commercial and open source implementations and other published guides, so I'd like to see something other than what has been mostly an academic discussion about whether it's E or R.
Keith Boone (Apr 24 2020 at 18:47):
For what it's worth, I've implemented E twice for AuditEvent in commercially available products that have been in production for several years in one case, and a year in the other, and used it for several FHIR IGs as well. I'm not interested in seeing it change unless someone can come up with something other than an academic rationale.
Jens Villadsen (Apr 26 2020 at 13:52):
What's the use of E going to impact that is so fundamentally frustrating for use of it in audits is what I'd like to understand
I would like the use of the model to reflect the actual use as correctly as possible. I don't find 'E' doing that. Especially as I would like to differentiate between 'searches' and 'executions'. Searches in my system are expected to be idempotent whereas the same cannot be said about executions
Because changing the use of now is going to impact existing commercial and open source implementations and other published guides, so I'd like to see something other than what has been mostly an academic discussion about whether it's E or R.
That is of course a valid concern - but that goes for any change to future versions and time/money can be a reason not to change it. My system is a greenfield national solution where we besides the actual system also bridges AuditEvents from multiple sources with no ties to ATNA, IHE or DICOM. Processing the AuditEvent and the ability to filter e.g. whether an action is a search or not may not be the most central piece of information as every request and response is saved anyways and eventually indexed. I do however like to keep my model tight and clean - and the categorization of whether an action is potentially modifying data or not is part of that process. I don't find that approach particularly academic.
Keith Boone (Apr 27 2020 at 09:58):
Practically, Execute never has had the meaning of modify in any sense. An execution can modify, but it can also just read.
Green field ... "reflect actual use". But your definition of actual use and my definition of actual use come to different answers. There is no right or perfect answer to that question, and there's history, and an agreement as to what was selected, and implementations in place that use that answer.
FHIR defines E as follows:
E Execute Perform a system or application function such as log-on, program execution or use of an object's method, or perform a query/search operation.
That vocabulary is defined in terms of FHIR operations:
C = create
R = read or vread
U = update or patch (since patch is defined in terms of update)
D = delete
E = just about everything else.
Looking at it from that perspective, I feel even more strongly. E is operations other than CRUD, and search with ANY sort of complexity isn't CRUD. And the FHIR restful API is normative. I'd rather all search be E than some be R and some be E, and at least some of it needs to be E.
Jens Villadsen (Apr 27 2020 at 11:55):
How would you categorize the following @Keith Boone :
1) A transaction that does a single entity create
1) A transaction where two entities are created
2) A transaction that does a single entity read
3) A transaction where two entities are read
4) A query where two entities are read by id
Jens Villadsen (Apr 27 2020 at 11:55):
In terms of CRUDE
Keith Boone (Apr 27 2020 at 13:29):
When I implemented this using interceptors, prior to HAPI cutting over to the current format, but basically after it had processed the parameters. 1) Create operations went to create (C) 2) I didn't implement transaction, but did implement batch in one case, so a batch that created 2 entities uing batch went to (E), 3) went to read (R), 4) didn't implement a batch read, but it would have gone to (E) the same way that batch writes went to (E), 5) GET Resource?_id=1,2 would have gone to (E) if I had allowed it, both times I implemented search, I disallowed query by more than one id. Since it entered as Search, it would again have been (E).
John Moehrke (Apr 27 2020 at 13:33):
I would say they all should result in an "E" record, but items 1-4 would ALSO result in some CRUD audit entries.
Keith Boone (Apr 27 2020 at 13:34):
If using FHIR transaction or FHIR batch, I would agree, these would all have been (E) in the implementation I did. If using FHIR operations (read,vread, create, delete, etc), these would have gone as I've indicated.
John Moehrke (Apr 27 2020 at 13:34):
Someone might notice the query of _id, and recognize that as a Read; but they still should record it as a E/query. Just because the _id parameter is used does not mean it should not be recorded as an E/query. The nice part about E for query is that it works ALWAYS the same way.
Jens Villadsen (Apr 27 2020 at 20:42):
John Moehrke said:
I would say they all should result in an "E" record, but items 1-4 would ALSO result in some CRUD audit entries.
Ain't that a bit too ambiguous
Jens Villadsen (Apr 27 2020 at 20:55):
I believe we can agree to disagree on this matter ;)
Jens Villadsen (Apr 28 2020 at 08:30):
To me, a search/query that is idempotent that does filtering and/or narrowing and optional includes is a read of data
Last updated: Apr 12 2022 at 19:14 UTC