KeFHIR automatically configers itslef based on provided Conformance resources.
Resources are loaded from database using provided search implementation and then stored in memory for quick access.
Currently used conformance resources are:
Conformance resources may be saved in the same way as any other resource (considering it is allowed by your access control) using fhir rest.
However, this means that to create conformance you need conformance.
So, for the very first time you need to initialize it some other way - directly into database or write some code to load from somewhere, for example.
KeFHIR also provides service to load in from file system.
implementation "com.kodality.kefhir:fhir-conformance:${kefhirVersion}"
fhir-conformance
module can automatically download fhir definitions zip and populate the server with its data. This may be helpful for a quick start, but most probably you will need your custom setup eventually.
application.yml
kefhir.conformance.definitions-url: https://kexus.kodality.com/repository/store-public/kefhir/definitions.json.zip
When this variable is provided, KeFHIR will try to autoinitialize itself if no conformance is already present.
fhir-conformance
module creates new endpoint
POST /conformance-tools/import-file?file=/path/to/file/on/server
When requested, this fill read all files in this path and try to parse them as Budles and save.
The source code contains script for downloading FHIR definitions and uploading them to the server.
You can override default script, add Conformance directly to the database, use fhir-conformance
or invent your own way.
The server configuration after the initial Conformance loading may take several minutes.
By default conformance is loaded from the database.
If you do not want conformance to be loaded from database and provide it yourself, feel free to rewrite ConformanceLoader
bean. Default implementation - ConformanceStorageLoader
.
Available abstract class ConformanceStaticLoader
, which helps to manually provide conformance
Note: Initialization logic may be a subject to change in the future.
@Singleton
@Replaces(ConformanceLoader.class)
@RequiredArgsConstructor
public class FileBasedConformanceLoader extends ConformanceStaticLoader {
@Override
public List<String> getResources() {
try {
URL conformanceDir = FileBasedConformanceLoader.class.getClassLoader().getResource("fhir-conformance");
Collection<File> conformanceFiles = FileUtils.listFiles(new File(conformanceDir.toURI()), new String[]{"json"}, true);
return conformanceFiles.parallelStream().map(f -> {
try {
return IOUtils.toString(f.toURI(), StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException("Failed to parse FHIR conformance files", e);
}
}).toList();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
Another option would be to replace main bean ConformanceInitializationService
and implement conformance loading from scratch. Example:
@Singleton
@Replaces(ConformanceInitializationService.class)
public class ConformanceLoader extends ConformanceInitializationService {
private final List<ConformanceUpdateListener> conformanceUpdateListeners;
public ConformanceLoader(ResourceFormatService resourceFormatService, List<ConformanceUpdateListener> conformanceUpdateListeners) {
super(null, resourceFormatService, conformanceUpdateListeners);
this.conformanceUpdateListeners = conformanceUpdateListeners;
}
public void refresh() {
ConformanceHolder.setCapabilityStatement(this.<CapabilityStatement>load("CapabilityStatement").stream().findFirst().orElse(null));
ConformanceHolder.setStructureDefinitions(load("StructureDefinition"));
ConformanceHolder.setSearchParamGroups(load("SearchParameter"));
ConformanceHolder.setValueSets(load("ValueSet"));
ConformanceHolder.setCodeSystems(load("CodeSystem"));
ConformanceHolder.setCompartmentDefinitions(load("CompartmentDefinition"));
conformanceUpdateListeners.forEach(ConformanceUpdateListener::updated);
}
private <T extends Resource> List<T> load(String resource) {
// load from file here, for example
}
}