Are custom profiles supported?

1,667 views
Skip to first unread message

as...@yahoo.com

unread,
Jul 13, 2018, 5:13:27 PM7/13/18
to HAPI FHIR
We're trying to validate a resource (Practitioner) against a DSTU3 application-specific profile that we created.  Tracing through the validation code in the latest snapshot build, we are seeing validation being done against the default canonical profile, but our custom profile is not being loaded and we see the following error:

{
  "resourceType": "OperationOutcome",
  "text": {
    "status": "generated",
    "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><h1>Operation Outcome</h1><table border=\"0\"><tr><td style=\"font-weight: bold;\">WARNING</td><td>[Practitioner.meta.profile[0]]</td><td><pre>StructureDefinition reference \"http://hl7.org/fhir/StructureDefinition/ocp-practitioner\" could not be resolved</pre></td>\r\n\t\t\t\t\t\r\n\t\t\t\t\r\n\t\t\t</tr>\r\n\t\t</table>\r\n\t</div>"
  },
  "issue": [
    {
      "severity": "warning",
      "code": "processing",
      "diagnostics": "StructureDefinition reference \"http://hl7.org/fhir/StructureDefinition/ocp-practitioner\" could not be resolved",
      "location": [
        "Practitioner.meta.profile[0]"
      ]
    }
  ]
}


The profile is stored as a StructureDefinition locally.  Can the validator be configured to look at locally stored structure definitions?  Thanks in advance.

- Anthony

keeyan....@uconn.edu

unread,
Jul 17, 2018, 5:37:49 PM7/17/18
to HAPI FHIR
Hi,

You can access structure definitions locally by passing them to the validator.  First load the definition(s) from the directory as a structure definition



IParser xmlParser = FhirContext.forR4().newXmlParser();
xmlParser.setParserErrorHandler(new StrictErrorHandler());
List<StructureDefinition> definitions = new ArrayList<>();
try {
StructureDefinition sd = xmlParser.parseResource(StructureDefinition.class, new FileReader(<##YOUR_FILE_PATH##>));
definitions.add(sd);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}


Then make an implementation of IValidationSupport and add the required methods.  Using the code from above to load the structure definitions, you can do it like this:

public class MyValidationSupport implements IValidationSupport {

  public MyValidationSupport() {

//Definitions list gotten from code above
definitionsMap = new HashMap<>();
definitions.forEach(def -> definitionsMap.put(def.getUrl(), def));
}

  @Override
public ValueSet.ValueSetExpansionComponent expandValueSet(FhirContext theContext, ValueSet.ConceptSetComponent theInclude) {
return null;
}

@Override
public List<IBaseResource> fetchAllConformanceResources(FhirContext theContext) {

return null;
}

@Override
public List<StructureDefinition> fetchAllStructureDefinitions(FhirContext theContext) {

return definitions;
}

@Override
public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
return null;
}

@Override
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {

return (T) definitionsMap.get(theUri);
}

@Override
public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
return definitionsMap.get(theUrl);
}

@Override
public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
return false;
}

@Override
public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
return null;
}
}

Now all that's left is to make an instance validator and chain your new ValidationSupport with the BaseValidationSupport to get a full validator.  You can do that like this:

ctx =  FhirContext.forR4();
validator = ctx.newValidator();
instanceValidator = new FhirInstanceValidator();
IValidationSupport valSupport = new MyValidationSupport();
ValidationSupportChain support = new ValidationSupportChain(valSupport, new DefaultProfileValidationSupport());
instanceValidator.setValidationSupport(support);
validator.registerValidatorModule(instanceValidator);


This validator should use your locally stored profiles to validate resources with the appropriate URI.  Also, make sure your structure definition is referenced when you make your resource.  You can add a meta tag to the resource when you make it to specify the structure definition you want to use or it will still default to the regular structure definition in the jars.  You can also add the profile to the resource definition with an annotation, @Profile I think.

MyPractitioner mP = new MyPractitioner();
Meta meta = new Meta().addProfile("http://acme.org/my-structure-definition");
dvP.setMeta(met1);

I've just realized that you asked for DSTU3, but it should work the same as in R4.  

Best,

Keeyan

as...@yahoo.com

unread,
Jul 18, 2018, 11:27:21 AM7/18/18
to HAPI FHIR
Many thanks for the reply Keeyan - much appreciated.  Unfortunately, this is the approach I was already taking but with the JPA Server.  The JPA Server enables a default validator for the standard profiles/resources, which is called when an incoming FHIR request contains the $validate keyword.  A problem I've been dealing with is re-configuring that validator's ValidationSupportChain.  The changes I make within either the FhirConfig.java or JPAServerDemo.java files to attach a custom IValidationSupport class either before or after the DefaultProfileValidationSupport instance don't "stick" during JPA Server start-up.

Are you using the JPA Server and if so, did you configure the ValidationSupportChain in the FhirConfig.java or JPAServerDemo.java files?

- Anthony

hugo.j...@gmail.com

unread,
Aug 27, 2018, 1:25:49 PM8/27/18
to HAPI FHIR
You dont need any extra configuration on the JPA server to validate with you extra custom profiles. If the JPA server contains the struct definitons on its database it will automatically pick them up if they are referenced in meta.profile of a resource.
Try:
1 -  add your new StructureDefinitions to you jpa server by creating the resource instances. You can use the bundled dashboard for that using the create button on "crud operations"
2- go to the Practiioner resource and click "crud operations" -> validate (dont forget to reference the profile you want to validate in meta.profile)

as...@yahoo.com

unread,
Aug 27, 2018, 9:57:01 PM8/27/18
to HAPI FHIR
Unfortunately incorrect.  We were hoping too that the JPA Server would look up the StructureDefinition from the database, but that is not the case.  To illustrate the problem, validate the practitioner in the attached JSON file at the public test server.  The ocp-practitioner StructureDefinition is present in the database.  You'll see the following error:

StructureDefinition reference "http://hl7.org/fhir/StructureDefinition/ocp-practitioner" could not be resolved

In addition, there is a defect in the resolving code that I identified and submitted a pull request for the upcoming HAPI version:



Enabling the validation interceptor and overriding fetchStructureDefinition() in a ValidationSupport class implementing the IValidationSupport interface to retrieve the StructureDefinition from the DAO were necessary.
testPractitioner.json

Hugo Soares

unread,
Aug 28, 2018, 3:13:58 AM8/28/18
to as...@yahoo.com, hapi...@googlegroups.com
I use a local instance of the jpaserver (latest version) and it does work. It already includes validation support that will search for a structure definition by url. 

--
You received this message because you are subscribed to a topic in the Google Groups "HAPI FHIR" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/hapi-fhir/0hUGgBO2Xbo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to hapi-fhir+...@googlegroups.com.
To post to this group, send email to hapi...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/hapi-fhir/4e42b62f-c03f-44f9-8432-413b1cc85a25%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

as...@yahoo.com

unread,
Aug 28, 2018, 12:14:17 PM8/28/18
to HAPI FHIR
That doesn't explain the error shown at the public server with our ocp-practitioner StructureDefinition and the lack of this functionality when I was debugging the HAPI code.  I debugged multiple requests entirely through HAPI and the FHIR validator, observing the calls between the validator and HAPI to fetchStructureDefinition(), and saw no calls to the DAO to retrieve StructureDefinitions from the database.

The FHIR validator is not part of HAPI and has no knowledge about the JPA Server or the backing database.  If you're not using the validation interceptor, then the reason why it appears to work is likely due to your profiles having the same names as the standard FHIR StructureDefinitions.  The FHIR validator uses the standard StructureDefinitions stored in the profiles-types.xml, profiles-resources.xml, and profiles-others.xml files if no IValidationSupport objects are registered at start-up.

The only way I can be convinced is if you have a pointer in the code-base showing where the call is made to the DAO in the standard HAPI distribution.  :)

Hugo Soares

unread,
Aug 28, 2018, 12:32:36 PM8/28/18
to as...@yahoo.com, hapi...@googlegroups.com

as...@yahoo.com

unread,
Aug 28, 2018, 1:07:37 PM8/28/18
to HAPI FHIR
I absolutely agree that the JpaValidationSupportDstu3 is included in the validation chain by default.  However, that doesn't explain why even the public server cannot resolve the ocp-practitioner StructureDefinition.  The public server is running the latest code and shows behavior identical to what I've observed in my dev environment.

Refer to attached screenshots.

I set the breakpoint at line 121 of JpaValidationSupportDstu3.java and sent the following validate request with Postman.  The breakpoint was never hit.  In fact, I confirmed that the fetchResource() function was never called.


Body:
{
  "resourceType": "Practitioner",
  "meta": {
    "profile": [
    ]
  },
  "identifier": [
    {
      "system": "http://hl7.org/fhir/sid/us-npi",
      "value": "7722720916"
    }
  ],
  "active": true,
  "name": [
    {
      "family": "",
      "given": [
        ""
      ]
    }
  ],
  "telecom": [
    {
      "system": "phone",
      "value": "410-529-1250",
      "rank": 1
    },
    {
      "system": "email",
      "rank": 2
    }
  ],
  "address": [
   {
      "line": [
  
        "4072 Healthcare Avenue",
"Suite 300"
      ],
      "city": "Toledo",
      "state": "OH",
      "postalCode": "41076",
      "country": "US"
    }
  ]

ocp-practitionerStructureDefinition.jpg
validate2.jpg
validate1.jpg

jannu...@gmail.com

unread,
Jan 15, 2020, 10:49:38 PM1/15/20
to HAPI FHIR
Even i am stuck with the same problem with R4 version. Could you please let me know the solution incase if you found the solution.

Kevin Mayfield

unread,
Jan 15, 2020, 11:48:54 PM1/15/20
to HAPI FHIR
Have you tried changing the url of your profile?

I've a feeling the url hl7.org is causing DefaultValidationSupport classes to try to validate the profile, as it supports that domain.

Reply all
Reply to author
Forward
0 new messages