Skip to content

Commit

Permalink
issue #3242 - scope search-system and search-history for fhirVersion
Browse files Browse the repository at this point in the history
1. introduce enums and utilities for working with resource type names
and fhirVersion values ('4.0' and '4.3')
2. use those to provide a better abstraction for working with the
fhir-server-config `fhirServer/resources` property group
(ResourcesConfigAdapter)
3. move fhirVersion MIME-type parameter processing into a new JAX-RS
RequestFilter FHIRVersionRequestFilter and update tests accordingly
4. update FHIRPersistenceUtil.parseSystemHistoryParameters to take into
account the requested fhirVersion and scope the HistoryContext
appropriately
5. update SearchUtil.parseQueryParameters to take into account the
requested fhirVersion and scope the SearchContext appropriately

Signed-off-by: Lee Surprenant <lmsurpre@us.ibm.com>
  • Loading branch information
lmsurpre committed Apr 8, 2022
1 parent 4f23fa2 commit 58d6eb9
Show file tree
Hide file tree
Showing 33 changed files with 885 additions and 497 deletions.
36 changes: 22 additions & 14 deletions fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfigHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.logging.Logger;

import com.ibm.fhir.config.PropertyGroup.PropertyEntry;
import com.ibm.fhir.core.FHIRVersionParam;

import jakarta.json.JsonValue;

Expand All @@ -22,7 +23,7 @@
*/
public class FHIRConfigHelper {
private static final Logger log = Logger.getLogger(FHIRConfigHelper.class.getName());

//Constants
public static final String SEARCH_PROPERTY_TYPE_INCLUDE = "_include";
public static final String SEARCH_PROPERTY_TYPE_REVINCLUDE = "_revinclude";
Expand Down Expand Up @@ -84,7 +85,7 @@ private static JsonValue getPropertyFromTenantOrDefault(String propertyName) {
try {
if (propertyName.startsWith(FHIRConfiguration.PROPERTY_DATASOURCES)
|| propertyName.startsWith(FHIRConfiguration.PROPERTY_PERSISTENCE_PAYLOAD)) {
// Issue #639 and #3416. Prevent datasource/payload lookups from falling back to
// Issue #639 and #3416. Prevent datasource/payload lookups from falling back to
// the default configuration which breaks tenant isolation.
result = null;
} else {
Expand Down Expand Up @@ -160,24 +161,31 @@ private static <T> T getTypedProperty(Class<T> expectedDataType, String property
}

return (result != null ? result : defaultValue);
}
}

/**
* Get the set of supported resource types for tenantId in the FHIRRequestContext
* @return an immutable set of resource type names that isn't null
* Get the set of supported resource types for the latest supported FHIRVersion
* and the tenantId in the FHIRRequestContext
* @return an immutable non-null set of resource type names that isn't null
* @throws IllegalStateException if there is an unexpected issue while processing the config
*/
public static Set<String> getSupportedResourceTypes() {
return getSupportedResourceTypes(FHIRVersionParam.VERSION_43);
}

/**
* Get the set of supported resource types for the passed fhirVersion
* and the tenantId in the FHIRRequestContext
* @param fhirVersion
* @return an immutable non-null set of resource type names for the passed fhirVersion
* @throws IllegalStateException if there is an unexpected issue while processing the config
*/
public static Set<String> getSupportedResourceTypes(FHIRVersionParam fhirVersion) {
PropertyGroup rsrcsGroup = FHIRConfigHelper.getPropertyGroup(FHIRConfiguration.PROPERTY_RESOURCES);
try {
ResourcesConfigAdapter configAdapter = new ResourcesConfigAdapter(rsrcsGroup);
return configAdapter.getSupportedResourceTypes();
} catch (Exception e) {
log.throwing(FHIRConfigHelper.class.getName(), "getSupportedResourceTypes", e);
throw new IllegalStateException(e);
}
ResourcesConfigAdapter configAdapter = new ResourcesConfigAdapter(rsrcsGroup, fhirVersion);
return configAdapter.getSupportedResourceTypes();
}

/**
* Retrieves the search property restrictions.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
import java.util.stream.Collectors;

import com.ibm.fhir.config.PropertyGroup.PropertyEntry;
import com.ibm.fhir.core.FHIRVersionParam;
import com.ibm.fhir.core.ResourceTypeName;
import com.ibm.fhir.core.util.ResourceTypeHelper;


/**
* An abstraction for the ibm-fhir-server fhirServer/resources property group
Expand All @@ -38,8 +41,8 @@ public class ResourcesConfigAdapter {
private boolean isWholeSystemSearchSupported = true;
private boolean isWholeSystemHistorySupported = true;

public ResourcesConfigAdapter(PropertyGroup resourcesConfig) {
supportedTypes = computeSupportedResourceTypes(resourcesConfig);
public ResourcesConfigAdapter(PropertyGroup resourcesConfig, FHIRVersionParam fhirVersion) {
supportedTypes = computeSupportedResourceTypes(resourcesConfig, fhirVersion);

if (resourcesConfig == null) {
for (Interaction interaction : Interaction.values()) {
Expand Down Expand Up @@ -91,7 +94,7 @@ public boolean isHistoryRestricted() {
}

/**
* @return an immutable, non-null set of concrete supported resource types
* @return an immutable, non-null set of supported resource types for the given fhirVersion
* @throws Exception
*/
public Set<String> getSupportedResourceTypes() {
Expand All @@ -100,6 +103,7 @@ public Set<String> getSupportedResourceTypes() {

/**
* @return an immutable, non-null set of concrete resource types that are configured for the given interaction
* and fhirVersion
*/
public Set<String> getSupportedResourceTypes(Interaction interaction) {
Set<String> result = typesByInteraction.get(interaction);
Expand All @@ -110,14 +114,17 @@ public Set<String> getSupportedResourceTypes(Interaction interaction) {
}

/**
* Construct the list of concrete supported resource types from the passed configuration
* Construct the list of supported resource types from the passed configuration and fhirVersion
*
* @param resourcesConfig
* @param fhirVersion
* @return
*/
private Set<String> computeSupportedResourceTypes(PropertyGroup resourcesConfig) {
private Set<String> computeSupportedResourceTypes(PropertyGroup resourcesConfig, FHIRVersionParam fhirVersion) {
Set<String> applicableTypes = ResourceTypeHelper.getResourceTypesFor(fhirVersion);

if (resourcesConfig == null || resourcesConfig.getBooleanProperty("open", true)) {
return ALL_CONCRETE_TYPES;
return applicableTypes;
}

Set<String> result = new LinkedHashSet<String>();
Expand All @@ -132,10 +139,11 @@ private Set<String> computeSupportedResourceTypes(PropertyGroup resourcesConfig)
continue;
}

if (ALL_CONCRETE_TYPES.contains(name)) {
if (applicableTypes.contains(name)) {
result.add(name);
} else if (log.isLoggable(Level.FINE)) {
log.fine("Configured resource type '" + name + "' is not valid.");
log.fine("Configured resource type '" + name + "' is not valid "
+ "or not applicable for fhirVersion " + fhirVersion.value());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.ibm.fhir.config.Interaction;
import com.ibm.fhir.config.PropertyGroup;
import com.ibm.fhir.config.ResourcesConfigAdapter;
import com.ibm.fhir.core.FHIRVersionParam;

import jakarta.json.Json;
import jakarta.json.JsonObject;
Expand All @@ -24,16 +25,31 @@ public class ResourcesConfigAdapterTest {
public void testGetSupportedResourceTypes() throws Exception {
JsonObject json = Json.createObjectBuilder().build();
PropertyGroup pg = new PropertyGroup(json);
ResourcesConfigAdapter resourcesConfigAdapter = new ResourcesConfigAdapter(pg);
ResourcesConfigAdapter resourcesConfigAdapter = new ResourcesConfigAdapter(pg, FHIRVersionParam.VERSION_40);

Set<String> supportedResourceTypes = resourcesConfigAdapter.getSupportedResourceTypes();
assertEquals(supportedResourceTypes.size(), 146);
assertEquals(supportedResourceTypes.size(), 125);

System.out.println(supportedResourceTypes);

for (Interaction interaction : Interaction.values()) {
supportedResourceTypes = resourcesConfigAdapter.getSupportedResourceTypes(interaction);
assertEquals(supportedResourceTypes.size(), 146);
assertEquals(supportedResourceTypes.size(), 125);
}
}

@Test
public void testGetSupportedResourceTypes_r4b() throws Exception {
JsonObject json = Json.createObjectBuilder().build();
PropertyGroup pg = new PropertyGroup(json);
ResourcesConfigAdapter resourcesConfigAdapter = new ResourcesConfigAdapter(pg, FHIRVersionParam.VERSION_43);

Set<String> supportedResourceTypes = resourcesConfigAdapter.getSupportedResourceTypes();
assertEquals(supportedResourceTypes.size(), 141);

for (Interaction interaction : Interaction.values()) {
supportedResourceTypes = resourcesConfigAdapter.getSupportedResourceTypes(interaction);
assertEquals(supportedResourceTypes.size(), 141);
}
}
}
56 changes: 35 additions & 21 deletions fhir-core/src/main/java/com/ibm/fhir/core/FHIRMediaType.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 2019, 2021
* (C) Copyright IBM Corp. 2019, 2022
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -8,7 +8,8 @@

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.core.MediaType;
Expand All @@ -18,29 +19,42 @@
*/
public class FHIRMediaType extends MediaType {

public final static String SUBTYPE_FHIR_JSON = "fhir+json";
public final static String APPLICATION_FHIR_JSON = "application/" + SUBTYPE_FHIR_JSON;
public final static MediaType APPLICATION_FHIR_JSON_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON);
// use com.ibm.fhir.core.FHIRVersionParam instead
private static final String VERSION_40 = "4.0";
private static final String VERSION_43 = "4.3";
private static final String VERSION_401 = "4.0.1";
private static final String VERSION_430 = "4.3.0";

public final static String SUBTYPE_FHIR_XML = "fhir+xml";
public final static String APPLICATION_FHIR_XML = "application/" + SUBTYPE_FHIR_XML;
public final static MediaType APPLICATION_FHIR_XML_TYPE = new MediaType("application", SUBTYPE_FHIR_XML);
// Supported values for the MIME-type parameter fhirVersion.
// https://www.hl7.org/fhir/http.html#version-parameter
public static final String FHIR_VERSION_PARAMETER = "fhirVersion";
public static final Set<String> SUPPORTED_FHIR_VERSIONS =
Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(VERSION_40, VERSION_401, VERSION_43, VERSION_430)));

private static final Map<String,String> fhirVersion40ParameterMap = Collections.singletonMap(FHIR_VERSION_PARAMETER, VERSION_40);
private static final Map<String,String> fhirVersion43ParameterMap = Collections.singletonMap(FHIR_VERSION_PARAMETER, VERSION_43);

public static final String SUBTYPE_FHIR_JSON = "fhir+json";
public static final String APPLICATION_FHIR_JSON = "application/" + SUBTYPE_FHIR_JSON;
public static final MediaType APPLICATION_FHIR_JSON_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON);
public static final MediaType APPLICATION_FHIR_40_JSON_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON, fhirVersion40ParameterMap);
public static final MediaType APPLICATION_FHIR_43_JSON_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON, fhirVersion43ParameterMap);

public final static String SUBTYPE_JSON_PATCH = "json-patch+json";
public final static String APPLICATION_JSON_PATCH = "application/" + SUBTYPE_JSON_PATCH;
public final static MediaType APPLICATION_JSON_PATCH_TYPE = new MediaType("application", SUBTYPE_JSON_PATCH);
public static final String SUBTYPE_FHIR_XML = "fhir+xml";
public static final String APPLICATION_FHIR_XML = "application/" + SUBTYPE_FHIR_XML;
public static final MediaType APPLICATION_FHIR_XML_TYPE = new MediaType("application", SUBTYPE_FHIR_XML);
public static final MediaType APPLICATION_FHIR_40_XML_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON, fhirVersion40ParameterMap);
public static final MediaType APPLICATION_FHIR_43_XML_TYPE = new MediaType("application", SUBTYPE_FHIR_JSON, fhirVersion43ParameterMap);

public final static String SUBTYPE_FHIR_NDJSON = "fhir+ndjson";
public static final String SUBTYPE_JSON_PATCH = "json-patch+json";
public static final String APPLICATION_JSON_PATCH = "application/" + SUBTYPE_JSON_PATCH;
public static final MediaType APPLICATION_JSON_PATCH_TYPE = new MediaType("application", SUBTYPE_JSON_PATCH);

public static final String SUBTYPE_FHIR_NDJSON = "fhir+ndjson";
public static final String APPLICATION_NDJSON = "application/" + SUBTYPE_FHIR_NDJSON;
public final static MediaType APPLICATION_FHIR_NDJSON_TYPE = new MediaType("application", SUBTYPE_FHIR_NDJSON);
public static final MediaType APPLICATION_FHIR_NDJSON_TYPE = new MediaType("application", SUBTYPE_FHIR_NDJSON);

public final static String SUBTYPE_FHIR_PARQUET = "fhir+parquet";
public static final String SUBTYPE_FHIR_PARQUET = "fhir+parquet";
public static final String APPLICATION_PARQUET = "application/" + SUBTYPE_FHIR_PARQUET;
public final static MediaType APPLICATION_FHIR_PARQUET_TYPE = new MediaType("application", SUBTYPE_FHIR_PARQUET);

// Supported values for the MIME-type parameter fhirVersion.
// https://www.hl7.org/fhir/http.html#version-parameter
public static final String FHIR_VERSION_PARAMETER = "fhirVersion";
public static final Set<String> SUPPORTED_FHIR_VERSIONS =
Collections.unmodifiableSet(new HashSet<>(Arrays.asList("4.0","4.0.1","4.3","4.3.0")));
public static final MediaType APPLICATION_FHIR_PARQUET_TYPE = new MediaType("application", SUBTYPE_FHIR_PARQUET);
}
52 changes: 52 additions & 0 deletions fhir-core/src/main/java/com/ibm/fhir/core/FHIRVersionParam.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* (C) Copyright IBM Corp. 2022
*
* SPDX-License-Identifier: Apache-2.0
*/
package com.ibm.fhir.core;

/**
* Enum constants for the allowed values of the fhirVersion MIME-type parameter
*/
public enum FHIRVersionParam {
VERSION_40("4.0"),
VERSION_43("4.3");

private final String value;

FHIRVersionParam(String value) {
this.value = value;
}

/**
* @return
* The String value of the fhirVersion parameter
*/
public java.lang.String value() {
return value;
}

/**
* Factory method for creating FHIRVersionParam values from a passed string value.
*
* @param value
* A string that matches one of the allowed FHIRVersionParam values
* @return
* The corresponding FHIRVersionParam or null if a null value was passed
* @throws IllegalArgumentException
* If the passed string is not null and cannot be parsed into an allowed FHIRVersionParam value
*/
public static FHIRVersionParam from(String value) {
if (value == null) {
return null;
}
switch (value) {
case "4.0":
return VERSION_40;
case "4.3":
return VERSION_43;
default:
throw new IllegalArgumentException(value);
}
}
}
Loading

0 comments on commit 58d6eb9

Please sign in to comment.