Stream: implementers
Topic: x-provenance header not working
Nath (Jan 25 2020 at 15:30):
Hello Friends, I have been reading docs and desperately looking for an example how this X-Provenance works?. Here is what I tried:
I use the JPA Version R4.0.0. Upgraded to 4.0.1 also still not working.
@Autowired private IGenericClient fhirClient; Patient patient = new Patient(); patient.addIdentifier().setUse(Identifier.IdentifierUse.OFFICIAL).setSystem("urn:example") .setValue("101"); - - - - more fields to patient object Bundle bundle = new Bundle(); bundle.setType(Bundle.BundleType.TRANSACTION); bundle.addEntry() .setFullUrl(patient.getIdElement().getValue()) .setResource(patient) .getRequest() .setUrl("Patient") .setIfNoneExist("identifier=http://xyz.org/mrns|12345") .setMethod(Bundle.HTTPVerb.POST); AdditionalRequestHeadersInterceptor additionalRequestHeadersInterceptor = new AdditionalRequestHeadersInterceptor(); JSONObject jsonObject = new JSONObject(); try { jsonObject.put("resourceType", "Provenance"); jsonObject.put("recorded", new Date()); JSONObject j = new JSONObject(); j.put("who", "Patient/1"); // existing patient in my system jsonObject.put("agent", j); } catch (Exception e) {} additionalRequestHeadersInterceptor.addHeaderValue("X-Provenance", jsonObject.toString()); additionalRequestHeadersInterceptor.addHeaderValue("content-type", "application/fhir+json"); fhirClient.registerInterceptor(additionalRequestHeadersInterceptor); Bundle resp = fhirClient .transaction() .withBundle(bundle) .execute();
I checked the database, I see the patient is created but no provenance resource. Can someone help me what I am doing wrong ?.
Since there is no proper example describing this X-Provenance, its hard. I searched the code also but not able to find where X-Provenance is used as well. I will debug it further if someone points me to the source code.
thanks for your help
Nath
David Pyke (Jan 25 2020 at 15:32):
@John Moehrke
Scott Fradkin (Jan 25 2020 at 17:44):
If you're using HAPI-FHIR, it doesn't appear to support the X-Provenance header yet. We had to implement our own support for the header in order for it to work. Are there any servers that support it out of the box at this point in time?
Nath (Jan 25 2020 at 21:33):
thanks @Scott Fradkin Yes I am using Hapi fhir. Is there a link or document where I can see what's supported or not. Sorry I am new to this.
Sorry for this basic question, so where is this functionality currently implemented then ?
Also, "we had to implement our own support for the header ..", you mean if the header contains X-Provenance then do this functionality of creating the provenance resource youself in hapi fhir ?. Is that what you mean ?. basically, duplicate the functionality from the place where its currently implemented to hapi fhir ?
thanks
James Agnew (Jan 25 2020 at 23:19):
You would probably want to implement this as a Server Interceptor (see https://hapifhir.io/hapi-fhir/docs/interceptors/ ). We'd gladly welcome any contributions of such an interceptor if someone wanted to try building it and sharing their work.
Nath (Jan 26 2020 at 03:23):
@James Agnew thanks. sure, let me understand interceptor and provider.
High level this is what I am thinking:
In the bundle provider method,
JpaSystemProviderR4.java
@Transaction
public Bundle transaction(RequestDetails theRequestDetails, @TransactionParam Bundle theResources) {
startRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
try {
return getDao().transaction(theRequestDetails, theResources);
} finally {
endRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
}
}
I looked at all server interceptor and I see there is none currently for bundle pre-commit resources. I see only STORAGE_PRESTORAGE_RESOURCE_CREATED.
So, in the above method transaction(..) after getDao().transaction(theRequestDetails, theResources) is called, invoke the new interceptor say STORAGE_PRECOMMIT_RESOURCES.
JpaInterceptorBroadcaster.doCallHooks(myInterceptorBroadcaster, theRequest, Pointcut.STORAGE_PRECOMMIT_RESOURCES, theResources);
inside the interceptor, it should walk thru the theResources, get the id and version, create the provenance resource, call getDao().transaction(newRequest, provenanceResource)
This is for JPA but not sure what needs to be done for Restful server(non-jpa).
Please kindly guide me,
James Agnew (Jan 26 2020 at 14:06):
I think you should be fine to just hook into STORAGE_PRESTORAGE_RESOURCE_CREATED
and also STORAGE_PRESTORAGE_RESOURCE_UPDATED
if you want. Those will get called both for normal CRUD and for transaction operations.
Nath (Jan 26 2020 at 17:50):
thanks @James Agnew . Sorry, I am bit confused now. The STORAGE_PRESTORAGE_RESOURCE_CREATED is fired for each resource. So, if my txn bundle contains 3 resources I will get 3 times this interceptor be called and that's not what we want here.RIght?
In this case once all my 3 resources are created I want my interceptor be called and it will create provenance resource with version id's. So, I am thinking we need a new interceptor that should be invoked once all the resources in the bundle are processed.
thanks
James Agnew (Jan 27 2020 at 00:47):
ah, if the logic you're after is for a single call to happen after the whole bundle is done, you probably want to hook into SERVER_PROCESSING_COMPLETED_NORMALLY
Scott Fradkin (Jan 27 2020 at 04:36):
Our implementation was for prototype functionality for a single operation, so we didn't implement anything generic enough like a server interceptor, but basically, yes we created a new Provenance resource out of the header and added the resource identifiers inserted from the bundle as the target to the Provenance resource. So the Provenance resource was created and inserted after the bundle transaction was completed.
Nath (Jan 27 2020 at 05:27):
thanks @James Agnew. I looked at the server interceptor diagram https://hapifhir.io/hapi-fhir/docs/interceptors/server_pointcuts.html. The event SERVER_PROCESSING_COMPLETED_NORMALLY is raised after the transaction is completed but I want to add provenance resource within the same txn. So, I need something after all resources in the bundle are processed, id, version is generated, then I use those versions, id and create provenance resource in the same txn.
This will work for JPA.
Also, 2nd question is about Plain server, do I need to do anything since storage is done externally.
@Scott Fradkin thanks for the information.
thanks a lot.
Last updated: Apr 12 2022 at 19:14 UTC