diff --git a/docs/src/pages/guides/FHIRServerUsersGuide.md b/docs/src/pages/guides/FHIRServerUsersGuide.md index cfea43de365..ee0b8a65f80 100644 --- a/docs/src/pages/guides/FHIRServerUsersGuide.md +++ b/docs/src/pages/guides/FHIRServerUsersGuide.md @@ -2273,7 +2273,7 @@ This section contains reference information about each of the configuration prop |`fhirServer/core/capabilitiesUrl`|null| |`fhirServer/core/externalBaseUrl`|null| |`fhirServer/core/ifNoneMatchReturnsNotModified`|false| -|`fhirServer/core/defaultFhirVersion`|null| +|`fhirServer/core/defaultFhirVersion`|4.0| |`fhirServer/core/useImplicitTypeScopingForWholeSystemInteractions`|true| |`fhirServer/validation/failFast`|false| |`fhirServer/term/capabilitiesUrl`|null| diff --git a/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfigHelper.java b/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfigHelper.java index df4b6a70907..997635a6f14 100644 --- a/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfigHelper.java +++ b/fhir-config/src/main/java/com/ibm/fhir/config/FHIRConfigHelper.java @@ -181,8 +181,8 @@ public static Set getSupportedResourceTypes() { * @throws IllegalStateException if there is an unexpected issue while processing the config */ public static Set getSupportedResourceTypes(FHIRVersionParam fhirVersion) { - PropertyGroup rsrcsGroup = FHIRConfigHelper.getPropertyGroup(FHIRConfiguration.PROPERTY_RESOURCES); - ResourcesConfigAdapter configAdapter = new ResourcesConfigAdapter(rsrcsGroup, fhirVersion); + PropertyGroup resourcesGroup = FHIRConfigHelper.getPropertyGroup(FHIRConfiguration.PROPERTY_RESOURCES); + ResourcesConfigAdapter configAdapter = new ResourcesConfigAdapter(resourcesGroup, fhirVersion); return configAdapter.getSupportedResourceTypes(); } diff --git a/fhir-config/src/main/java/com/ibm/fhir/config/Interaction.java b/fhir-config/src/main/java/com/ibm/fhir/config/Interaction.java index 9a2189a40f5..78f9c6c3c42 100644 --- a/fhir-config/src/main/java/com/ibm/fhir/config/Interaction.java +++ b/fhir-config/src/main/java/com/ibm/fhir/config/Interaction.java @@ -5,6 +5,10 @@ */ package com.ibm.fhir.config; +/** + * Interaction constants to the allowed values of the + * fhirServer/resources/[resourceType]/interactions config property + */ public enum Interaction { CREATE("create"), DELETE("delete"), diff --git a/fhir-config/src/main/java/com/ibm/fhir/config/ResourcesConfigAdapter.java b/fhir-config/src/main/java/com/ibm/fhir/config/ResourcesConfigAdapter.java index 03d785499c2..34917786402 100644 --- a/fhir-config/src/main/java/com/ibm/fhir/config/ResourcesConfigAdapter.java +++ b/fhir-config/src/main/java/com/ibm/fhir/config/ResourcesConfigAdapter.java @@ -14,6 +14,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,6 +42,13 @@ public class ResourcesConfigAdapter { private boolean isWholeSystemSearchSupported = true; private boolean isWholeSystemHistorySupported = true; + /** + * Public constructor + * + * @param resourcesConfig a PropertyGroup instance for the fhirServer/resources property group + * @param fhirVersion a FHIRVersionParam with the fhirVersion to use for computing the applicable resource types + * @throws Exception + */ public ResourcesConfigAdapter(PropertyGroup resourcesConfig, FHIRVersionParam fhirVersion) { supportedTypes = computeSupportedResourceTypes(resourcesConfig, fhirVersion); @@ -123,27 +131,27 @@ public Set getSupportedResourceTypes(Interaction interaction) { private Set computeSupportedResourceTypes(PropertyGroup resourcesConfig, FHIRVersionParam fhirVersion) { Set applicableTypes = ResourceTypeHelper.getResourceTypesFor(fhirVersion); - if (resourcesConfig == null || resourcesConfig.getBooleanProperty("open", true)) { - return applicableTypes; - } - - Set result = new LinkedHashSet(); - for (PropertyEntry rsrcsEntry : resourcesConfig.getProperties()) { - String name = rsrcsEntry.getName(); - - // Ensure we skip over the special property "open" - // and skip the abstract types Resource and DomainResource - if (FHIRConfiguration.PROPERTY_FIELD_RESOURCES_OPEN.equals(name) || - RESOURCE.value().equals(name) || - DOMAIN_RESOURCE.value().equals(name)) { - continue; - } + Set result; + if (resourcesConfig == null || resourcesConfig.getBooleanProperty(FHIRConfiguration.PROPERTY_FIELD_RESOURCES_OPEN, true)) { + result = applicableTypes; + } else { + result = new LinkedHashSet(); + for (PropertyEntry rsrcsEntry : resourcesConfig.getProperties()) { + String name = rsrcsEntry.getName(); + + // Ensure we skip over the special property "open" + // and skip the abstract types Resource and DomainResource + if (FHIRConfiguration.PROPERTY_FIELD_RESOURCES_OPEN.equals(name) || + ResourceTypeHelper.getAbstractResourceTypeNames().contains(name)) { + continue; + } - if (applicableTypes.contains(name)) { - result.add(name); - } else if (log.isLoggable(Level.FINE)) { - log.fine("Configured resource type '" + name + "' is not valid " - + "or not applicable for fhirVersion " + fhirVersion.value()); + if (applicableTypes.contains(name)) { + result.add(name); + } else if (log.isLoggable(Level.FINE)) { + log.fine("Configured resource type '" + name + "' is not valid " + + "or not applicable for fhirVersion " + fhirVersion.value()); + } } } @@ -156,5 +164,39 @@ public boolean isWholeSystemSearchSupported() { public boolean isWholeSystemHistorySupported() { return isWholeSystemHistorySupported; + + // note that this private method depends on the member supportedTypes having already been computed + private Map> computeTypesByInteraction(PropertyGroup resourcesConfig) throws Exception { + Map> typeMap = new HashMap<>(); + if (resourcesConfig == null) { + for (Interaction interaction : Interaction.values()) { + typeMap.put(interaction, supportedTypes); + } + } else { + for (String resourceType : supportedTypes) { + List interactions = resourcesConfig.getStringListProperty(resourceType + "/" + FHIRConfiguration.PROPERTY_FIELD_RESOURCES_INTERACTIONS); + if (interactions == null) { + interactions = resourcesConfig.getStringListProperty("Resource/" + FHIRConfiguration.PROPERTY_FIELD_RESOURCES_INTERACTIONS); + } + + if (interactions == null) { + for (Interaction interaction : Interaction.values()) { + typeMap.computeIfAbsent(interaction, k -> new LinkedHashSet<>()).add(resourceType); + } + continue; + } + + for (String interactionString : interactions) { + Interaction interaction = Interaction.from(interactionString); + typeMap.computeIfAbsent(interaction, k -> new LinkedHashSet<>()).add(resourceType); + } + } + } + + Map> finalMap = new HashMap<>(); + for (Entry> entry : typeMap.entrySet()) { + finalMap.put(entry.getKey(), Collections.unmodifiableSet(entry.getValue())); + } + return Collections.unmodifiableMap(finalMap); } } diff --git a/fhir-core/src/main/java/com/ibm/fhir/core/FHIRVersionParam.java b/fhir-core/src/main/java/com/ibm/fhir/core/FHIRVersionParam.java index f8d4f78f74c..ed502e94379 100644 --- a/fhir-core/src/main/java/com/ibm/fhir/core/FHIRVersionParam.java +++ b/fhir-core/src/main/java/com/ibm/fhir/core/FHIRVersionParam.java @@ -14,7 +14,12 @@ public enum FHIRVersionParam { private final String value; - FHIRVersionParam(String value) { + /** + * Private constructor + * + * @param value the fhirVersion value string + */ + private FHIRVersionParam(String value) { this.value = value; } diff --git a/fhir-core/src/main/java/com/ibm/fhir/core/util/ResourceTypeHelper.java b/fhir-core/src/main/java/com/ibm/fhir/core/util/ResourceTypeHelper.java index 4e75a270bde..37e2dc4550d 100644 --- a/fhir-core/src/main/java/com/ibm/fhir/core/util/ResourceTypeHelper.java +++ b/fhir-core/src/main/java/com/ibm/fhir/core/util/ResourceTypeHelper.java @@ -21,7 +21,6 @@ public class ResourceTypeHelper { private static final Set REMOVED_RESOURCE_TYPES = collectRemovedResourceTypes(); private static final Set R4B_ONLY_RESOURCE_TYPES = collectR4bOnlyResourceTypes(); - private static final Set ABSTRACT_TYPES = Collections.unmodifiableSet(new HashSet<>( Arrays.asList( ResourceTypeName.RESOURCE, @@ -48,6 +47,11 @@ public class ResourceTypeHelper { .map(ResourceTypeName::value) .collect(Collectors.toList()))); + private static final Set ABSTRACT_RESOURCES = Collections.unmodifiableSet( + ABSTRACT_TYPES.stream() + .map(ResourceTypeName::value) + .collect(Collectors.toSet())); + /** * @param fhirVersion The value of the MIME-type parameter 'fhirVersion' for the current interaction * (e.g. "4.3" not "4.3.0") @@ -71,6 +75,14 @@ public static Set getNewOrBreakingResourceTypeNames() { return R4B_ONLY_RESOURCES; } + /** + * @return the set of resource type names that were either introduced in 4.3.0 (e.g. Ingredient) or changed + * in backwards-incompatible ways in the 4.3.0 release (e.g. Evidence and EvidenceVariable) + */ + public static Set getAbstractResourceTypeNames() { + return ABSTRACT_RESOURCES; + } + private static Set collectRemovedResourceTypes() { Set set = new HashSet<>(); set.add(ResourceTypeName.EFFECT_EVIDENCE_SYNTHESIS); diff --git a/fhir-core/src/test/java/com/ibm/fhir/core/util/test/ResourceTypeHelperTest.java b/fhir-core/src/test/java/com/ibm/fhir/core/util/test/ResourceTypeHelperTest.java index 2183ea11cd1..62aebbb3fce 100644 --- a/fhir-core/src/test/java/com/ibm/fhir/core/util/test/ResourceTypeHelperTest.java +++ b/fhir-core/src/test/java/com/ibm/fhir/core/util/test/ResourceTypeHelperTest.java @@ -15,6 +15,9 @@ import com.ibm.fhir.core.FHIRVersionParam; import com.ibm.fhir.core.util.ResourceTypeHelper; +/** + * Tests for the ResourceTypeHelper class + */ public class ResourceTypeHelperTest { @Test public void testGetNewOrBreakingResourceTypeNames() {