Skip to content

Commit

Permalink
issues #2241 and #2057 - load operation from registry and skip warning
Browse files Browse the repository at this point in the history
With this pull request, the spec-defined OperationDefinitions are now
pulled from the registry instead of having them copied to each
individual module.

Additionally, because so many of these spec-defined OperationDefinitions
violate opd-0 (`name.matches('[A-Z]([A-Za-z0-9_]){0,254}')`), I toned
down the logging so that only validation errors are logged by default
(and not validation warnings).

Signed-off-by: Lee Surprenant <lmsurpre@us.ibm.com>
  • Loading branch information
lmsurpre committed Apr 13, 2021
1 parent d9e8bd5 commit d8104dc
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 423 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 2016, 2020
* (C) Copyright IBM Corp. 2016, 2021
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -91,8 +91,10 @@ private boolean isValid(FHIROperation operation) throws FHIRValidationException,
List<Issue> issues = FHIRValidator.validator().validate(opDef);
if (!issues.isEmpty()) {
for (Issue issue : issues) {
log.info("Issue: " + issue.getCode().getValue() + ":"
+ issue.getSeverity().getValue() + ":" + issue.getDetails().getText().getValue());
if (log.isLoggable(Level.FINE)) {
log.fine("Issue: " + issue.getCode().getValue() + ":"
+ issue.getSeverity().getValue() + ":" + issue.getDetails().getText().getValue());
}
if (issue.getSeverity().equals(IssueSeverity.ERROR)
|| issue.getSeverity().equals(IssueSeverity.FATAL)) {
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,28 @@
/*
* (C) Copyright IBM Corp. 2020
* (C) Copyright IBM Corp. 2020, 2021
*
* SPDX-License-Identifier: Apache-2.0
*/

package com.ibm.fhir.operation.convert;

import java.io.InputStream;

import com.ibm.fhir.exception.FHIROperationException;
import com.ibm.fhir.model.format.Format;
import com.ibm.fhir.model.parser.FHIRParser;
import com.ibm.fhir.model.resource.OperationDefinition;
import com.ibm.fhir.model.resource.Parameters;
import com.ibm.fhir.model.resource.Parameters.Parameter;
import com.ibm.fhir.model.resource.Resource;
import com.ibm.fhir.model.type.code.IssueType;
import com.ibm.fhir.registry.FHIRRegistry;
import com.ibm.fhir.server.operation.spi.AbstractOperation;
import com.ibm.fhir.server.operation.spi.FHIROperationContext;
import com.ibm.fhir.server.operation.spi.FHIRResourceHelpers;
import com.ibm.fhir.server.util.FHIROperationUtil;

public class ConvertOperation extends AbstractOperation {
public ConvertOperation() {
super();
}

@Override
protected OperationDefinition buildOperationDefinition() {
try (InputStream in = getClass().getClassLoader().getResourceAsStream("convert.json");){
return FHIRParser.parser(Format.JSON).parse(in);
} catch (Exception e) {
throw new Error(e);
}
return FHIRRegistry.getInstance().getResource("http://hl7.org/fhir/OperationDefinition/Resource-convert",
OperationDefinition.class);
}

@Override
Expand Down
69 changes: 0 additions & 69 deletions operation/fhir-operation-convert/src/main/resources/convert.json

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* (C) Copyright IBM Corp. 2017, 2020
* (C) Copyright IBM Corp. 2017, 2021
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -8,7 +8,6 @@

import static com.ibm.fhir.model.type.String.string;

import java.io.InputStream;
import java.net.URI;
import java.time.ZoneOffset;
import java.util.HashMap;
Expand All @@ -17,8 +16,6 @@
import java.util.UUID;

import com.ibm.fhir.exception.FHIROperationException;
import com.ibm.fhir.model.format.Format;
import com.ibm.fhir.model.parser.FHIRParser;
import com.ibm.fhir.model.resource.Bundle;
import com.ibm.fhir.model.resource.Bundle.Entry;
import com.ibm.fhir.model.resource.Composition;
Expand All @@ -32,6 +29,7 @@
import com.ibm.fhir.model.type.Reference;
import com.ibm.fhir.model.type.Uri;
import com.ibm.fhir.model.type.code.BundleType;
import com.ibm.fhir.registry.FHIRRegistry;
import com.ibm.fhir.server.operation.spi.AbstractOperation;
import com.ibm.fhir.server.operation.spi.FHIROperationContext;
import com.ibm.fhir.server.operation.spi.FHIRResourceHelpers;
Expand All @@ -41,39 +39,36 @@
public class DocumentOperation extends AbstractOperation {
@Override
protected OperationDefinition buildOperationDefinition() {
try (InputStream in = getClass().getClassLoader().getResourceAsStream("document.json");){
return FHIRParser.parser(Format.JSON).parse(in);
} catch (Exception e) {
throw new Error(e);
}
return FHIRRegistry.getInstance().getResource("http://hl7.org/fhir/OperationDefinition/Composition-document",
OperationDefinition.class);
}

@Override
protected Parameters doInvoke(FHIROperationContext operationContext, Class<? extends Resource> resourceType, String logicalId, String versionId, Parameters parameters,
FHIRResourceHelpers resourceHelper) throws FHIROperationException {
protected Parameters doInvoke(FHIROperationContext operationContext, Class<? extends Resource> resourceType, String logicalId,
String versionId, Parameters parameters, FHIRResourceHelpers resourceHelper) throws FHIROperationException {
try {
Composition composition = null;

Resource resource = resourceHelper.doRead("Composition", logicalId, false, false, null, null);
if (resource == null) {
throw new FHIROperationException("Could not find composition with id: " + logicalId);
}

composition = (Composition) resource;

Bundle bundle = buildDocument(operationContext, composition, resourceHelper);
Parameter persistParameter = getParameter(parameters, "persist");

if (persistParameter != null) {
com.ibm.fhir.model.type.Boolean persistParameterValue = persistParameter.getValue().as(com.ibm.fhir.model.type.Boolean.class); //getValueBoolean();

if (persistParameterValue != null) {
boolean persist = false;

if (persistParameterValue.getValue() != null) {
persist = persistParameterValue.getValue();
}

if (persist) {
// FHIRResourceHelper resourceHelper = (FHIRResourceHelper) operationContext.getProperty(FHIROperationContext.PROPNAME_RESOURCE_HELPER;
FHIRRestOperationResponse response = resourceHelper.doCreate("Bundle", bundle, null, null, false);
Expand All @@ -84,22 +79,22 @@ protected Parameters doInvoke(FHIROperationContext operationContext, Class<? ext
}
}
}


return FHIROperationUtil.getOutputParameters(bundle);
} catch (FHIROperationException e) {
throw e;
} catch (Exception e) {
throw new FHIROperationException("An error occurred during the document operation", e);
}
}

private Bundle buildDocument(FHIROperationContext operationContext, Composition composition, FHIRResourceHelpers resourceHelper) throws Exception {
//Bundle document = factory.createBundle();
//document.setType(factory.createBundleType().withValue(BundleTypeList.DOCUMENT));

Bundle.Builder documentBuilder = Bundle.builder().type(BundleType.DOCUMENT);

// the composition is the first bundle entry in the document
Bundle.Entry.Builder entryBuilder = Entry.builder(); //createBundleEntry();
//ResourceContainer container = factory.createResourceContainer();
Expand All @@ -110,44 +105,44 @@ private Bundle buildDocument(FHIROperationContext operationContext, Composition
//FHIRUtil.setResourceContainerResource(container, resource);
//bundleEntry.setResource(composition);
entryBuilder.resource(composition);

setFullUrl(operationContext, entryBuilder, "Composition/" + composition.getId());

//document.getEntry().add(bundleEntry);
documentBuilder.entry(entryBuilder.build());

Map<String, Resource> resources = new HashMap<String, Resource>();

// Composition.subject
addBundleEntry(operationContext, documentBuilder, composition.getSubject(), resourceHelper, resources);

// Composition.author
for (Reference author : composition.getAuthor()) {
addBundleEntry(operationContext, documentBuilder, author, resourceHelper, resources);
}

// Composition.attester.party
for (Composition.Attester attester : composition.getAttester()) {
addBundleEntry(operationContext, documentBuilder, attester.getParty(), resourceHelper, resources);
}

// Composition.custodian
addBundleEntry(operationContext, documentBuilder, composition.getCustodian(), resourceHelper, resources);

// Composition.event.detail
for (Composition.Event event : composition.getEvent()) {
for (Reference detail : event.getDetail()) {
addBundleEntry(operationContext, documentBuilder, detail, resourceHelper, resources);
}
}

// Composition.encounter
addBundleEntry(operationContext, documentBuilder, composition.getEncounter(), resourceHelper, resources);

// Composition.section.entry
addBundleEntries(operationContext, documentBuilder, composition.getSection(), resourceHelper, resources);


return documentBuilder.timestamp(Instant.now(ZoneOffset.UTC))
.identifier(Identifier.builder()
.system(Uri.of("http://hl7.org/fhir/OperationDefinition/Composition-document")).value(string("urn:uuid:" + UUID.randomUUID().toString()))
Expand All @@ -160,72 +155,72 @@ private Bundle buildDocument(FHIROperationContext operationContext, Composition
if (reference == null) {
return;
}

if (reference.getReference() == null) {
throw new FHIROperationException("Empty reference object is not allowed");
}

String referenceValue = reference.getReference().getValue();
if (referenceValue == null) {
throw new FHIROperationException("Empty reference value is not allowed");
}

Resource resource = resources.get(referenceValue);

if (resource == null) {
String[] referenceTokens = referenceValue.split("/");

// assumption: references will be relative {resourceTypeName}/{logicalId}
if (referenceTokens.length != 2) {
throw new FHIROperationException("Could not parse reference value: " + referenceValue);
}

String resourceTypeName = referenceTokens[0];
String logicalId = referenceTokens[1];

resource = resourceHelper.doRead(resourceTypeName, logicalId, false, false, null, null);

if (resource == null) {
throw new FHIROperationException("Could not find resource for reference value: " + referenceValue);
}

resources.put(referenceValue, resource);

// create a bundle entry for the resource
//BundleEntry bundleEntry = factory.createBundleEntry();

//ResourceContainer container = factory.createResourceContainer();
//FHIRUtil.setResourceContainerResource(container, resource);

Bundle.Entry.Builder entryBuilder = Entry.builder(); //createBundleEntry();
entryBuilder.resource(resource);

setFullUrl(operationContext, entryBuilder, referenceValue);

//document.getEntry().add(bundleEntry);
documentBuilder.entry(entryBuilder.build());
}
}

private void addBundleEntries(FHIROperationContext operationContext, Bundle.Builder documentBuilder, List<Composition.Section> sections, FHIRResourceHelpers resourceHelper, Map<String, Resource> resources) throws Exception {
for (Composition.Section section : sections) {
for (Composition.Section section : sections) {
// process entries for this section
for (Reference entry : section.getEntry()) {
addBundleEntry(operationContext, documentBuilder, entry, resourceHelper, resources);
}

// process subsections
addBundleEntries(operationContext, documentBuilder, section.getSection(), resourceHelper, resources);
}
}

private void setFullUrl(FHIROperationContext operationContext, Bundle.Entry.Builder entryBuilder, String referenceValue) {
String requestBaseURI = (String) operationContext.getProperty(FHIROperationContext.PROPNAME_REQUEST_BASE_URI);
if (requestBaseURI != null) {
entryBuilder.fullUrl(uri(requestBaseURI + "/" + referenceValue));
}
}

private static Uri uri(String uri) {
return Uri.builder().value(uri).build();
}
Expand Down
Loading

0 comments on commit d8104dc

Please sign in to comment.