Updated address validation handling

This commit is contained in:
Nick Goupinets 2021-04-23 18:55:51 -04:00
parent 634522b405
commit ac2aac4342
5 changed files with 79 additions and 12 deletions

View File

@ -333,6 +333,22 @@ public final class TerserUtil {
childDefinition.getAccessor().getValues(theResource).clear();
}
/**
* Clears the specified field on the element provided
*
* @param theFhirContext Context holding resource definition
* @param theFieldName Name of the field to clear values for
* @param theBase The element definition to clear values on
*/
public static void clearField(FhirContext theFhirContext, String theFieldName, IBase theBase) {
BaseRuntimeElementDefinition definition = theFhirContext.getElementDefinition(theBase.getClass());
BaseRuntimeChildDefinition childDefinition = definition.getChildByName(theFieldName);
if (childDefinition == null) {
throw new IllegalStateException(String.format("Field %s does not exist", theFieldName));
}
childDefinition.getAccessor().getValues(theBase).clear();
}
/**
* Sets the provided field with the given values. This method will add to the collection of existing field values
* in case of multiple cardinality. Use {@link #clearField(FhirContext, String, IBaseResource)}

View File

@ -21,6 +21,8 @@ package ca.uhn.fhir.rest.server.interceptor.validation.address;
*/
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.interceptor.api.Hook;
@ -29,9 +31,13 @@ import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.interceptor.ConfigLoader;
import ca.uhn.fhir.util.ExtensionUtil;
import ca.uhn.fhir.util.FhirTerser;
import ca.uhn.fhir.util.IModelVisitor2;
import ca.uhn.fhir.util.TerserUtil;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IDomainResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -55,7 +61,6 @@ public class AddressValidatingInterceptor {
private Properties myProperties;
public AddressValidatingInterceptor() {
super();
@ -66,6 +71,7 @@ public class AddressValidatingInterceptor {
public AddressValidatingInterceptor(Properties theProperties) {
super();
myProperties = theProperties;
start(theProperties);
}
@ -136,9 +142,9 @@ public class AddressValidatingInterceptor {
AddressValidationResult validationResult = getAddressValidator().isValid(theAddress, theFhirContext);
ourLog.debug("Validated address {}", validationResult);
clearPossibleDuplicatesDueToTerserCloning(theAddress, theFhirContext);
ExtensionUtil.setExtensionAsString(theFhirContext, theAddress, getExtensionUrl(),
validationResult.isValid() ? IAddressValidator.EXT_VALUE_VALID : IAddressValidator.EXT_VALUE_INVALID);
theFhirContext.newTerser().cloneInto(validationResult.getValidatedAddress(), theAddress, true);
} catch (Exception ex) {
ourLog.warn("Unable to validate address", ex);
@ -146,6 +152,11 @@ public class AddressValidatingInterceptor {
}
}
private void clearPossibleDuplicatesDueToTerserCloning(IBase theAddress, FhirContext theFhirContext) {
TerserUtil.clearField(theFhirContext, "line", theAddress);
ExtensionUtil.clearExtensionsByUrl(theAddress, getExtensionUrl());
}
protected String getExtensionUrl() {
if (getProperties().containsKey(PROPERTY_EXTENSION_URL)) {
return getProperties().getProperty(PROPERTY_EXTENSION_URL);

View File

@ -113,12 +113,9 @@ public class FieldValidatingInterceptor {
}
private void setValidationStatus(FhirContext ctx, IBase theBase, boolean isValid) {
if (isValid) {
ExtensionUtil.clearExtensionsByUrl(theBase, getValidationExtensionUrl());
} else {
IBaseExtension<?, ?> validationResultExtension = ExtensionUtil.addExtension(theBase, getValidationExtensionUrl());
ExtensionUtil.setExtension(ctx, theBase, getValidationExtensionUrl(), "boolean", Boolean.TRUE);
}
ExtensionUtil.clearExtensionsByUrl(theBase, getValidationExtensionUrl());
IBaseExtension<?, ?> validationResultExtension = ExtensionUtil.addExtension(theBase, getValidationExtensionUrl());
ExtensionUtil.setExtensionAsString(ctx, theBase, getValidationExtensionUrl(), isValid ? "yes" : "no");
}
private String getValidationExtensionUrl() {

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.rest.server.interceptor.validation.address;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.interceptor.validation.address.impl.LoquateAddressValidator;
import org.checkerframework.checker.units.qual.A;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.r4.model.Address;
@ -19,7 +20,9 @@ import java.util.Properties;
import static ca.uhn.fhir.rest.server.interceptor.s13n.StandardizingInterceptor.STANDARDIZATION_DISABLED_HEADER;
import static ca.uhn.fhir.rest.server.interceptor.validation.address.AddressValidatingInterceptor.ADDRESS_VALIDATION_DISABLED_HEADER;
import static ca.uhn.fhir.rest.server.interceptor.validation.address.AddressValidatingInterceptor.PROPERTY_VALIDATOR_CLASS;
import static ca.uhn.fhir.rest.server.interceptor.validation.address.impl.BaseRestfulValidator.PROPERTY_SERVICE_KEY;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -41,6 +44,32 @@ class AddressValidatingInterceptorTest {
private RequestDetails myRequestDetails;
@Test
public void testReal() {
Properties config = new Properties();
config.setProperty(PROPERTY_VALIDATOR_CLASS, LoquateAddressValidator.class.getCanonicalName());
config.setProperty(PROPERTY_SERVICE_KEY, "KR26-JA29-HB16-PA11");
AddressValidatingInterceptor interceptor = new AddressValidatingInterceptor(config);
Address address = new Address();
address.setUse(Address.AddressUse.WORK);
address.addLine("100 Somewhere");
address.setCity("Burloak");
address.setPostalCode("A0A0A0");
address.setCountry("Canada");
interceptor.validateAddress(address, ourCtx);
assertTrue(address.hasExtension());
assertEquals("no", address.getExtensionFirstRep().getValueAsPrimitive().getValueAsString());
assertEquals("100 Somewhere,Burloak", address.getText());
assertEquals(1, address.getLine().size());
assertEquals("100 Somewhere", address.getLine().get(0).getValueAsString());
assertEquals("Burloak", address.getCity());
assertEquals("A0A0A0", address.getPostalCode());
assertEquals("Canada", address.getCountry());
}
@Test
void start() throws Exception {
AddressValidatingInterceptor interceptor = new AddressValidatingInterceptor(new Properties());

View File

@ -2,6 +2,7 @@ package ca.uhn.fhir.util;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import org.checkerframework.checker.units.qual.A;
import org.hl7.fhir.r4.model.Address;
import org.hl7.fhir.r4.model.DateTimeType;
import org.hl7.fhir.r4.model.DateType;
@ -319,12 +320,25 @@ class TerserUtilTest {
@Test
public void testClearFields() {
Patient p1 = new Patient();
p1.addName().setFamily("Doe");
{
Patient p1 = new Patient();
p1.addName().setFamily("Doe");
TerserUtil.clearField(ourFhirContext, "name", p1);
TerserUtil.clearField(ourFhirContext, "name", p1);
assertEquals(0, p1.getName().size());
assertEquals(0, p1.getName().size());
}
{
Address a1 = new Address();
a1.addLine("Line 1");
a1.addLine("Line 2");
a1.setCity("Test");
TerserUtil.clearField(ourFhirContext, "line", a1);
assertEquals(0, a1.getLine().size());
assertEquals("Test", a1.getCity());
}
}
@Test