Skip to content

Commit

Permalink
Merge pull request #3685 from IBM/issue-3242-export
Browse files Browse the repository at this point in the history
issue #3242 - use the fhirVersion from the import/export request
  • Loading branch information
lmsurpre authored Jun 10, 2022
2 parents 00bb3b3 + 1410fb0 commit e796463
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import javax.ws.rs.core.MediaType;

import com.ibm.fhir.core.FHIRMediaType;
import com.ibm.fhir.core.FHIRVersionParam;
import com.ibm.fhir.exception.FHIROperationException;
import com.ibm.fhir.model.resource.OperationDefinition;
import com.ibm.fhir.model.resource.Parameters;
Expand Down Expand Up @@ -66,7 +67,8 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
Parameters response = null;
OperationConstants.ExportType exportType = export.checkExportType(operationContext.getType(), resourceType);

Set<String> types = export.checkAndValidateTypes(exportType, getParameters(parameters, OperationConstants.PARAM_TYPE));
FHIRVersionParam fhirVersion = (FHIRVersionParam) operationContext.getProperty(FHIROperationContext.PROPNAME_FHIR_VERSION);
Set<String> types = export.checkAndValidateTypes(exportType, fhirVersion, getParameters(parameters, OperationConstants.PARAM_TYPE));

if (!ExportType.INVALID.equals(exportType)) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.InputStream;
import java.util.List;

import com.ibm.fhir.core.FHIRVersionParam;
import com.ibm.fhir.exception.FHIROperationException;
import com.ibm.fhir.model.format.Format;
import com.ibm.fhir.model.parser.FHIRParser;
Expand Down Expand Up @@ -70,7 +71,8 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
String inputSource = util.retrieveInputSource();

// Parameter: input
List<Input> inputs = util.retrieveInputs();
FHIRVersionParam fhirVersion = (FHIRVersionParam) operationContext.getProperty(FHIROperationContext.PROPNAME_FHIR_VERSION);
List<Input> inputs = util.retrieveInputs(fhirVersion);

// Parameter: storageDetail
StorageDetail storageDetail = util.retrieveStorageDetails();
Expand All @@ -86,7 +88,7 @@ private void checkImportType(FHIROperationContext.Type type) throws FHIROperatio
// Check Import Type is System. We only support system right now.

if (!FHIROperationContext.Type.SYSTEM.equals(type)) {
throw buildExceptionWithIssue("Invalid call $import operation call only system is allowed",
throw buildExceptionWithIssue("Invalid call; $import can only be invoked at the system level",
IssueType.INVALID);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 2021
* (C) Copyright IBM Corp. 2021, 2022
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -41,13 +41,13 @@ public void preflight() throws FHIROperationException {
/**
* validates the azure provider is properly configured.
*
* @param source
* @param storageProvider
* @throws FHIROperationException
*/
public void validate(String source) throws FHIROperationException {
public void validate(String storageProvider) throws FHIROperationException {
ConfigurationAdapter adapter = ConfigurationFactory.getInstance();
if (adapter.isStorageProviderAuthTypeConnectionString(source)) {
String conn = adapter.getStorageProviderAuthTypeConnectionString(source);
if (adapter.isStorageProviderAuthTypeConnectionString(storageProvider)) {
String conn = adapter.getStorageProviderAuthTypeConnectionString(storageProvider);
if (conn == null || conn.isEmpty()) {
throw export.buildOperationException("bad configuration for the Azure Blob Container's connection configuration", IssueType.EXCEPTION);
}
Expand All @@ -56,7 +56,7 @@ public void validate(String source) throws FHIROperationException {
}

// Used to get the Azure Container
if (adapter.getStorageProviderBucketName(source) == null || adapter.getStorageProviderBucketName(source).isEmpty()) {
if (adapter.getStorageProviderBucketName(storageProvider) == null || adapter.getStorageProviderBucketName(storageProvider).isEmpty()) {
throw export.buildOperationException("bad configuration for the basic configuration with bucketname", IssueType.EXCEPTION);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import com.ibm.fhir.config.FHIRConfigHelper;
import com.ibm.fhir.core.FHIRMediaType;
import com.ibm.fhir.core.FHIRVersionParam;
import com.ibm.fhir.exception.FHIROperationException;
import com.ibm.fhir.model.resource.OperationOutcome.Issue;
import com.ibm.fhir.model.resource.Parameters;
Expand Down Expand Up @@ -161,11 +162,13 @@ public Instant checkAndExtractSince(Parameters parameters) {
* processes both the Parameters object and the query parameters
*
* @param exportType
* @param fhirVersion
* @param parameters
* @return
* @throws FHIROperationException
*/
public Set<String> checkAndValidateTypes(OperationConstants.ExportType exportType, List<Parameter> parameters) throws FHIROperationException {
public Set<String> checkAndValidateTypes(OperationConstants.ExportType exportType, FHIRVersionParam fhirVersion, List<Parameter> parameters)
throws FHIROperationException {
/*
* Only resources of the specified resource types(s) SHALL be included in the response. If this parameter is
* omitted, the server SHALL return all supported resources within the scope of the client authorization. For
Expand All @@ -179,7 +182,7 @@ public Set<String> checkAndValidateTypes(OperationConstants.ExportType exportTyp
* within the file set. For example _type=Practitioner could be used to bulk data extract all Practitioner
* resources from a FHIR endpoint.
*/
Set<String> supportedResourceTypes = FHIRConfigHelper.getSupportedResourceTypes();
Set<String> supportedResourceTypes = FHIRConfigHelper.getSupportedResourceTypes(fhirVersion);
Set<String> result = new HashSet<>();
if (parameters != null) {
for (Parameters.Parameter parameter : parameters) {
Expand All @@ -203,7 +206,7 @@ public Set<String> checkAndValidateTypes(OperationConstants.ExportType exportTyp
}
}

// The case where no resourceTypes are specified, inlining only the supported ResourceTypes
// The case where no resourceTypes are specified on a system export, inlining only the supported ResourceTypes
if (result.isEmpty() && ExportType.SYSTEM.equals(exportType)) {
result = new HashSet<>(supportedResourceTypes);
} else if (ExportType.PATIENT.equals(exportType) || ExportType.GROUP.equals(exportType)) {
Expand Down Expand Up @@ -234,7 +237,7 @@ private Set<String> filterTypesToPatientResourceTypes(Set<String> resourceTypes)
result.add(resourceType);
} else {
LOG.info("Requested type '" + Encode.forHtml(resourceType) + "' cannot be in the Patient compartment;"
+ "this is not supported for Patient/Group export and so this type will be skipped");
+ " this is not supported for Patient/Group export and so this type will be skipped");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

package com.ibm.fhir.operation.bulkdata.util;

import static com.ibm.fhir.model.util.ModelSupport.FHIR_STRING;
import static com.ibm.fhir.operation.bulkdata.util.CommonUtil.buildExceptionWithIssue;

import java.util.ArrayList;
Expand All @@ -16,8 +17,10 @@
import java.util.Set;

import com.ibm.fhir.config.FHIRConfigHelper;
import com.ibm.fhir.core.FHIRVersionParam;
import com.ibm.fhir.exception.FHIROperationException;
import com.ibm.fhir.model.resource.Parameters;
import com.ibm.fhir.model.type.Uri;
import com.ibm.fhir.model.type.code.IssueType;
import com.ibm.fhir.model.util.ModelSupport;
import com.ibm.fhir.operation.bulkdata.OperationConstants;
Expand Down Expand Up @@ -95,7 +98,7 @@ public String retrieveInputSource() throws FHIROperationException {
Iterator<FHIRPathNode> iter = result.iterator();
while (iter.hasNext()) {
FHIRPathElementNode node = (FHIRPathElementNode) iter.next();
return node.asElementNode().element().as(com.ibm.fhir.model.type.Uri.class).getValue();
return node.asElementNode().element().as(Uri.class).getValue();
}
} catch (NoSuchElementException | ClassCastException | FHIRPathException e) {
throw buildExceptionWithIssue("invalid $import parameter value in 'inputSource'", e, IssueType.INVALID);
Expand All @@ -105,17 +108,18 @@ public String retrieveInputSource() throws FHIROperationException {
}

/**
* processes the retrieve inputs from the Parameters object and evaluationContext.
* Validate and retrieve the inputs from the Parameters object.
*
* @param fhirVersion
* @return
* @throws FHIROperationException
*/
public List<Input> retrieveInputs() throws FHIROperationException {
public List<Input> retrieveInputs(FHIRVersionParam fhirVersion) throws FHIROperationException {
// Parameter: input (required)
List<Input> inputs = new ArrayList<>();

try {
Set<String> supportedResourceTypes = FHIRConfigHelper.getSupportedResourceTypes();
Set<String> supportedResourceTypes = FHIRConfigHelper.getSupportedResourceTypes(fhirVersion);
Collection<FHIRPathNode> result = evaluator.evaluate(evaluationContext, "parameter.where(name = 'input')");

Iterator<FHIRPathNode> iter = result.iterator();
Expand Down Expand Up @@ -230,7 +234,7 @@ public StorageDetail retrieveStorageDetails() throws FHIROperationException {
EvaluationContext evaluationContextPartType = new EvaluationContext(node.element());
Collection<FHIRPathNode> resultPartType = evaluator.evaluate(evaluationContextPartType, "value");
String type =
((FHIRPathElementNode) resultPartType.iterator().next()).element().as(com.ibm.fhir.model.type.String.class).getValue();
((FHIRPathElementNode) resultPartType.iterator().next()).element().as(FHIR_STRING).getValue();

// Checks if not valid, and throws exception
if (!OperationConstants.STORAGE_TYPES.contains(type)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import com.ibm.fhir.config.FHIRConfiguration;
import com.ibm.fhir.config.FHIRRequestContext;
import com.ibm.fhir.core.FHIRVersionParam;
import com.ibm.fhir.exception.FHIRException;
import com.ibm.fhir.exception.FHIROperationException;
import com.ibm.fhir.model.resource.Group;
Expand Down Expand Up @@ -281,58 +282,58 @@ public void testCheckAndExtractSinceWithInvalidType() {
@Test(expectedExceptions = { com.ibm.fhir.exception.FHIROperationException.class })
public void testCheckAndValidateTypesEmpty() throws FHIROperationException {
List<Parameter> parameters = List.of(Parameter.builder().name(string("_type")).value(string("1")).build());
util.checkAndValidateTypes(ExportType.SYSTEM, parameters);
util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, parameters);
fail();
}

@Test(expectedExceptions = { com.ibm.fhir.exception.FHIROperationException.class })
public void testCheckAndValidateTypesNull() throws FHIROperationException {
List<Parameter> parameters = List.of(Parameter.builder().name(string("_type")).value((Element)null).build());
util.checkAndValidateTypes(ExportType.SYSTEM, parameters);
util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, parameters);
fail();
}

@Test(expectedExceptions = { com.ibm.fhir.exception.FHIROperationException.class })
public void testCheckAndValidateTypesNullQPS() throws FHIROperationException {
List<Parameter> parameters = List.of(Parameter.builder().name(string("_type")).value((Element) null).build());
util.checkAndValidateTypes(ExportType.SYSTEM, parameters);
util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, parameters);
fail();
}

@Test
public void testCheckAndValidateTypesPatientWithoutComma() throws FHIROperationException {
List<Parameter> parameters = List.of(Parameter.builder().name(string("_type")).value(string("Patient")).build());
Set<String> types = util.checkAndValidateTypes(ExportType.SYSTEM, parameters);
Set<String> types = util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, parameters);
assertNotNull(types);
}

@Test
public void testCheckAndValidateTypesPatientWithComma() throws FHIROperationException {
List<Parameter> parameters = List.of(Parameter.builder().name(string("_type")).value(string("Patient,")).build());
Set<String> types = util.checkAndValidateTypes(ExportType.SYSTEM, parameters);
Set<String> types = util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, parameters);
assertNotNull(types);
}

@Test
public void testCheckAndValidateTypesPatientMedicationWithComma() throws FHIROperationException {
List<Parameter> parameters = List.of(Parameter.builder().name(string("_type")).value(string("Patient,Medication")).build());
Set<String> types = util.checkAndValidateTypes(ExportType.SYSTEM, parameters);
Set<String> types = util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, parameters);
assertNotNull(types);
}

@Test(expectedExceptions = { com.ibm.fhir.exception.FHIROperationException.class })
public void testCheckAndValidateTypesPatientMedicationWithExtraComma() throws FHIROperationException {
// parameters
List<Parameter> parameters = List.of(Parameter.builder().name(string("_type")).value(string("Patient,,Medication")).build());
util.checkAndValidateTypes(ExportType.SYSTEM, parameters);
util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, parameters);
fail();
}

@Test
public void testCheckAndValidateTypesWithExtraComma() throws FHIROperationException {
// parameters
List<Parameter> parameters = List.of(Parameter.builder().name(string("_type")).value(string(",,")).build());
Set<String> result = util.checkAndValidateTypes(ExportType.SYSTEM, parameters);
Set<String> result = util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, parameters);
assertNotNull(result);
assertFalse(result.isEmpty());
}
Expand All @@ -341,14 +342,14 @@ public void testCheckAndValidateTypesWithExtraComma() throws FHIROperationExcept
public void testCheckAndValidateTypesNoParameters() throws FHIROperationException {
// parameters
List<Parameter> parameters = List.of(Parameter.builder().name(string("french")).value(string("Patient,,Medication")).build());
Set<String> result = util.checkAndValidateTypes(ExportType.SYSTEM, parameters);
Set<String> result = util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, parameters);
assertNotNull(result);
assertFalse(result.isEmpty());
}

@Test
public void testCheckAndValidateTypesEmptyParameters() throws FHIROperationException {
Set<String> result = util.checkAndValidateTypes(ExportType.SYSTEM, null);
Set<String> result = util.checkAndValidateTypes(ExportType.SYSTEM, FHIRVersionParam.VERSION_43, null);
assertNotNull(result);
assertFalse(result.isEmpty());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

import com.ibm.fhir.config.FHIRConfiguration;
import com.ibm.fhir.config.FHIRRequestContext;
import com.ibm.fhir.core.FHIRVersionParam;
import com.ibm.fhir.exception.FHIRException;
import com.ibm.fhir.exception.FHIROperationException;
import com.ibm.fhir.model.format.Format;
Expand Down Expand Up @@ -66,8 +67,8 @@ public void testBulkImportUtilInputs() throws IOException, FHIRException {
FHIRRequestContext.set(context);
context.setTenantId("not-config");
BulkDataImportUtil util = new BulkDataImportUtil(getContext(), loadTestFile("/testdata/import/import-demo.json"));
assertFalse(util.retrieveInputs().isEmpty());
assertEquals(util.retrieveInputs().size(), 2);
assertFalse(util.retrieveInputs(FHIRVersionParam.VERSION_43).isEmpty());
assertEquals(util.retrieveInputs(FHIRVersionParam.VERSION_43).size(), 2);
}

@Test
Expand Down Expand Up @@ -160,7 +161,7 @@ public void testCheckAllowedResourceTypesForInputs() throws IOException, FHIRExc
FHIRRequestContext.set(context);
context.setTenantId("config");
BulkDataImportUtil util = new BulkDataImportUtil(getContext(), loadTestFile("/testdata/import/import-demo-config.json"));
util.retrieveInputs();
util.retrieveInputs(FHIRVersionParam.VERSION_43);
}

@Test(expectedExceptions = { FHIROperationException.class })
Expand All @@ -169,7 +170,7 @@ public void testCheckAllowedResourceTypesForInputsBad() throws IOException, FHIR
FHIRRequestContext.set(context);
context.setTenantId("not-config");
BulkDataImportUtil util = new BulkDataImportUtil(getContext(), loadTestFile("/testdata/import/import-demo-not-config.json"));
util.retrieveInputs();
util.retrieveInputs(FHIRVersionParam.VERSION_43);
}

public Parameters loadTestFile(String file) throws FHIRParserException, IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
import com.ibm.fhir.model.type.code.BundleType;
import com.ibm.fhir.model.type.code.HTTPVerb;
import com.ibm.fhir.model.type.code.IssueType;
import com.ibm.fhir.model.type.code.SearchEntryMode;
import com.ibm.fhir.model.util.ModelSupport;
import com.ibm.fhir.model.util.ReferenceFinder;
import com.ibm.fhir.registry.FHIRRegistry;
Expand Down Expand Up @@ -205,7 +204,7 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
MultivaluedMap<String, String> queryParametersWithoutDates = new MultivaluedHashMap<String,String>(queryParameters);
boolean startOrEndProvided = queryParametersWithoutDates.remove(DATE_QUERY_PARAMETER) != null;

List<String> defaultResourceTypes = new ArrayList<String>(0);
List<String> defaultResourceTypes;
try {
FHIRVersionParam fhirVersion = (FHIRVersionParam) operationContext.getProperty(FHIROperationContext.PROPNAME_FHIR_VERSION);
defaultResourceTypes = getDefaultIncludedResourceTypes(resourceHelper, fhirVersion);
Expand Down

0 comments on commit e796463

Please sign in to comment.