Most probably you would like to validate incoming resources.
This logic can be divided into several parts:
KeFHIR provides default resource profile validation based on current conformance. A HAPI validation library is used for this.
This validator validates correct json or xml structure, as well as validates against current profile.
To include this validator in your project, simply add curresponding dependency.
implementation "com.kodality.kefhir:validation-profile:${kefhirVersion}"
Validation can be done at any step while saving resource.
Best way to add own validation is by implementing ResourceBeforeSaveInterceptor
interface, ideally at two main steps: INPUT_VALIDATION
and BUSINESS_VALIDATION
.
Failed validation should throw a FhirException
.
Simple validation solution may look like:
@Singleton
public class ResourceProfileValidator extends ResourceBeforeSaveInterceptor {
@Inject
private ResourceFormatService resourceFormatService;
public ResourceProfileValidator() {
super(ResourceBeforeSaveInterceptor.BUSINESS_VALIDATION);
}
@Override
public void handle(ResourceId id, ResourceContent content, String interaction) {
if (!id.getResourceType().equals("MedicationRequest")) {
return;
}
MedicationRequest medicationRequest = resourceFormatService.parse(version.getContent());
Date end = medicationRequest.getDispenseRequest().getValidityPeriod().getEnd();
Date maxEnd = DateUtils.addHours(medicationRequest.getAuthoredOn(), 72);
if (end.after(maxEnd)) {
throw new FhirException(400, IssueType.INVALID, "MedicationRequest validityPeriod cannot exceed 72 hours");
}
}
}
In some cases you want to add some restrictions to search. In this case you can take advantage of ResourceBeforeSearchInterceptor
, same as above.
For example if you would like to make sure someone can search only for his organization:
public class CustomSearchValidator extends ResourceBeforeSearchInterceptor {
@Override
public void handle(SearchCriterion criteria) {
if (!criteria.getType().equals(ResourceType.MedicationRequest.name())) {
return;
}
QueryParam condition = criteria.getConditions().stream().filter(qp -> qp.getKey().equals("intended-performer")).findFirst().orElse(null);
if (condition != null && !condition.getValues().stream().allMatch(this.isUserOrganization())) {
throw new FhirException(400, IssueType.INVALID, "Search for other organizations not allowed");
}
}
}