Added ability to modify URLs in BundleUtil

This commit is contained in:
Ken Stevens 2019-10-03 09:46:32 -04:00
parent 260cee023a
commit 29e7cdc476
32 changed files with 261 additions and 98 deletions

View File

@ -32,6 +32,7 @@ import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType; import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType; import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
import ca.uhn.fhir.util.*; import ca.uhn.fhir.util.*;
import ca.uhn.fhir.util.bundle.BundleUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;

View File

@ -0,0 +1,28 @@
package ca.uhn.fhir.util.bundle;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.ParametersUtil;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
class BundleEntryMutator {
private final IBase myEntry;
private final BaseRuntimeChildDefinition myRequestChildDef;
private final BaseRuntimeElementCompositeDefinition<?> myRequestChildContentsDef;
BundleEntryMutator(IBase theEntry, BaseRuntimeChildDefinition theRequestChildDef, BaseRuntimeElementCompositeDefinition<?> theRequestChildContentsDef) {
myEntry = theEntry;
myRequestChildDef = theRequestChildDef;
myRequestChildContentsDef = theRequestChildContentsDef;
}
void setRequestUrl(FhirContext theFhirContext, String theRequestUrl) {
BaseRuntimeChildDefinition requestUrlChildDef = myRequestChildContentsDef.getChildByName("url");
IPrimitiveType<?> url = ParametersUtil.createUri(theFhirContext, theRequestUrl);
for (IBase nextRequest : myRequestChildDef.getAccessor().getValues(myEntry)) {
requestUrlChildDef.getMutator().addValue(nextRequest, url);
}
}
}

View File

@ -0,0 +1,35 @@
package ca.uhn.fhir.util.bundle;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import org.hl7.fhir.instance.model.api.IBaseResource;
public class BundleEntryParts {
private final RequestTypeEnum myRequestType;
private final IBaseResource myResource;
private final String myUrl;
private final String myConditionalUrl;
BundleEntryParts(RequestTypeEnum theRequestType, String theUrl, IBaseResource theResource, String theConditionalUrl) {
super();
myRequestType = theRequestType;
myUrl = theUrl;
myResource = theResource;
myConditionalUrl = theConditionalUrl;
}
public RequestTypeEnum getRequestType() {
return myRequestType;
}
public IBaseResource getResource() {
return myResource;
}
public String getConditionalUrl() {
return myConditionalUrl;
}
public String getUrl() {
return myUrl;
}
}

View File

@ -1,9 +1,6 @@
package ca.uhn.fhir.util; package ca.uhn.fhir.util.bundle;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.*;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
@ -14,6 +11,7 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
@ -42,37 +40,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
*/ */
public class BundleUtil { public class BundleUtil {
public static class BundleEntryParts {
private final RequestTypeEnum myRequestType;
private final IBaseResource myResource;
private final String myUrl;
private final String myConditionalUrl;
BundleEntryParts(RequestTypeEnum theRequestType, String theUrl, IBaseResource theResource, String theConditionalUrl) {
super();
myRequestType = theRequestType;
myUrl = theUrl;
myResource = theResource;
myConditionalUrl = theConditionalUrl;
}
public RequestTypeEnum getRequestType() {
return myRequestType;
}
public IBaseResource getResource() {
return myResource;
}
public String getConditionalUrl() {
return myConditionalUrl;
}
public String getUrl() {
return myUrl;
}
}
/** /**
* @return Returns <code>null</code> if the link isn't found or has no value * @return Returns <code>null</code> if the link isn't found or has no value
*/ */
@ -185,20 +152,26 @@ public class BundleUtil {
* Extract all of the resources from a given bundle * Extract all of the resources from a given bundle
*/ */
public static List<BundleEntryParts> toListOfEntries(FhirContext theContext, IBaseBundle theBundle) { public static List<BundleEntryParts> toListOfEntries(FhirContext theContext, IBaseBundle theBundle) {
List<BundleEntryParts> retVal = new ArrayList<>();
RuntimeResourceDefinition def = theContext.getResourceDefinition(theBundle); EntryListAccumulator entryListAccumulator = new EntryListAccumulator();
BaseRuntimeChildDefinition entryChild = def.getChildByName("entry"); processEntries(theContext, theBundle, entryListAccumulator);
List<IBase> entries = entryChild.getAccessor().getValues(theBundle); return entryListAccumulator.getList();
}
BaseRuntimeElementCompositeDefinition<?> entryChildElem = (BaseRuntimeElementCompositeDefinition<?>) entryChild.getChildByName("entry");
BaseRuntimeChildDefinition resourceChild = entryChildElem.getChildByName("resource"); public static void processEntries(FhirContext theContext, IBaseBundle theBundle, Consumer<ModifiableBundleEntry> theProcessor) {
BaseRuntimeChildDefinition requestChild = entryChildElem.getChildByName("request"); RuntimeResourceDefinition bundleDef = theContext.getResourceDefinition(theBundle);
BaseRuntimeElementCompositeDefinition<?> requestElem = (BaseRuntimeElementCompositeDefinition<?>) requestChild.getChildByName("request"); BaseRuntimeChildDefinition entryChildDef = bundleDef.getChildByName("entry");
BaseRuntimeChildDefinition requestUrlChild = requestElem.getChildByName("url"); List<IBase> entries = entryChildDef.getAccessor().getValues(theBundle);
BaseRuntimeChildDefinition requestIfNoneExistChild = requestElem.getChildByName("ifNoneExist");
BaseRuntimeChildDefinition methodChild = requestElem.getChildByName("method"); BaseRuntimeElementCompositeDefinition<?> entryChildContentsDef = (BaseRuntimeElementCompositeDefinition<?>) entryChildDef.getChildByName("entry");
BaseRuntimeChildDefinition resourceChildDef = entryChildContentsDef.getChildByName("resource");
BaseRuntimeChildDefinition requestChildDef = entryChildContentsDef.getChildByName("request");
BaseRuntimeElementCompositeDefinition<?> requestChildContentsDef = (BaseRuntimeElementCompositeDefinition<?>) requestChildDef.getChildByName("request");
BaseRuntimeChildDefinition requestUrlChildDef = requestChildContentsDef.getChildByName("url");
BaseRuntimeChildDefinition requestIfNoneExistChildDef = requestChildContentsDef.getChildByName("ifNoneExist");
BaseRuntimeChildDefinition methodChildDef = requestChildContentsDef.getChildByName("method");
for (IBase nextEntry : entries) { for (IBase nextEntry : entries) {
IBaseResource resource = null; IBaseResource resource = null;
@ -206,15 +179,15 @@ public class BundleUtil {
RequestTypeEnum requestType = null; RequestTypeEnum requestType = null;
String conditionalUrl = null; String conditionalUrl = null;
for (IBase next : resourceChild.getAccessor().getValues(nextEntry)) { for (IBase nextResource : resourceChildDef.getAccessor().getValues(nextEntry)) {
resource = (IBaseResource) next; resource = (IBaseResource) nextResource;
} }
for (IBase nextRequest : requestChild.getAccessor().getValues(nextEntry)) { for (IBase nextRequest : requestChildDef.getAccessor().getValues(nextEntry)) {
for (IBase nextUrl : requestUrlChild.getAccessor().getValues(nextRequest)) { for (IBase nextUrl : requestUrlChildDef.getAccessor().getValues(nextRequest)) {
url = ((IPrimitiveType<?>) nextUrl).getValueAsString(); url = ((IPrimitiveType<?>) nextUrl).getValueAsString();
} }
for (IBase nextUrl : methodChild.getAccessor().getValues(nextRequest)) { for (IBase nextMethod : methodChildDef.getAccessor().getValues(nextRequest)) {
String methodString = ((IPrimitiveType<?>) nextUrl).getValueAsString(); String methodString = ((IPrimitiveType<?>) nextMethod).getValueAsString();
if (isNotBlank(methodString)) { if (isNotBlank(methodString)) {
requestType = RequestTypeEnum.valueOf(methodString); requestType = RequestTypeEnum.valueOf(methodString);
} }
@ -227,7 +200,7 @@ public class BundleUtil {
conditionalUrl = url != null && url.contains("?") ? url : null; conditionalUrl = url != null && url.contains("?") ? url : null;
break; break;
case POST: case POST:
List<IBase> ifNoneExistReps = requestIfNoneExistChild.getAccessor().getValues(nextRequest); List<IBase> ifNoneExistReps = requestIfNoneExistChildDef.getAccessor().getValues(nextRequest);
if (ifNoneExistReps.size() > 0) { if (ifNoneExistReps.size() > 0) {
IPrimitiveType<?> ifNoneExist = (IPrimitiveType<?>) ifNoneExistReps.get(0); IPrimitiveType<?> ifNoneExist = (IPrimitiveType<?>) ifNoneExistReps.get(0);
conditionalUrl = ifNoneExist.getValueAsString(); conditionalUrl = ifNoneExist.getValueAsString();
@ -241,11 +214,10 @@ public class BundleUtil {
* All 3 might be null - That's ok because we still want to know the * All 3 might be null - That's ok because we still want to know the
* order in the original bundle. * order in the original bundle.
*/ */
retVal.add(new BundleEntryParts(requestType, url, resource, conditionalUrl)); BundleEntryMutator mutator = new BundleEntryMutator(nextEntry, requestChildDef, requestChildContentsDef);
ModifiableBundleEntry entry = new ModifiableBundleEntry(new BundleEntryParts(requestType, url, resource, conditionalUrl), mutator);
theProcessor.accept(entry);
} }
return retVal;
} }
/** /**
@ -278,4 +250,6 @@ public class BundleUtil {
} }
return retVal; return retVal;
} }
} }

View File

@ -0,0 +1,18 @@
package ca.uhn.fhir.util.bundle;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
class EntryListAccumulator implements Consumer<ModifiableBundleEntry> {
private final List<BundleEntryParts> myList = new ArrayList<>();
@Override
public void accept(ModifiableBundleEntry theModifiableBundleEntry) {
myList.add(theModifiableBundleEntry.getBundleEntryParts());
}
public List<BundleEntryParts> getList() {
return myList;
}
}

View File

@ -0,0 +1,32 @@
package ca.uhn.fhir.util.bundle;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.ParametersUtil;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
public class ModifiableBundleEntry {
private final BundleEntryParts myBundleEntryParts;
private final BundleEntryMutator myBundleEntryMutator;
ModifiableBundleEntry(BundleEntryParts theBundleEntryParts, BundleEntryMutator theBundleEntryMutator) {
myBundleEntryParts = theBundleEntryParts;
myBundleEntryMutator = theBundleEntryMutator;
}
BundleEntryParts getBundleEntryParts() {
return myBundleEntryParts;
}
void setRequestUrl(FhirContext theFhirContext, String theRequestUrl) {
myBundleEntryMutator.setRequestUrl(theFhirContext, theRequestUrl);
}
String getRequestUrl() {
return myBundleEntryParts.getUrl();
}
}

View File

@ -23,7 +23,7 @@ package ca.uhn.fhir.validation.schematron;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.validation.*; import ca.uhn.fhir.validation.*;
import com.helger.commons.error.IError; import com.helger.commons.error.IError;
import com.helger.commons.error.list.IErrorList; import com.helger.commons.error.list.IErrorList;

View File

@ -35,7 +35,7 @@ import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory;
import ca.uhn.fhir.rest.client.apache.GZipContentInterceptor; import ca.uhn.fhir.rest.client.apache.GZipContentInterceptor;
import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.ResourceReferenceInfo; import ca.uhn.fhir.util.ResourceReferenceInfo;
import ca.uhn.fhir.validation.FhirValidator; import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult; import ca.uhn.fhir.validation.ValidationResult;

View File

@ -22,7 +22,6 @@ package ca.uhn.fhir.rest.client.method;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
@ -37,7 +36,7 @@ import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException; import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.ReflectionUtil; import ca.uhn.fhir.util.ReflectionUtil;
public abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Object> { public abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Object> {

View File

@ -8,7 +8,7 @@ import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry; import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil; import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;

View File

@ -25,7 +25,7 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.test.utilities.LoggingRule; import ca.uhn.fhir.test.utilities.LoggingRule;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;

View File

@ -126,7 +126,7 @@ import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.StopWatch; import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;

View File

@ -16,7 +16,7 @@ import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor; import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;

View File

@ -10,7 +10,7 @@ import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.interceptor.consent.*; import ca.uhn.fhir.rest.server.interceptor.consent.*;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;

View File

@ -19,7 +19,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor; import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor; import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.validation.ResultSeverityEnum; import ca.uhn.fhir.validation.ResultSeverityEnum;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;

View File

@ -11,7 +11,7 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.test.utilities.JettyUtil;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import net.ttddyy.dsproxy.QueryCount; import net.ttddyy.dsproxy.QueryCount;

View File

@ -12,7 +12,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.test.utilities.JettyUtil;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import net.ttddyy.dsproxy.QueryCount; import net.ttddyy.dsproxy.QueryCount;
import net.ttddyy.dsproxy.listener.SingleQueryCountHolder; import net.ttddyy.dsproxy.listener.SingleQueryCountHolder;

View File

@ -8,7 +8,7 @@ import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry; import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil; import ch.qos.logback.core.joran.util.ConfigurationWatchListUtil;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;

View File

@ -29,7 +29,7 @@ import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.server.SimpleBundleProvider; import ca.uhn.fhir.rest.server.SimpleBundleProvider;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.slf4j.Logger; import org.slf4j.Logger;

View File

@ -29,7 +29,7 @@ import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.server.SimpleBundleProvider; import ca.uhn.fhir.rest.server.SimpleBundleProvider;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;

View File

@ -11,8 +11,8 @@ import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor.Verdict; import ca.uhn.fhir.rest.server.interceptor.auth.AuthorizationInterceptor.Verdict;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.BundleUtil.BundleEntryParts; import ca.uhn.fhir.util.bundle.BundleEntryParts;
import ca.uhn.fhir.util.FhirTerser; import ca.uhn.fhir.util.FhirTerser;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;

View File

@ -23,15 +23,21 @@ package ca.uhn.fhir.rest.server.interceptor.auth;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Pointcut;
import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.ParameterUtil; import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter; import ca.uhn.fhir.util.bundle.BundleEntryParts;
import ca.uhn.fhir.util.bundle.BundleUtil;
import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -60,7 +66,8 @@ import java.util.*;
* *
* @see AuthorizationInterceptor * @see AuthorizationInterceptor
*/ */
public abstract class SearchNarrowingInterceptor extends InterceptorAdapter { public class SearchNarrowingInterceptor {
private static final Logger ourLog = LoggerFactory.getLogger(SearchNarrowingInterceptor.class);
/** /**
* Subclasses should override this method to supply the set of compartments that * Subclasses should override this method to supply the set of compartments that
@ -79,10 +86,8 @@ public abstract class SearchNarrowingInterceptor extends InterceptorAdapter {
return null; return null;
} }
@Hook(Pointcut.SERVER_INCOMING_REQUEST_POST_PROCESSED)
@Override
public boolean incomingRequestPostProcessed(RequestDetails theRequestDetails, HttpServletRequest theRequest, HttpServletResponse theResponse) throws AuthenticationException { public boolean incomingRequestPostProcessed(RequestDetails theRequestDetails, HttpServletRequest theRequest, HttpServletResponse theResponse) throws AuthenticationException {
// We don't support this operation type yet // We don't support this operation type yet
Validate.isTrue(theRequestDetails.getRestOperationType() != RestOperationTypeEnum.SEARCH_SYSTEM); Validate.isTrue(theRequestDetails.getRestOperationType() != RestOperationTypeEnum.SEARCH_SYSTEM);
@ -171,6 +176,24 @@ public abstract class SearchNarrowingInterceptor extends InterceptorAdapter {
return true; return true;
} }
@Hook(Pointcut.SERVER_INCOMING_REQUEST_PRE_HANDLED)
public void incomingRequestPreHandled(RequestDetails theRequestDetails, HttpServletRequest theRequest, HttpServletResponse theResponse) throws AuthenticationException {
if (theRequestDetails.getRestOperationType() != RestOperationTypeEnum.TRANSACTION) {
return;
}
incomingRequestPostProcessedBundle(theRequestDetails, theRequest, theResponse);
}
private void incomingRequestPostProcessedBundle(RequestDetails theRequestDetails, HttpServletRequest theRequest, HttpServletResponse theResponse) {
IBaseBundle bundle = (IBaseBundle) theRequestDetails.getResource();
FhirContext ctx = theRequestDetails.getFhirContext();
List<BundleEntryParts> entries = BundleUtil.toListOfEntries(ctx, bundle);
for (BundleEntryParts entry : entries) {
bundle.setUserData("test", "bark");
}
theRequestDetails.setResource(bundle);
}
private void processResourcesOrCompartments(RequestDetails theRequestDetails, RuntimeResourceDefinition theResDef, HashMap<String, List<String>> theParameterToOrValues, Collection<String> theResourcesOrCompartments, boolean theAreCompartments) { private void processResourcesOrCompartments(RequestDetails theRequestDetails, RuntimeResourceDefinition theResDef, HashMap<String, List<String>> theParameterToOrValues, Collection<String> theResourcesOrCompartments, boolean theAreCompartments) {
String lastCompartmentName = null; String lastCompartmentName = null;
String lastSearchParamName = null; String lastSearchParamName = null;

View File

@ -34,7 +34,7 @@ import ca.uhn.fhir.rest.api.server.ResponseDetails;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.ForbiddenOperationException; import ca.uhn.fhir.rest.server.exceptions.ForbiddenOperationException;
import ca.uhn.fhir.rest.server.util.ICachedSearchDetails; import ca.uhn.fhir.rest.server.util.ICachedSearchDetails;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.IModelVisitor2; import ca.uhn.fhir.util.IModelVisitor2;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.*; import org.hl7.fhir.instance.model.api.*;

View File

@ -28,7 +28,7 @@ import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;

View File

@ -17,7 +17,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.test.utilities.JettyUtil;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.ElementUtil; import ca.uhn.fhir.util.ElementUtil;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;

View File

@ -13,7 +13,7 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.test.utilities.JettyUtil;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.ElementUtil; import ca.uhn.fhir.util.ElementUtil;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;

View File

@ -15,6 +15,7 @@ import java.util.concurrent.TimeUnit;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.test.utilities.JettyUtil;
import ca.uhn.fhir.util.bundle.BundleUtil;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.http.*; import org.apache.http.*;
import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.entity.UrlEncodedFormEntity;

View File

@ -40,6 +40,8 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.*; import org.hl7.fhir.r4.model.*;
import org.junit.*; import org.junit.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;

View File

@ -5,6 +5,8 @@ import ca.uhn.fhir.model.api.IQueryParameterOr;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.annotation.OptionalParam; import ca.uhn.fhir.rest.annotation.OptionalParam;
import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.client.api.IGenericClient; import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
@ -22,9 +24,7 @@ import org.eclipse.jetty.servlet.ServletHolder;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Resource;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
@ -39,8 +39,11 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.test.utilities.JettyUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SearchNarrowingInterceptorTest { public class SearchNarrowingInterceptorTest {
private static final Logger ourLog = LoggerFactory.getLogger(SearchNarrowingInterceptorTest.class);
private static String ourLastHitMethod; private static String ourLastHitMethod;
private static FhirContext ourCtx; private static FhirContext ourCtx;
@ -104,6 +107,31 @@ public class SearchNarrowingInterceptorTest {
assertThat(toStrings(ourLastPatientParam), Matchers.contains("Patient/123,Patient/456")); assertThat(toStrings(ourLastPatientParam), Matchers.contains("Patient/123,Patient/456"));
} }
@Test
public void testNarrowObservationsByPatientContext_ClientRequestedBundleNoParams() {
ourNextCompartmentList = new AuthorizedList().addCompartments("Patient/123", "Patient/456");
Bundle bundle = new Bundle();
bundle.setType(Bundle.BundleType.TRANSACTION);
bundle.addEntry().getRequest().setMethod(Bundle.HTTPVerb.GET).setUrl("Observation");
ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
ourClient
.transaction()
.withBundle(bundle)
.execute();
assertEquals("Observation.search", ourLastHitMethod);
assertNull(ourLastIdParam);
assertNull(ourLastCodeParam);
assertNull(ourLastSubjectParam);
assertNull(ourLastPerformerParam);
assertThat(toStrings(ourLastPatientParam), Matchers.contains("Patient/123,Patient/456"));
}
/** /**
* Should not make any changes * Should not make any changes
*/ */
@ -274,6 +302,14 @@ public class SearchNarrowingInterceptorTest {
} }
public static class DummySystemProvider {
@Transaction
public Bundle transaction(@TransactionParam Bundle theInput) {
return theInput;
}
}
private static class MySearchNarrowingInterceptor extends SearchNarrowingInterceptor { private static class MySearchNarrowingInterceptor extends SearchNarrowingInterceptor {
@Override @Override
protected AuthorizedList buildAuthorizedList(RequestDetails theRequestDetails) { protected AuthorizedList buildAuthorizedList(RequestDetails theRequestDetails) {
@ -298,10 +334,12 @@ public class SearchNarrowingInterceptorTest {
DummyPatientResourceProvider patProvider = new DummyPatientResourceProvider(); DummyPatientResourceProvider patProvider = new DummyPatientResourceProvider();
DummyObservationResourceProvider obsProv = new DummyObservationResourceProvider(); DummyObservationResourceProvider obsProv = new DummyObservationResourceProvider();
DummySystemProvider systemProv = new DummySystemProvider();
ServletHandler proxyHandler = new ServletHandler(); ServletHandler proxyHandler = new ServletHandler();
RestfulServer ourServlet = new RestfulServer(ourCtx); RestfulServer ourServlet = new RestfulServer(ourCtx);
ourServlet.setFhirContext(ourCtx); ourServlet.setFhirContext(ourCtx);
ourServlet.registerProviders(systemProv);
ourServlet.setResourceProviders(patProvider, obsProv); ourServlet.setResourceProviders(patProvider, obsProv);
ourServlet.setPagingProvider(new FifoMemoryPagingProvider(100)); ourServlet.setPagingProvider(new FifoMemoryPagingProvider(100));
ourServlet.registerInterceptor(new MySearchNarrowingInterceptor()); ourServlet.registerInterceptor(new MySearchNarrowingInterceptor());

View File

@ -1,13 +1,18 @@
package ca.uhn.fhir.util; package ca.uhn.fhir.util.bundle;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.bundle.ModifiableBundleEntry;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
import static org.junit.Assert.assertEquals;
public class BundleUtilTest { public class BundleUtilTest {
@ -18,27 +23,27 @@ public class BundleUtilTest {
Bundle b = new Bundle(); Bundle b = new Bundle();
b.getLinkOrCreate("prev").setUrl("http://bar"); b.getLinkOrCreate("prev").setUrl("http://bar");
b.getLinkOrCreate("next").setUrl("http://foo"); b.getLinkOrCreate("next").setUrl("http://foo");
Assert.assertEquals("http://foo", BundleUtil.getLinkUrlOfType(ourCtx, b, "next")); assertEquals("http://foo", BundleUtil.getLinkUrlOfType(ourCtx, b, "next"));
} }
@Test @Test
public void testGetLinkDoesntExist() { public void testGetLinkDoesntExist() {
Bundle b = new Bundle(); Bundle b = new Bundle();
b.getLinkOrCreate("prev").setUrl("http://bar"); b.getLinkOrCreate("prev").setUrl("http://bar");
Assert.assertEquals(null, BundleUtil.getLinkUrlOfType(ourCtx, b, "next")); assertEquals(null, BundleUtil.getLinkUrlOfType(ourCtx, b, "next"));
} }
@Test @Test
public void testGetTotal() { public void testGetTotal() {
Bundle b = new Bundle(); Bundle b = new Bundle();
b.setTotal(999); b.setTotal(999);
Assert.assertEquals(999, BundleUtil.getTotal(ourCtx, b).intValue()); assertEquals(999, BundleUtil.getTotal(ourCtx, b).intValue());
} }
@Test @Test
public void testGetTotalNull() { public void testGetTotalNull() {
Bundle b = new Bundle(); Bundle b = new Bundle();
Assert.assertEquals(null, BundleUtil.getTotal(ourCtx, b)); assertEquals(null, BundleUtil.getTotal(ourCtx, b));
} }
@Test @Test
@ -48,9 +53,18 @@ public class BundleUtilTest {
bundle.addEntry(new Bundle.BundleEntryComponent().setResource(new Patient())); bundle.addEntry(new Bundle.BundleEntryComponent().setResource(new Patient()));
} }
List<Patient> list = BundleUtil.toListOfResourcesOfType(ourCtx, bundle, Patient.class); List<Patient> list = BundleUtil.toListOfResourcesOfType(ourCtx, bundle, Patient.class);
Assert.assertEquals(5, list.size()); assertEquals(5, list.size());
} }
@Test
public void testProcessEntries() {
Bundle bundle = new Bundle();
bundle.setType(Bundle.BundleType.TRANSACTION);
bundle.addEntry().getRequest().setMethod(Bundle.HTTPVerb.GET).setUrl("Observation");
Consumer<ModifiableBundleEntry> consumer = e -> e.setRequestUrl(ourCtx, e.getRequestUrl() + "?foo=bar");
BundleUtil.processEntries(ourCtx, bundle, consumer);
assertEquals("Observation?foo=bar", bundle.getEntryFirstRep().getRequest().getUrl());
}
@AfterClass @AfterClass
public static void afterClassClearContext() { public static void afterClassClearContext() {

View File

@ -10,7 +10,7 @@ import ca.uhn.fhir.rest.client.impl.BaseClient;
import ca.uhn.fhir.rest.client.impl.GenericClient; import ca.uhn.fhir.rest.client.impl.GenericClient;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
@ -43,7 +43,6 @@ import org.mockito.stubbing.Answer;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringReader; import java.io.StringReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;

View File

@ -6,8 +6,7 @@ import java.util.Collection;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition; import ca.uhn.fhir.util.bundle.BundleUtil;
import ca.uhn.fhir.util.BundleUtil;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;