use of org.hl7.fhir.r4.model.Enumerations.ResourceType in project pathling by aehrc.
the class TestHelpers method mockResource.
public static void mockResource(@Nonnull final Database database, @Nonnull final SparkSession spark, @Nonnull final ResourceType... resourceTypes) {
for (final ResourceType resourceType : resourceTypes) {
final Dataset<Row> dataset = getDatasetForResourceType(spark, resourceType);
when(database.read(resourceType)).thenReturn(dataset);
}
}
use of org.hl7.fhir.r4.model.Enumerations.ResourceType in project redmatch by aehrc.
the class FhirExporter method getValue.
/**
* Resolves a value.
*
* @param value The value specified in the transformation rules.
* @param fhirType The type of the FHIR attribute where this value will be set.
* @param vertex A vertex with patient data.
* @param recordId The id of this record. Used to create the references to FHIR ids.
* @param enumFactory If the type is an enumeration, this is the factory to create an instance.
* @param fhirPackage The target FHIR package.
* @return The value or null if the value cannot be determined. This can also be a list.
*/
private Base getValue(Value value, Class<?> fhirType, JsonObject vertex, String recordId, Class<?> enumFactory, VersionedFhirPackage fhirPackage) throws IOException {
// If this is a field-based value then make sure that there is a value and if not return null
if (value instanceof FieldBasedValue) {
FieldBasedValue fbv = (FieldBasedValue) value;
// Account for field ids of the form xx___y
String fieldId = fbv.getFieldId();
String shortFieldId = null;
String regex = "(?<fieldId>.*)___\\d+$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(fieldId);
if (matcher.find()) {
shortFieldId = matcher.group("fieldId");
log.debug("Transformed fieldId into '" + fieldId + "'");
}
boolean hasValue = false;
JsonElement jsonElement = vertex.get(fieldId);
if (jsonElement != null) {
String rawValue = jsonElement.getAsString();
if (!rawValue.isEmpty()) {
hasValue = true;
}
}
if (!hasValue && shortFieldId != null) {
jsonElement = vertex.get(shortFieldId);
if (jsonElement != null) {
String rawValue = jsonElement.getAsString();
if (!rawValue.isEmpty()) {
hasValue = true;
}
}
}
if (!hasValue) {
return null;
}
}
if (value instanceof BooleanValue) {
return new BooleanType(((BooleanValue) value).getValue());
} else if (value instanceof CodeLiteralValue) {
String code = ((CodeLiteralValue) value).getCode();
return getCode(code, enumFactory);
} else if (value instanceof ConceptLiteralValue) {
ConceptLiteralValue clv = (ConceptLiteralValue) value;
String system = clv.getSystem();
String code = clv.getCode();
String display = clv.getDisplay() != null ? clv.getDisplay() : "";
return getConcept(system, code, display, fhirType);
} else if (value instanceof DoubleValue) {
return new DecimalType(((DoubleValue) value).getValue());
} else if (value instanceof IntegerValue) {
return new IntegerType(((IntegerValue) value).getValue());
} else if (value instanceof ReferenceValue) {
ReferenceValue rv = (ReferenceValue) value;
Reference ref = new Reference();
String resourceType = rv.getResourceType();
String resourceId = rv.getResourceId();
boolean unique = uniqueIds.contains(resourceType + "<" + resourceId + ">");
CodeInfo codeInfo = terminologyService.lookup(fhirPackage, resourceType);
if (codeInfo.isProfile()) {
resourceType = StringUtils.getLastPath(codeInfo.getBaseResource());
}
if (unique) {
// This is a reference to a unique resource - no need to append row id
if (fhirResourceMap.containsKey(resourceId)) {
ref.setReference("/" + resourceType + "/" + resourceId);
} else {
log.debug("Did not find resource " + resourceType + "/" + resourceId);
}
} else {
if (fhirResourceMap.containsKey(resourceId + "-" + recordId)) {
ref.setReference("/" + resourceType + "/" + resourceId + "-" + recordId);
} else {
log.debug("Did not find resource " + resourceType + "/" + resourceId + "-" + recordId);
}
}
return ref;
} else if (value instanceof StringValue) {
if (fhirType.equals(StringType.class)) {
return new StringType(((StringValue) value).getStringValue());
} else if (fhirType.equals(MarkdownType.class)) {
return new MarkdownType(((StringValue) value).getStringValue());
} else if (fhirType.equals(IdType.class)) {
return new IdType(((StringValue) value).getStringValue());
} else if (fhirType.equals(UriType.class)) {
return new UriType(((StringValue) value).getStringValue());
} else if (fhirType.equals(OidType.class)) {
return new OidType(((StringValue) value).getStringValue());
} else if (fhirType.equals(UuidType.class)) {
return new UuidType(((StringValue) value).getStringValue());
} else if (fhirType.equals(CanonicalType.class)) {
return new CanonicalType(((StringValue) value).getStringValue());
} else if (fhirType.equals(UrlType.class)) {
return new UrlType(((StringValue) value).getStringValue());
} else {
throw new TransformationException("Got StringValue for FHIR type " + fhirType.getName() + ". This should not happen!");
}
} else if (value instanceof CodeSelectedValue) {
CodeSelectedValue csv = (CodeSelectedValue) value;
String fieldId = csv.getFieldId();
Mapping m = getSelectedMapping(fieldId, vertex);
if (m == null) {
throw new TransformationException("Mapping for field " + fieldId + " is required but was not found.");
}
return getTarget(m).getCodeElement();
} else if (value instanceof ConceptSelectedValue) {
ConceptSelectedValue csv = (ConceptSelectedValue) value;
String fieldId = csv.getFieldId();
Mapping m = getSelectedMapping(fieldId, vertex);
if (m == null) {
throw new TransformationException("Mapping for field " + fieldId + " is required but was not found.");
}
if (fhirType.isAssignableFrom(Coding.class)) {
return getTarget(m);
} else if (fhirType.isAssignableFrom(CodeableConcept.class)) {
return new CodeableConcept().addCoding(getTarget(m));
} else {
throw new TransformationException("FHIR type of field " + fieldId + " (" + fhirType + ") is incompatible with CONCEPT_SELECTED.");
}
} else if (value instanceof ConceptValue) {
// Ontoserver REDCap plugin format: 74400008|Appendicitis|http://snomed.info/sct
ConceptValue cv = (ConceptValue) value;
String fieldId = cv.getFieldId();
Mapping m = getMapping(fieldId);
if (m != null) {
if (fhirType.isAssignableFrom(Coding.class)) {
return getTarget(m);
} else if (fhirType.isAssignableFrom(CodeableConcept.class)) {
return new CodeableConcept().addCoding(getTarget(m));
} else {
throw new TransformationException("FHIR type of field " + fieldId + " (" + fhirType + ") is incompatible with CONCEPT.");
}
} else {
au.csiro.redmatch.model.Field field = doc.getSchema().getField(fieldId);
Coding c = field.getCoding(vertex);
if (c != null) {
if (fhirType.isAssignableFrom(Coding.class)) {
return c;
} else if (fhirType.isAssignableFrom(CodeableConcept.class)) {
return new CodeableConcept().addCoding(c);
} else {
throw new TransformationException("FHIR type of field " + fieldId + " (" + fhirType + ") is incompatible with CONCEPT.");
}
}
}
throw new TransformationException("Could not get concept for field " + fieldId + ".");
} else if (value instanceof FieldValue) {
FieldValue fv = (FieldValue) value;
String fieldId = fv.getFieldId();
FieldValue.DatePrecision pr = fv.getDatePrecision();
au.csiro.redmatch.model.Field field = doc.getSchema().getField(fieldId);
return field.getValue(vertex, fhirType, pr);
} else {
throw new TransformationException("Unable to get VALUE for " + value);
}
}
use of org.hl7.fhir.r4.model.Enumerations.ResourceType in project redmatch by aehrc.
the class RedmatchApi method exportAll.
/**
* Runs an operation on all the Redmatch rule documents found in the base folder.
*
* @param baseFolder The folder that contains the Redmatch rule documents , one or more schemas referenced by the
* rules and a redmatch-config.yaml file with source server details.
* @param progressReporter An object used to report progress. Can be null.
* @param cancelToken Used to check if the user has cancelled the operation.
* @return Map of diagnostic messages. Key is file where error happened.
*/
public List<Diagnostic> exportAll(@NotNull File baseFolder, ProgressReporter progressReporter, CancelChecker cancelToken) {
if (!baseFolder.canRead() || !baseFolder.canWrite()) {
return List.of(new Diagnostic(zeroZero, "Unable to read or write on the base folder.", DiagnosticSeverity.Error, "API"));
}
// Get .rdm files
List<File> rdmFiles;
try (Stream<Path> walk = Files.walk(baseFolder.toPath())) {
rdmFiles = walk.filter(p -> !Files.isDirectory(p)).map(Path::toFile).filter(f -> f.getName().endsWith(".rdm")).collect(Collectors.toList());
} catch (IOException e) {
return List.of(new Diagnostic(zeroZero, "Unexpected I/O error: " + e.getLocalizedMessage(), DiagnosticSeverity.Error, "API"));
}
try {
List<Diagnostic> diagnostics = new ArrayList<>();
Map<String, DomainResource> resourcesMap = new HashMap<>();
for (File rdmFile : rdmFiles) {
Pair<Map<String, DomainResource>, List<Diagnostic>> data = transform(rdmFile, progressReporter, cancelToken);
resourcesMap.putAll(data.getValue0());
diagnostics.addAll(data.getValue1());
}
// Group resources by type
final Map<String, List<DomainResource>> grouped = new HashMap<>();
for (String key : resourcesMap.keySet()) {
DomainResource dr = resourcesMap.get(key);
String resourceType = dr.getResourceType().toString();
List<DomainResource> list = grouped.computeIfAbsent(resourceType, k -> new ArrayList<>());
list.add(dr);
}
Path outputFolder = createOutputFolder(baseFolder).toPath();
save(grouped, outputFolder, progressReporter, cancelToken);
return diagnostics;
} catch (Exception e) {
log.error(e);
return List.of(new Diagnostic(zeroZero, "Could not complete transformation:" + e.getLocalizedMessage(), DiagnosticSeverity.Error, "API"));
}
}
use of org.hl7.fhir.r4.model.Enumerations.ResourceType in project CRD by HL7-DaVinci.
the class QueryBatchRequest method performQueryBatchRequest.
/**
* Backfills the missing required values of the response that prefetch may have missed.
* This implementation pulls the IDs of the required references from the request object's draft
* orders, checks which of those values are missing from the current CRD response, builds the
* Query Batch JSON request using
* http://build.fhir.org/ig/HL7/davinci-crd/hooks.html#fhir-resource-access,
* then populates the CRD response with the response from the Query Batch.
*/
public void performQueryBatchRequest(CdsRequest<?, ?> cdsRequest, CrdPrefetch crdPrefetch) {
logger.info("***** ***** Performing Query Batch Request.");
CrdPrefetch crdResponse = crdPrefetch;
// The list of references that should be queried in the batch request.
List<String> requiredReferences = new ArrayList<String>();
// Get the IDs of references in the request's draft orders.
Bundle draftOrdersBundle = cdsRequest.getContext().getDraftOrders();
// This assumes that only the first draft order is relevant.
Resource initialRequestResource = draftOrdersBundle.getEntry().get(0).getResource();
ResourceType requestType = initialRequestResource.getResourceType();
// Extract the references by iterating through the JSON.
Gson gson = new Gson();
final JsonObject jsonObject = gson.toJsonTree(initialRequestResource).getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
FhirRequestProcessor.extractReferenceIds(requiredReferences, entry.getValue());
}
// Filter out references that already exist in the CRD Response.
requiredReferences = requiredReferences.stream().filter(referenceId -> !crdResponse.containsRequestResourceId(referenceId)).collect(Collectors.toList());
logger.info("References to query: " + requiredReferences);
if (requiredReferences.isEmpty()) {
logger.info("A Query Batch Request is not needed: all references have already already fetched.");
return;
}
// Build the Query Batch Request JSON.
Bundle queryBatchRequestBundle = buildQueryBatchRequestBundle(requiredReferences);
String queryBatchRequestBody = FhirContext.forR4().newJsonParser().encodeResourceToString(queryBatchRequestBundle);
// Make the query batch request to the EHR server.
Bundle queryResponseBundle = null;
try {
logger.info("Executing Query Batch Request: " + queryBatchRequestBody);
queryResponseBundle = (Bundle) FhirRequestProcessor.executeFhirQueryBody(queryBatchRequestBody, cdsRequest, this.fhirComponents, HttpMethod.POST);
queryResponseBundle = extractNestedBundledResources(queryResponseBundle);
logger.info("Extracted Query Batch Resources: " + (queryResponseBundle).getEntry().stream().map(entry -> entry.getResource()).collect(Collectors.toList()));
} catch (Exception e) {
logger.error("Failed to backfill prefetch with Query Batch Request " + queryBatchRequestBody, e);
}
if (queryResponseBundle == null) {
logger.error("No response recieved from the Query Batch Request.");
return;
}
// Add the request resource to the query batch response as it may be missing.
// Coverage and Subject are not automatically being
// linked to the request object. It seems to somehow automatically link during
// standard prefetch, but not here so we're doing it manually.
List<Coverage> coverages = FhirRequestProcessor.extractCoverageFromBundle(queryResponseBundle);
List<Patient> patients = FhirRequestProcessor.extractPatientsFromBundle(queryResponseBundle);
FhirRequestProcessor.addInsuranceAndSubject(initialRequestResource, patients, coverages);
BundleEntryComponent newEntry = new BundleEntryComponent();
newEntry.setResource(initialRequestResource);
queryResponseBundle.addEntry(newEntry);
// Add the query batch response resources to the CRD Prefetch request.
logger.info("Query Batch Response Entries: " + queryResponseBundle.getEntry());
FhirRequestProcessor.addToCrdPrefetchRequest(crdResponse, requestType, queryResponseBundle.getEntry());
logger.info("Post-Query Batch CRDResponse: " + crdResponse);
}
use of org.hl7.fhir.r4.model.Enumerations.ResourceType in project CRD by HL7-DaVinci.
the class Utilities method bundleAsHashmap.
/**
* Change a fhir bundle into a hashmap keyed by resources type, where the value is a list of
* resources of that type.
* @return a hashmap of a ResourceType as key, and a List of Resources of that type
*/
public static HashMap<String, List<Resource>> bundleAsHashmap(Bundle bundle) {
HashMap<String, List<Resource>> bundleMap = new HashMap<>();
for (BundleEntryComponent bec : bundle.getEntry()) {
if (!bec.hasResource()) {
continue;
}
Resource resource = bec.getResource();
String resourceType = resource.getResourceType().toString();
if (!bundleMap.containsKey(resourceType)) {
bundleMap.put(resourceType, new ArrayList<>());
}
List<Resource> resourceList = (List<Resource>) bundleMap.get(resourceType);
resourceList.add(resource);
}
return bundleMap;
}
Aggregations