1.2Changelog: 2020

 

1.2.1Changelog

 

1.2.2HAPI FHIR 5.3.0 (Odyssey)

 

Release Information

Released: 2021-02-18

Codename: (Odyssey)

Changes

The version of a few dependencies have been bumped to the latest versions (dependent HAPI modules listed in brackets):

  • SLF4j (All Modules): 1.7.28 -> 1.7.30
  • Jackson (All Modules): 2.11.2 -> 2.12.1
  • Woodstox (XML FHIR Parser): 4.4.1 -> 6.2.3 (Note that the Maven groupId has changed from org.codehaus.woodstox to com.fasterxml.woodstox and the Maven artifactId has changed from woodstox-core-asl to woodstox-core for this library)
  • Spring (JPA): 5.2.3.RELEASE -> 5.2.9.RELEASE
  • Datasource-Proxy (JPA): 1.5.1 -> 1.7
  • Apache Commons Collections4 (JPA): 4.3 -> 4.4
  • Jetty (JPA Starter): 9.4.30.v20200611 -> 9.4.35.v20201120
  • Guava (JP): 29.0-jre -> 30.1-jre
  • Hibernate ORM (JPA Server): 5.4.22.FINAL -> 5.4.26.FINAL
  • Spring (JPA Server): 5.2.9.RELEASE -> 5.3.3
  • Spring Data (JPA Server): 2.2.0.RELEASE -> 2.4.2
  • Hibernate Search (JPA Server): 5.11.5.FINAL -> 6.0.0.Final
  • Lucene(HAPI FHIR JPA Server): 5.5.5 -> 8.7.0
  • Spring Boot (JPA Starter): 2.2.6.RELEASE -> 2.4.1
  • JANSI (CLI): 1.18 -> 2.1.1
  • PH-Schematron (SCH Validator): 5.2.0 -> 5.6.5
  • PH-Commons (SCH Validator): 5.3.8 -> 9.5.4

#2054

Two new switches have neen added to FhirInstanceValidator to suppress optional warning messages. Thanks to Anders Havn for the pull request!

#2177

Redesigning the Enterprise Master Patient Index solution to a Master Data Management solution. The new MDM solution supports other FHIR resources where EMPI only allowed Person resource to be used. For example, if MDM is occurring on a patient, we will create a new Patient, and tag that patient as a Golden Record. This means that several things have changed:

  • Provider methods that pointed to type of Person are now server-level operations in which you specify a resource type.
  • Link updating and querying no longer rely on Person IDs, but instead on arbitrary resource ids, depending on the resource type you are referring to in MDM.
  • Change to the EMPI config to require a list of mdmTypes.

Code-level changes include the following changes:
  • hapi-fhir-server-empi and hapi-fhir-jpaserver-empi Maven projects were renamed to hapi-fhir-server-mdm and hapi-fhir-jpaserver-mdm
  • All classes were refactored to use correct terms, e.g. Golden Resource in place of Person
  • Message channel was renamed from empi to mdm
  • Subscriptions were renamed to mdm-RESOURCE_TYPE, where RESOURCE_TYPE is an MDM type configured in mdmTypes section of the configuration file
  • Configuration file was renamed from empi-rules.json to mdm-rules.json
  • Log file was changed from empi-troubleshooting.log to mdm-troubleshooting.log

#2182

When a unique index SearchParameter violation is blocked, the error message will now include the ID of the relevant SearchParameter, in order to make troubleshooting easier.

#2191

Added a new IResourceChangeListenerRegistry service and modified SearchParamRegistry and SubscriptionRegistry to use it. This service contains an in-memory list of all registered {@link IResourceChangeListener} instances along with their caches and other details needed to maintain those caches. Register an {@link IResourceChangeListener} instance with this service to be notified when resources you care about are changed. This service quickly notifies listeners of changes that happened on the local process and also eventually notifies listeners of changes that were made by remote processes.

#2198

It is now possible for read operations (read/history/search/etc) in a partitioned server to read across more than one partition if the partitioning interceptor indicates multiple partitions.

#2213

Non release (i.e. SNAPSHOT) builds of HAPI FHIR will now include the Git revision hash as well as the build date in the version string that is logged on initialization, and included in the default server X-Powered-By string. Release builds are not affected by this change.

#2221

The error message returned by the transaction processor has been improved for the case where a transaction uses an unsupported/disabled resource types.

#2234

When performing a conditional create/update containing the email search parameter, any + characters will now be interpreted as actually being a plus symbol instead of being unescaped into a space character. This is technically a deviation from how URLs should be parsed, but allows for a sensible behaviour in a spot where no spaces are allowed.

#2237

It is now possible to use a parameter of type IBaseResource or IBaseBundle as the parameter on a @Transaction method in a plain server.

#2261

Optionally supports storage and search in canonical form of the quantity value which is defined by 'http://unitsofmeasure.org'; please check ModelConfig for the configuration. No changes were made to the existing behaviour.

#2264

The interceptor framework will now recognize and invoke @Hook methods that have an access level of public, protected, or default. Previously only public methods were recognized.

#2264

A new interceptor called the Repository Validating Interceptor has been added. This new interceptor allows a HAPI FHIR JPA Server to declare rules about mandatory profiles that all resources stored to the server must declare conformance and/or correctly validate against.

#2282

When performing a ValueSet expansion where the valueset to be expanded includes a display name for concepts it is explicitly including, this display name will be propagated to the expansion if no other display is available. Thanks to Hanan Awwad for the contribution!

#2310

A new utility called FHIRPathResourceGeneratorR4 has been added. This class can be used to build and populate a resource model object using FHIRPath expressions. Thanks to Marcel P for the contribution!

#2323

The JPA server has a new setting on the ModelConfig bean called "AutoVersionReferencesAtPaths". Using this setting, the server can be configured to add the current target resource version ID to any resource references found in a resource being stored. In addition, a new setting has been added to the JPA ModelConfig bean that allows _include statements to respect versioned references, and actually include the correct version for the reference.

Added support for the $evaluate-measure Operation as part of adding CQL support.

#2302

The JPA server generated SQL for date search parameters has been streamlined to avoid the use of redundant OR expressions that slow down performance in some cases.

#2190

Updates to Hibernate Search require a full reindexing of all indexed fulltext data, which is held in Lucene or Elasticsearch. Users using elasticsearch for fulltext indexing must upgrade to Elasticsearch 7.10.0.

#2197

The resource IDs for several LOINC resources were corrected. Thanks to Steven Wagers for the pull request!

#2264

The experimental TransactionBuilder helper class has been renamed to BundleBuilder as it now has utility methods for working with other types of Bundles too.

#2290

In the JPA server. the SQL datatype used to index quantities has been changed from NUMBER(19,2) to double precision (or equivalents depending on platform). This improves the query support for ssearching on very small quantities.

#2340

The @ResourceDef annotation has been marked as inheritable, so it does not need to be explicitly added to custom structures that extend built-in structures. Thanks to Marcelo Avancini for the pull request!

#2372

ElasticsearchHibernatePropertiesBuilder will now reject any REST url which is protocol-aware. Protocol information should be set in the protocol field of the builder.

#2175

Expanding a ValueSet using a filter now evaluates the display with left-matching by string token, case-insensitive.

#2180

Loading a package without a description was causing a null pointer exception. This has been fixed.

#2183

The CodeSystem/$subsumes operation inadvertantly reversed the meanings of the CodeA and CodeB parameters, resulting in subsumes and subsumed-by responses being reversed. This has been corrected. Thanks to Rob Hausam for reporting!

#2192

ApacheRestfulClientFactory now uses system properties for proxy configuration. Thanks to Vladimir Nemergut for the pull request!

#2195

When performing a ValueSet expansion with a filter a large pre-expanded ValueSet (more than 1000 codes), the filter failed to find concepts appearing after the first thousand. This has been corrected.

#2205

The new JPA SearchBuilder failed to perform FHIR Searches on Oracle DB with an invalid SQL error. This has been corrected.

#2208

When performing a JPA server search on a partitioned server, searches with only the _id parameter and no other parameters did not include the partition selector in the generated SQL, resulting in leakage across partitions. Thanks to GitHub user @jtheory for reporting!

#2211

The recent EMPI project accidentally caused a split package in ca.uhn.fhir.rest.server. This has been corrected. Thanks to Bill Denton for the pull request!

#2214

When using the validator from within the JPA server, validating CapabilityStatement resources failed with an error when trying to load linked SearchParameter resources. This has been corrected.

#2215

When using a partitioned JPA server, auto-create placeholder targets did not work if the partition interceptor was registered against the server (e.g. for a multitenancy configuration). This has been corrected. Thanks to Rob Whelan for reporting!

#2262

Sorting of search results was not working for MySQL, MSSQL and MariaDB due to recent changes made to handle sorting of nullable columns. This has now been fixed.

#2265

The new optimized SQL Generator introduced in HAPI FHIR 5.2.0 did not correctly bind variables for SQL Server queries, making the search functionality unusable. This has been corrected.

#2269

A database index in the JPA server was added in HAPI FHIR 5.2.0 and Smile CDR 2020.11 that exceeded the maximum index length in MySQL, preventing server upgrades on that database platform. This has been corrected.

#2271

Attempts to load IG packs when partitioning was enabled, resulted in nullpointer exceptions. This has now been fixed and IG packs and conformance resources will be loaded to the DEFAULT partition.

#2273

An incorrect HTML resource path led to a utility JavaScript library failing to load in the TestPage Overlay module. Thanks to Alejandro Medina for the pull request!

#2297

When performing a FHIR create using the HAPI FHIR client, if the payload is a Bundle resource the individual resources in the Bundle had their IDs removed by the client during payload serialization. This has been corrected.

#2298

A recent change inadvertently caused an issue with DB migration utility such that it would attempt to drop indexes even when the dry-run option was specified. This has been fixed.

#2299

The BulkExportDaoSvc bean was forgotten from the BaseConfig context. It has been added.

#2309

In the JPA server, HumanName.name.text was not being indexed and therefore was not searchable. This has been corrected.

#2327

The $expand filter parameter was not matching the ValueSet display value in all cases. E.g. a ValueSet with name 'abc def ghi' would match 'abc def' and 'def' but not 'def ghi'. This has been corrected so the ValueSet will match the filter if any substring of the ValueSet display value matches the $expand filter.

#2361

Unrecognized search param prefix strings were silently discarded. This is now an error.

#2365

A bug in the InMemoryResourceMatcher caused AND clauses to be treated as OR clauses. Thanks to Jari Maijenburg for the report and pull request!

#2369

When using the Consent Interceptor, the startOperation method was not invoked for search paging requests. This has been corrected. Thanks to Tue Toft Nørgård for reporting!

#2361

As of version 2.69, the LOINC Top2000CommonLabResultsSi.csv and Top2000CommonLabResultsUs.csv became optional. The Terminology Loader Service has been updated to reflect this change.

#2220

An important security issue with the JPA Server was solved. This issue applies only to JPA servers running in partitioned mode. When performing searches on a partitioned server, search results from previously cached searches against different partitions may be returned, potentially leaking data across partitions. This issue has been resolved.

#2229

Remove support for the upload-igpack command. This command is no longer supported, as the IGPack format has been withdrawn and replaced with the FHIR NPM Package specification, which is also supported by HAPI FHIR

1.2.3HAPI FHIR 5.2.1 (Numbats)

 

Release Information

Released: 2021-01-20

Codename: (Numbats)

Changes

#2298

A recent change inadvertently caused an issue with DB migration utility such that it would attempt to drop indexes even when the dry-run option was specified. This has been fixed.

1.2.4HAPI FHIR 5.2.0 (Numbat)

 

Release Information

Released: 2020-11-19

Codename: (Numbat)

Changes

The version of a few dependencies have been bumped to the latest versions (dependent HAPI modules listed in brackets):

  • Jackson (Base): 2.10.0 -> 2.11.2
  • Flyway (JPA): 6.4.1 -> 6.5.4
  • JQuery (Testpage Overlay): 3.3.1 -> 3.5.1
  • UCUM (JPA): 1.0.2 -> 1.0.3
  • HttpClient (Client): 4.5.12 -> 4.5.13
  • Awesome Bootstrap Checkbos (Testpage Overlay): 1.0.1 -> 1.0.2
  • MomentJS (Testpage Overlay): 2.15.1 -> 2.27.0
  • Select2 (Testpage Overlay): 4.0.3 -> 4.0.13

The JPA Server SQL generator for handling FHIR search operations has been completely rewritten to no longer depend on the Hibernate QueryBuilder APIs. This rewrite produces much more efficient SQL in many cases and should dramatically increase performance in such cases. For example, a 10x speedup has been observed on Postgresql when searching a very large database where the search URL has multiple chained search params.

This new SQL builder will be disabled by default in HAPI FHIR 5.2.0 and Smile CDR 2020.11.R01, and can be enabled via a setting in the DaoConfig (HAPI FHIR) and Storage Module config (Smile CDR). Snapshot/prerelease builds will ship with this new SQL builder enabled by default, and the intention is to make this the default and ultimately remove the legacy SQL builder in the next quarterly release.

We highly encourage testing of this new feature, and welcome feedback on how it performs in your environment.

#2041

A new class called TransactionBuilder has been added. This class can be used to build FHIR Transaction Bundles easily.

#2045

The RemoteTerminologyServiceValidationSupport class used for connecting to a remote terminology service will no longer attempt to perform code validation for fields where the code system is implied, since there is no FHIR operation allowing this style of validation to be performed remotely.

#2051

The FHIR Client will now accept an HTTP 204 NO CONTENT as a response to a write operation such as a create/update/transaction/etc.

#2059

In the JPA server, when performing synchronous searches it is now possible to specify a limit and offset using a new (nonstandard) parameter called _offset. Thanks to Tuomo Ala-Vannesluoma for the pull request!

#2078

When using package support to install a package with STORE_AND_INSTALL mode, resources that are already present in the database will now be updated to the contents of the version in the package.

#2081

Operations for CodeSystem, ValueSet and ConceptMap will now support multiple CodeSystem versions.

#2081

Terminology loader for LOINC will now support specifying version and loading multiple versions of LOINC.

#2081

An implementation of CodeSystem validate-code operation has been added for R4 and R5.

#2083

The JPA search coordinator will now use worker threads sourced from a ThreadPoolTaskExecutor, in order to simplify the addition of decorators to those threads. Thanks to Tue Toft Nørgård for the pull requets!

#2087

Added new DaoConfig parameter called maximumTransactionBundleSize that if not-null will throw a PayloadTooLarge exception when the number of resources in a transaction bundle exceeds this size.

#2099

Stored SearchParameter resources with a status of DRAFT will no longer override and disable existing built-in search parameters. This is done in order to avoid issues caused by uploading NPM packages such as US Core that contain a large number of draft parameters.

#2104

EMPI enhancements. Added new IDENTIFIER matcher rule type that defines a matcher where two resources share the same value for a particular identifier system, or if no system is indicated, defines a matcher where two resources share any matching system,values identifier. Improved channel and batch troubleshooting logging. Added new controller layer to support non-fhir apis. Changed rule json format; replaced 'metric' with either matcher or simiarity that now have their own distinct subkeys.

#2118

Support for RDF Turle parsing and encoding has now been added. This support was previously partially implemented, but did not work correctly. A huge thanks to Josh Collins and Eric Prud'hommeaux of Janeiro Digital for the pull request!

#2131

A new _expunge parameter has been added to the DELETE operation when deleting multiple resources via a URL. For example DELETE http://www.example.com:8000/Observation?_expunge=true or DELETE http://www.example.com:8000/Observation?status=cancelled&_expunge=true. When the _expunge parameter is provided to DELETE then the matched resources and all of their history will be both deleted and expunged from the database. This will perform considerably faster than doing the delete and expunge separately. Note that Expunge must be enabled on the server for this to work.

#2141

The Package Installer has been enhanced to allow resources that do not have a url element to be loaded from a package. Resources without url will instead use identifier element.

#2142

A null check was added to the R4 CapabilityStatement generator, in order to improve the error message when a mandatory parameter is missed. Thanks to GitHub user @blangley28 for the contribution!

#2128

The version of Bootstrap used by the Testpage Overlay project has been upgraded from 3.4.0 to 4.5.2. Note that this is a major release upgrade, so any overlay implementations may require some modification to deal with changes to the Bootstrap framework.

#2145

In HAPI FHIR 5.1.0 JPA Server, if partitioning was enabled, but no interceptor was registered to the STORAGE_PARTITION_IDENTIFY_READ pointcut, the system would simply default to 'All Partitions'. This was not the intended behaviour, so this will now result in an error.

#1607

A performance bottleneck was fixed in the datetime datatypes that caused lock contention when parsing resources in heavily multithreaded environments. Thanks to GitHub user @abrsystematic for the pull request!

#2043

The JPA SearchParameetr validator did not reject custom Search Parameetrs with an invalid path expression consisting of only a resource type and no element name. Creating such a search parameter could cause strange indexing issues, so this has been added to the validator.

#2049

A potential NPE in the JPA server was fixed. This error could be triggered by searching for resources with unresolvable references. Thanks to Anders Havn for the pull request!

#2050

An issue was fixed where multiple JPA server updates to the same resource within the same database transaction would fail with a database constraint error.

#2062

A deadlock was fixed where the Database-backed Binary Storage service could lock the system up when running under very high contention.

#2097

A crash in the JPA server was fixed when performing a search containined two chained search parameters to date target types.

#2099

When using an NPM package spec in STORE_AND_INSTALL mode, conformance resources will only be stored if they have a status of active. This fixes a bug wgere installing the US Core IG caused searches to stop working due to draft Search Parameters.

#2101

In some circumstances when using a Plain Server, the generated CapabilityStatement could have duplciate Search Parameter definitions. This has been corrected.

#2104

EMPI bug fixes. Special characters in search param values (e.g. space) led to missed matches; these are now properly escaped so matches are accurately found. Candidates were failing to match when candidateSearchParams was empty; matches now work properly with empty candidateSearchParams. matchResultMap entries were incorrectly resolving if any named matchFields matched; they now correctly resolve only when ALL matchFields match.

#2112

When parsing XML encoded resources, if an xml:lang attribute was present in the narrative HTML, it would incorrectly have its prefix omitted. Thanks to Oliver Egger for the pull request!

#2113

When performing a _lastUpdated search in the JPA server where the parameter value(s) are supplied with date (not time) precision, a timezone bug could cause some resources to not be included. This has been corrected.

#2147

The _typeFilter parameter did not correctly work for JPA Bulk Export jobs. This has been corrected.

#2150

The In Memory search matcher (used for Subscriptions) could crash if a subscription was registered using the _source search parameter, and a resource was processed with no source value. This has been corrected.

#2162

When expanding a pre-expanded ValueSet using a filter, the filter was ignored and the pre-expansion was not used resulting in an inefficient and potentially incorrect expansion. This has been corrected.

#2164

The JPA Package loader was failing if the package had a description longer than 200 characters. This has been fixed.

1.2.5HAPI FHIR 5.1.0 (Manticore)

 

Release Information

Released: 2020-08-13

Codename: (Manticore)

Changes

The version of a few dependencies have been bumped to the latest versions (dependent HAPI modules listed in brackets):

  • Guava (JPA): 28.2-jre -> 29.0-jre
  • Jetty (CLI): 9.4.24.v20191120 -> 9.4.30.v20200611

#1637

An index has been added on the TRM_CONCEPT table. This index was previously missing, meaning that rebuilding large code systems took an abnormally long amount of time. Thanks to Jacob Stampe Mikkelsen for the pull request!

#1666

The email sender used by email subscriptions can now be configured with TLS parameters.

#1826

A new service has been added to the JPA server that fetches FHIR Implementation Guide NPM packages and installs the contained conformance resources into the JPA repository. Thanks to Martin Zacho Grønhøj for the pull request!

#1862

The Snapshot Generator now uses the R5 codebase for all versions of FHIR (similar to how the validator already worked). This means that the snapshot generator will be much more feature complete and hopefully have fewer bugs given the single codebase.

#1864

AuthorizationInterceptor can now fully secure GraphQL operations in the JPA server, meaning that it is possible to use compartment and type rules to restrict the specific data that is available through the GraphQL interface.

#1865

The validator will now correctly issue a warning instead of an error if a code can't be found when validating a code in a CodeSystem where the content mode (CodeSystem.content) has a value of fragment.

#1867

Initial implementation of lastn operation that uses an Elasticsearch v6 server to index observations.

#1871

In the JPA server, when indexing Date SearchParameters where the value being indexed is a FHIR Period that is missing either a lower bound or an upper bound, a default value representing an extreme 'beginning of time' or 'end of time' is now used. This allows range searches to return more accurate results.

#1893

Support for the :of-type modifier has been added to TokenParamModifier. Thanks to Alexander Lukyanchikov for the pull request!

#1896

Support has been added for GraphQL querying using an HTTP POST (with the query in the body). Thanks to Ibrohim Kholilul Islam for the pull request implementing this new feature!

#1911

Support for FHIR NPM Packages has been added to the JPA server. This new functionality allows packages to be installed to special tables within the FHIR JPA schema, and conformance resources used for validation.

#1917

The LOINC importer has been updated to support the file format used by the LOINC 2.68 release.

#1921

A new optional type parameter has been added to the $mark-all-resources-for-reindexing operation, allowing resources of a specific type to be marked.

#1926

Spring Batch has been added to HAPI FHIR in the hapi-fhir-jpaserver-batch project. hapi-fhir-jpaserver-base will make use of it for batch jobs

#1932

A new configuration bean called ValidationSettings has been added to the JPA server. This can be used to enable validation of reference target resources if necessary.

#1934

The RemoteTerminologyServiceValidationSupport validation support module, which is used to connect to external/remote terminology services, has been significantly enhanced to provide testing for supported CodeSystems and ValueSets. It will also now validate codes in fields that are not bound to a specific ValueSet.

#1936

Phonetic name search is now supported via ISearchParamRegistry.setStringEncoder().

#1939

The JPA server is now able to support _has queries where the linked search expression on the right hand side of the _has parameter is a second _has query.

#1951

REST Hook subscriptions may now specify a search expression to be used to fetch a collection of resources to deliver when a subscription matches.

#1966

The GraphQL module can now accept arrays of arguments as input to searches, and will treat them as OR'ed parameters. Thanks to Ibrohim Kholilul Isla for the pull request!

#1967

The HAPI FHIR CommonCodeSystemsTerminologyService validation support module now includes support for ISO 3166 (country codes).

#1971

A new interceptor called UserRequestRetryVersionConflictsInterceptor has been added to the JPA server. This interceptor allows clients to instruct the server to attempt to avoid returning an HTTP 409 (Version Conflict) if two concurrent client requests try to update the same resource at the same time.

#1982

The validator will now accept codes that are defined in a ValueSet where the valueset contains an enumeration of codes, and the CodeSystem URL refers to an unknown CodeSystem. This allows successful validation of ValueSets in several IGs that rely on the existence of grammar based systems.

#1984

Two new operations have been added for EMPI: $empi-clear and $empi-submit. $empi-clear will delete EMPI links, and related Person objects. $empi-submit will submit all matching resources for EMPI processing.

#1994

A few issues in the migrator when applying migrations against some versions of MSSQL were resolved

#2023

The JPA server maintains a cache of active SearchParameeter resources that can cause misleading results if a SearchParameter is changed and other resources that would be indexed by the changed SearchParameter are updated before the cache refreshes. A new interceptor has been added that should force a refresh sooner, especially on non-clustered systems.

#2025

A new interceptor has been added for the JPA server that selectively allows resource deletions to proceed even if there are valid references to the candidate for deletion from other resources that are not being deleted.

#1899

When submitting a transaction bundle containing a large number of resources being written, where the resources had tags or profile definitions, a number of redundant database calls have been optimized out. This should significantly improve performance for these scenarios.

#1937

Due to an inefficient SQL statement when performing searches with large numbers of _revincludes where the resources have tags, a large number of database roundtrips were produced when searching. This has been streamlined, greatly improving the response times for some searches.

#1963

When performing a search in the JPA server using a chained search parameter, an unnecessary resource type predicate was previously added to the generated SQL and has now been removed. This should improve performance on some queries.

#1945

When performing a JPA 'upsert' (a PUT to an ID that may or may not already exist) on a partitioned system, the partition interceptor will now be called once to determine the READ partition in order to find the candidate resource to update, and possibly a second time to determine the CREATE partition if a new row is actually being created. Previously only the CREATE partition was checked and used to perform the initial read.

#1952

HAPI FHIR has been migrated to use JUnit 5 (from JUnit 4) for unit testing. This change does not affect users of the library, but helps to make tests more maintainable.

#1857

Breaking Change: The method FhirContext#getResourceNames() has been renamed to FhirContext#getResourceTypes(). HAPI currently goes back and forth between the two, but is consolidating on Types.

#237

The R5 structure methods for working with extensions on arbitrary fields, e.g. getExtensionByUrl(String), removeExtension(String), getExtensionsByUrl(String) hasExtension(String), and getExtensionString(String) have been enhanced so that they now return modifier extensions as well as the non-modifier extensions they previously returned.

#1862

Breaking Change: The IValidationSupport interface has had one further change after the rewrite in HAPI FHIR 5.0.0. Instead of passing an IValidationSupport object as an argument to many methods on the interface, a context object is now used instead.

#1848

When parsing a resource into a custom structure (e.g. a custom class extended a built-in FHIR resource class), inter-resouirce references could contain invaliud java refeences to other resources. Thanks to Christian Ohr for reporting and fixing!

#1850

A new operation has been added to the JPA server called $diff. This operation can generate a FHIR Patch diff showing the changes between two versions of a resource, or even two separate resources. See Diff for more information.

#1850

The FHIR Patch format is now supported for patching resources, in addition to the previously supported JSON Patch and XML Patch.

#1850

When serializing a resource, the JSON Parser will now ignore any extensions that are present on an element if they do not have a URL or any children populated.

#1851

In HAPI FHIR 5.0.0, partitioned JPA servers were introduced. The documentation claimed that an interceptor implementing the STORAGE_PARTITION_IDENTIFY_READ was optional, but the server incorrectly made this mandatory. This has been corrected.

#1853

The @Interceptor annotation was not marked as inheritable, meaning that the order attribute was lost when using Spring proxies. Thanks to Tue Toft Nørgård for the pull request!

#1854

When using a SearchParameter with uniqueness enabled, the $expunge operation sometimes failed to expunge resources with a database constraint error. This has been fixed.

#1856

The subscription delivery queue in the JPA server was erroneously keeping both a copy of the serialized and the deserialized payload in memory for each entry in the queue, doubling the memory requirements. This also caused failures when delivering XML payloads in some configurations. This has been corrected.

#1863

Cascade deletes were failing in cases where the resource being deleted had more than 600 conflicts due to a hard-coded limit on the number of conflicts that the CascadingDeleteInterceptor was allowed to process at a time. This hard-coded limit has been replaced with an optional configuration parameter.

#1878

Several duplicate classes were removed from the testpage overlay, avoiding a warning on startup. Thanks to Joel Schneider for the pull request!

#1895

HAPI FHIR 5.0.0 introduced a regression in JPA validator performance, where a number of unnecessary database lookups were introduced. This has been corrected.

#1933

BaseValidationSupportWrapper.expandValueSet(...) and ValidationSupportChain.expandValueSet(...) were incorrectly replacing expansion options (i.e. offset and count) with null, causing these parameters to be ignored when invoking the ValueSet$expand operation. This has been corrected.

#1948

When validating resources containing codes in a ValueSet that included UCUM codes, the validator would incorrectly report that the code was valid even if it was not in the ValueSet. This has been corrected.

#1971

The create-package CLI command failed with a NPE if no package dependencies were specified. This has been corrected.

#1983

ConceptMap resources were blocked from uploading into the JPA server if the ConceptMap had a source and/or target URL defined at the ConceptMap level but not at the group level. This prevented some US Core resources from being successfully uploaded. This has been corrected.

#2003

In HAPI FHIR 4.2.0 and before, due to the lenient Gson parser it was possible to store data in the JPA server that contained invalid decimal numbers with no leading digits, e.g. .123 and -.123. When we moved to Jackson as a JSON parser, these values could no longer be parsed due to Jackson's more strict (and correct) interpretation of the JSON specification. Unfortunately this led to data previously stored in the database being unusable. A fix has been implemented that automatically adds a leading zero to any decimals that were previously saved in invalid state. New data will still be blocked from being added if it contains invalid JSON numbers.

#2005

When generating a snapshot for a StructureDefinition that extends another non-base StructureDefinition, if the parent SD did not have a snapshot itself, the child snapshot would be empty. This has been corrected.

#2006

When updating a resource with links that change, to reduce database operations, hapi-fhir reuses link index records. However, all the columns were being properly updated except for the source path column which was accidentally missed and continued to hold the previous value. This resulted in mismatched source paths and values. This has been corrected.

#2012

In some cases, the Bundle total was not getting filtered from search results when using the consent interceptor. Thanks to Jens Kristian Villadsen for reporting!

#2022

When performing a resource $expunge in the JPA server, in-memory caches caused issues if a forced ID was reused quickly enough (as can be the case in some testing scenarios). Thanks to GitHub user @janvdpol for reporting!"

#2026

An XSS vulnerability was reported in the HAPI FHIR Testpage Overlay module. Thanks to Will Davison of NCC Group (Manchester UK) for disclosing this vulnerability. Users of the HAPI FHIR Testpage Overlay can use a specially crafted URL to exploit an XSS vulnerability in this module, allowing arbitrary JavaScript to be executed in the user's browser. The impact of this vulnerability is believed to be low, as this module is intended for testing and not believed to be widely used for any production purposes. Nonetheless, we recommend all users of the affected module upgrade immediately. A complete audit of the affected codebase has been completed in order to detect and resolve any similar issues.

#1855

A very old feature that is not believed to be used anywhere has been removed: The ServerProfileProvider is a special resource provider that was automatically registered to HAPI FHIR REST servers, and served up StructureDefinitions that were registered to the FhirContext. Registering custom StructureDefinitions against the FhirContext for exposure through the REST API (as what was then the /Profile endpoint) was planned to be a common feature during the DSTU1 lifecycle but did not turn out to be a useful approach. This feature was mostly forgotten about until the logic for selecting resource provider handler methods was revamped and the old mechanism suddenly became the default resource provider for StructureDefinition resources in the JPA server. We don't expect any negative impact by this change, please post in our mailing list if you disagree.

1.2.6HAPI FHIR 5.0.2 (Labrador)

 

Release Information

Released: 2020-06-02

Codename: (Labrador)

Changes

This release corrects a snapshot dependency on org.hl7.fhir.core that was accidentally left in HAPI FHIR 5.0.1.

The default setting for the partition mode's Include Hashes in Search Indexes setting was incorrectly set to true in HAPI FHIR 5.0.0 and has now been changed to false, as this is a more sensible default. Note that this wil affect existing systems that are trying this feature out. A manual reindex of data may be required.

1.2.7HAPI FHIR 5.0.1 (Labrador)

 

Release Information

Released: 2020-05-15

Codename: (Labrador)

Changes

#1842

When performing queries with multiple chained search parameters, such as 'Observation?subject.identifier=FOO&specimen.identifier=BAR', an unnecessary SQL join was introduced into the resulting query. This was inefficient, and made it particularly hard for the RDBMS optimizer to pick an efficient query plan in some cases. This is not fixing a regression (this issue has always existed in HAPI FHIR JPA) but it was deemed sufficiently important to merit a dedicated point release.

#1847

Issue #1849 added two new search columns for date SearchParameters that are used to provide searching at the day granularity in a timezone independent way. These new columns require a new database index that was missed in the original merge.

1.2.8HAPI FHIR 5.0.0 (Labrador)

 

Release Information

Released: 2020-05-13

Codename: (Labrador)

Changes

The version of a few dependencies have been bumped to the latest versions (dependent HAPI modules listed in brackets):

  • Hibernate ORM (JPA): 5.4.6 -> 5.4.14
  • Hibernate Search (JPA): 5.11.3 -> 5.11.5
  • Hibernate Validator (JPA): 5.4.2.Final -> 6.1.3.Final
  • Guava (JPA): 28.0 -> 28.2
  • Spring Boot (Boot): 2.2.0.RELEASE -> 2.2.6.RELEASE
  • FlywayDB (JPA) 6.1.0 -> 6.4.1
  • Apache HTTPCliient (JPA): 4.5.9 -> 4.5.12
  • Apache HTTPCore (JPA): 4.4.11 -> 4.4.14
  • Commons Compress (All): 1.19 -> 1.20

#1710

The classes BaseOrListParam and BaseParam now have public visibility in order to make it easier to create more generic APIs. Thanks to GitHub user @ibacher for the pull request!

#1728

Fields of type canonical were not previously indexed by the JPA server, meaning that some default search parameters could not be honoured (e.g. StructureDefinition:valueset). This is now corrected.

#1736

When performing large terminology concept additions via the delta addition service, concepts will now be added via the deferred storage service, meaning that they will be added in small incremental batches instead of as a part of one large transaction. This helps to avoid timeouts and memory issues when uploading large collections of concepts.

#1742

When performing a terminology delta ADD operation, if the number of codes being added is large the codes will be added in small batches via an asynchronous scheduled task in order to avoid overwhelming the database with a large operation.

#1749

A new constructor has been added to RestfulServer that accepts an InterceptorService. Thanks to gematik FuE for the pull request!

#1760

Adds support for chained parameters in a _has query. For example GET /Patient?_has:Observation:subject:device.identifier=1234-5. Adds a performance warning on any queries that use an unqualified resource in a chain which ends up resolving to 2 or more candidate target types. Thanks to Jean-Francois Briere for the patch.

#1769

A new built-in server interceptor called FhirPathFilterInterceptor has been added. This interceptor evaluates an arbitrary FHIRPath expression against the resource being returned and replaces the response with a Parameters resource containing the results of the evaluation.

#1772

The JPA server now allows chained searches on the _type parameter. For example, the following could be used to find all Encounters with a context of type Group: Encounter?subject._type=Group.

#1774

The REST Server will now raise an error if a client tries to perform a FHIR read operation while using URL paramaters that are specific to FHIR search operations. This should help clients who are mistaking the semantics between the two operations, as previously the search parameters were simply ignored leading to confusion. Thanks to Jafer Khan for implementing this!

#1776

A new server interceptor called ResponseSizeCapturingInterceptor has been added. This interceptor captures and makes available the number of characters written (pre-compression if Gzip compression is being used) to the HTTP response stream for FHIR responses.

#1783

The client interceptor pointcuts CLIENT_REQUEST and CLIENT_RESPONSE now allow a parameter of type IRestfulClient to be injected, containing a reference to the client making the request. In addition, CLIENT_REQUEST interceptors are now able to modify the URL of the request before it is performed.

#1783

In the JPA server, the ModelConfig setting 'DefaultSearchParamsCanBeOverridden' now has a default value of true (previously this was false). In addition, when creating/updating a SearchParameter resource, the system will now raise an error if the client is attempting to override a built-in SearchParameter when this setting is disabled (previously this was silently ignored).

#1783

In the JPA sevrer, if overriding built-in search parameters is not enabled, the server will now return an error if a client tries to create a SearchParameter that is trying to override one. Previously, the SearchParameter would be stored but silently ignored, which was confusing.

#1783

A new client interceptor called UrlTenantSelectionInterceptor has been added. This interceptor allows the dynamic selection of a tenant ID on servers that are using URL Base Tenant Selection.

#1788

The ApacheProxyAddressStrategy has been improved to add support for additional proxy headers inclusing X-Forwarded-Host, X-Forwarded-Proto, X-Forwarded-Port, and X-Forwarded-Prefix. Thanks to Thomas Papke for the pull request!

#1793

When parsing JSON resources, if an element contains an invalid value, the Parser Error Handler did not have access to the actual name of the element being parsed. This meant that errors lacked useful detail in order to diagnose the issue. This has been corrected. Thanks to GitHub user @jwalter for reporting!

#1797

The HAPI FHIR instance validator now includes validation for currency types (ISO 4217)

#1798

New mthods have been added to DateClientParam allowing searching at MILLIS precision. Thanks to David Gileadi for the pull request!

#1802

In a plain server, if a Resource Provider class had two methods with the same parameter names (as specified in the @OptionalParam or @RequiredParam) but different cardinalities, the server could sometimes pick the incorrect method to execute. The selection algorithm has been improved to no longer have this issue, and to be more consistent and predictable in terms of which resource provider method is selected when the choice is somewhat ambiguous.

#1804

Support for HAPI FHIR cascading deletes has been added to the Generic Client.

#1812

The JAX-RS server will now scan and serve ResourceProvider methods defined in super-classes as well. Thanks to Zhe Wang for the pull request!

#1824

Native support for UCUM has been added to the validation stack, meaning that UCUM codes can be validated at runtime without the need for any external validation.

#1831

Indexing for the :text modifier can now be globally or selectively disabled in the JPA server. This can have a measurable impact on index sizes and write speed in servers with large numbers of token indexes.

#1836

In HAPI FHIR 4.2.0, when performing a Bulk Export on a server with Binary Storage enabled, the bulk export files were not able to take advantage of the externalized binary stroage and would be stored in the relational DB. This has now been enhanced to allow bulk export files to store externally.

#1838

Date searches can be performed relative to 'now' using the %now parameter value. For example, to search for Procedures with a date later than now, you can search for /Procedure?date=ge%now. Note the '%' will need to be URL escaped so the actual URL will be /Procedure?date=ge%25now. The way this works is the server substitutes %now with the current date and time in the standard FHIR format yyyy-MM-ddTHH:mm:ss before submitting it to the FHIR Storage module. Similarly date searches can be performed relative to 'today' using the '%today' parameter value. '%today' works the same as '%now' except that it searches as a 'date' type as opposed to a 'dateTime' type.

#1702

Loading of _include and _revinclude values has been optimized to be slightly faster

#1726

When performing date range searches in the JPA server, the server was generating extra unneccessary joins in the generated SQL. This has been streamlined, which should result in faster searches when performing date ranges.

#1813

History operations in the JPA server have been significantly optimized to remove the number of SQL SELECT statements, and to completely eliminate any INSERT statements. This should have a positive effect on heavy users of history operations. In addition, history operations will no longer write an entry in the query cache (HFJ_SEARCH) table which should further improve performance of this operation.

#1693

Adjusted schema definitions for Resource and Resource History tables to eliminate circular dependencies with Forced ID table and to improve performance when expunging large numbers of resources.

#1698

Removed the SEARCH_LAST_RETURNED column of the HFJ_SEARCH table. HAPI FHIR updated the HFJ_SEARCH table with every request, but this led to unecessary database load. The purpose of this column was to ensure that search results were kept around long enough for systems that needed them for paging (default one hour). When expiring search results, we used to add one hour to SEARCH_LAST_RETURNED to determine the expiry time. However, the length of time where a search result could be updated was relatively small (default one minute). So rather than keeping track of the expiry time to expire exactly one hour after the last returned time, hapi now simply expires after the maximum possible length of time (default one hour plus one minute). This eliminates the need to update the HFJ_SEARCH table with every search.

#1715

The version converters for all versions except R4/R5 have been reworked to be split into individual classes per resource type (the R4/R5 converters were already organized this way). Thanks to Mark Iantorno for a huge effort to write a Java source parser/serializer to acomplish this task.

#1769

Breaking Change: The IFluentPath interface has been renamed to IFhirPath, and the FhirContext#newFluentPath() method has been replaced with an equivalent FhirContext.newFhirPath(). The FhirPath expression language was initially called FluentPath before being renamed, so this change brings HAPI FHIR inline with the correct naming.

#1790

Breaking Change: Several classes in the JPA server have been moved to new packages, including the DaoConfig and IDao interfaces. These classes have not changed in terms of functionality, but existing projects may need to adjust some package import statements.

#1804

Breaking Change: The Generic/Fluent delete() operation now returns a MethodOutcome object instead of an OperationOutcome. The OperationOutcomoe is still available direcly by querying the MethodOutcome object, but this change makes the delete() method more consistent with other similar methods in the API.

Breaking Change: Some R4 and R5 structure fields containing a code value with a Required (closed) binding did not use the java Enum type that was generated for the given field. These have been changed to use the Enum values where possible. This change does not remove any functionality from the model but may require a small amount of re-coding to deal with new setter/getter types on a few fields.

#1807

New Feature: A new feature has been added to the JPA server called **Partitioning. This feature allows data to be segregated using a user defined partitioning strategy. This can be leveraged to take advantags of native RDBMS partition strategies, and also to implement multitenant servers.

#1841

Breaking Change: The FHIR R5 draft definitions have been updated to the current 'Preview 2' definitions (FHIR 4.4.0).

DSTU3 searches using near-distance only worked on Location resources directly. It now works on chained searches on resources with a location. E.g. PractitionerRole?location.near-distance=1.0 now works properly.

#1583

Breaking Change: The HAPI FHIR Validation infrastructure has changed significantly under the hood. Existing users of the validator may need to change package declarations (as FhirInstanceValidator and several other related classes have been moved) and potentially add new modules to their Validation Support Chain. See Migrating to HAPI FHIR 5.x for details on how to account for this change in your code.

#1499

When performing a search with a DateParam that has DAY precision, rely on new ordinal date field for comparison instead of attempting to find oldest and newest instant that could be valid.

#1717

ValueSet expansions containing lists of terms did not correctly expand when backed by ElasticSearch due to the use of a feature not supported in ES. Thanks to Jens Villadsen for reporting!

#1721

When performing a terminology delta ADD operation, existing parent-child links were often deleted and recrreated needlessly during operations, which could result in a deadlock. This has been resolved.

#1732

In the JPA server, quickly deleting a resource and then performing a query that had recently returned that search result could cause a cached stub resource (containing no data but with an ID and metadata populated) to be returned. This has been corrected.

#1734

The Pointcut JavaDoc had an incorrect link from one pointcut to another and has been fixed. Thanks to Bert Roos for the pull request!

#1742

When performing a search in the JPA server where the only parameter was a _has parameter, the server did not respect the resource typename being searched for, causing false positive search results. This has been corrected.

#1742

When validating a resource, the validator will now report an error if the resource declares conformance to an unknown or invalid profile URL via the Resource.meta.profile declaration. Previously this was a warning and did not block successful validation.

#1759

When deleting searches from the query cache where a large number of searches with a large number of results were present, the system would repeatedly mark the same rows as deletion candidates. This put unneccessary pressure on the database and has been corrected.

#1761

A minor regression in 4.2.0 was introduced, where JPA searches using the _id search parameter often had a duplicate SQL predicate in their where clause. This issue may not have caused any bad effects on some environments, but it did look strange in SQL logs and has been corrected.

#1763

In servers, when requesting _summary=count, the response Bundle.type value was filtered, leading to an invalid response bundle. This has been corrected. Thanks to GitHub user @Legi429 for reporting!

#1770

When parsing Bundles, contained resoures from other entries in the Bundle could incorrecly be stitched into a target resource if they had the same local ID. Thanks to August Langhout for the pull request!

#1778

When encoding a resource, a crash could occur if the resource had a contained Bundle resource. This is not commonly done, but there are valid scenarios for doing so.

#1791

The GraphQL Expression parser sometimes fails and reports unhelpful error messages when using search arguments. Thanks to Ibrohim Kholilul Islam for the pull request!

#1794

A bug in the JPA server prevented Client Resource ID mode from being set to NOT_ALLOWED when Server Resource ID mode was set to UUID. Thanks to GitHub user @G-2-Z for reporting!

#1801

In previous versions of HAPI FHIR, the server incorrectly silently accepted decimal numbers in JSON with no leading numbers (e.g. .123), as well as decimal numbers with more than one leading zero (e.g. 00.123). These will now be rejected by the JSON parser. Any values with this string that have previously been stored in the JPA server database will now automatically normalize the value to 0.123.

#1801

When invoking JPA DAO methods programatically to store a resource (as opposed to using the FHIR REST API), if the resource being stored had any contained resources, these would sometimes not be visible to the search parameter indexer, leading to missing search params. This is a very fringe use case, but a workaround has been put in place to solve it.

#1806

The JPA server ElasticSearch provider failed to initialize if username/password credentials were not explicitly provided, meaning it could not run on AWS-supplied ElasticSearch. Thanks to Maciej Kucharek for the pull request!

#1810

The text styling on the Testpage Overlay homepage has been improved to use native Bootstrap warning colours. Thanks to Joel Schneider for the pull request!

#1829

In the JPA server, performing a search where the only search parameter was the _tag parameter could cause resources of the wrong type to be included in search results. This has been corrected.

#1837

The FHIR R4 validation resources (StructureDefintion, ValueSet, etc) were not updated to the R4 4.0.1 technical correction versions in HAPI FHIR 4.2.0. This has been corrected.

1.2.9HAPI FHIR 4.2.0 (Koala)

 

Release Information

Released: 2020-02-15

Codename: (Koala)

Changes

The version of a few dependencies have been bumped to the latest versions (dependent HAPI modules listed in brackets):

  • Jetty (CLI): 9.4.14.v20181114 -> 9.4.23.v20191118
  • Spring (JPA, Testpage): 5.2.1 -> 5.2.3 (addresses CVE-2020-5398 and CVE-2020-5397)

#1588

Support for several new operators has been added to the _filter support in the JPA server. Thanks to Anthony Sute for the Pull Request!

#1649

Support for LOINC 2.67 file format changes has been added to the JPA Server LOINC uploader. Thanks to Dan Vreeman for reporting!

In the JPA server, a new setting called setPopulateIdentifierInAutoCreatedPlaceholderReferenceTargets(boolean) has been added to the DaoConfig. If this setting is enabled, when creating placeholder resources, the Reference.identifier value is copied to the target resource if possible.

#1694

It is now possible to specify resource provider method annotations on interface methods implemented by resource provider classes, as opposed to needing to specify them directly on the concrete class. Thanks to Tue Toft Nørgård for the pull request!

Searching Location.position by latitude, longitude and distance for DSTU3, R4 and R5 is now supported using a simple 'box' search. Locations falling within a box with length and width of 2 * distance, centred on specified latitude,longitude are matched. If no distance is provided, the coordinates must match exactly.

Chained searches using the _has search parameter as the chain value are now supported by the JPA server.

#981

Support has been added to the server (plain and JPA) for querying with _count=0 as a URL parameter.

#1660

A significant performance improvement was added to the Json and XML parsers when parsing large Bundle resources. Throughput for parsing these resources has been improved by roughly 50%. Thanks to Rok Bertoncelj and Bogdan Solga for providing analysis and insight that triggered this change.

When parsing Bundle resources containing other resources, XML/JSON parsers have an option called "override resource ID with bundle entry fullUrl". This option previously caused any value found in Bundle.entry.fullUrl to override any value found in Bundle.entry.resource.id (meaning that the parsed resource would take its ID from the fullUrl even if that ID disagreed with the ID found in the resource itself. As of HAPI FHIR 4.1.0 the value in Bundle.entry.fullUrl will only be used to set the parsed resource ID if the resource has no ID present.

Changed database migration to use flyway. This adds a new table called FLY_HFJ_MIGRATION that records all database migration tasks that have already been applied. The hapi-fhir-cli migrate tool has been changed to use flyway. Learn more about flyway here: https://flywaydb.org/.

The IRestfulClient#registerInterceptor and IRestfulClient#unregisterInterceptor methods now take Object as an argument instead of IClientInterceptor, allowing client interceptors to now be migrated to the new interceptor framework.

#1583

As of FHIR R4, some fields that were previously of type reference are now of type canonical. One example is QuestionnaireResponse.questionnaire. Technically this means that this field should no longer contain a relative reference, but as they are sometimes used that way, HAPI FHIR will now try to be permissive and will index relative link canonical fields such as (Questionnaire/123) as though it actually was a local relative link. Thanks to Dean Atchley for reporting and providing a test case!

#1610

A missing mandatory was added to the SNOMED CT CodeSystem that is uploaded when SCT is uploaded to the JPA server. Thanks to Anders Havn for the pull request!

#1643

When validating resources containing custom valuesets defined in PrePopulatedValidationSupport outside of the JPA server, sometimes code systems could not be found resulting in false negative errors.

#1650

Several misleading comments in documentation code snippets were fixed. Thanks to Jafer Khan for the pull request!

#1603

The client threw a NullPointerException in some circumstances when it received an HTTP 201 No Content response from the server. This has been corrected. Thanks to Petro Mykhailysyn for the pull request!

#1671

When performing the $expunge operation in the JPA server, the operation sometimes failed if a resource being expunged had historical versions that did not contain any tags. This has been corrected.

#1676

When validating an XML resource, the validatin failed if the resource contained an xsi:schemaLocation declaration. This has been corrected. Thanks to Brian Kaney for reporting!

#1679

An issue with the new flyway migrator hashCode generation was resolved. Thanks to Jafer Khan for the pull request!

#1658

When parsing HTML Narratives, the lang attribute was stripped from the outer DIV tag if present. Thanks to Sean McIlvenna for reporting!

#1655

When using a custom structure that changes the cardinality from 0..* to 0..1, the Parser was encoding a plain field instead of an array (as required by the FHIR specification). Thanks to Petro Mykhailysyn for the pull request!

A memory leak was resolved in the JPA terminology service delta upload operations.

ValueSet PreCalculation did not successfully expand valuesets when Lucene was not enabled in the JPA server. This has been corrected.

#1689

A correction was made to the narrative generation documentation. Thanks to GitHub user dionmcm for the pull request!

#1613

ValueSet Precalculation sometimes failed on Oracle DBs due to an invalid SQL function. This has been corrected.

A ConcurrentModificationException was sometimes thrown when performing a cascading delete. This has been corrected.

#1624

The constructor for Verdict.java was inadvertantly made private, preventing custom rules from being written. Thanks to Jafer Khan for the pull request!