Merge remote-tracking branch 'origin/master' into call_access_method
This commit is contained in:
commit
dcdbe51e7e
|
@ -109,15 +109,15 @@ public class SingleValidationMessage {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||||
if (myLocationCol != null || myLocationLine != null) {
|
if (myLocationCol != null || myLocationLine != null) {
|
||||||
b.append("myLocationCol", myLocationCol);
|
b.append("col", myLocationCol);
|
||||||
b.append("myLocationRow", myLocationLine);
|
b.append("row", myLocationLine);
|
||||||
}
|
}
|
||||||
if (myLocationString != null) {
|
if (myLocationString != null) {
|
||||||
b.append("myLocationString", myLocationString);
|
b.append("locationString", myLocationString);
|
||||||
}
|
}
|
||||||
b.append("myMessage", myMessage);
|
b.append("message", myMessage);
|
||||||
if (mySeverity != null) {
|
if (mySeverity != null) {
|
||||||
b.append("mySeverity", mySeverity.getCode());
|
b.append("severity", mySeverity.getCode());
|
||||||
}
|
}
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.fusesource.jansi.AnsiConsole;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -52,16 +53,20 @@ public abstract class BaseApp {
|
||||||
loggingConfigOff();
|
loggingConfigOff();
|
||||||
|
|
||||||
// We don't use qualified names for loggers in CLI
|
// We don't use qualified names for loggers in CLI
|
||||||
ourLog = LoggerFactory.getLogger(App.class.getSimpleName());
|
ourLog = LoggerFactory.getLogger(App.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MyShutdownHook myShutdownHook;
|
||||||
|
private boolean myShutdownHookHasNotRun;
|
||||||
|
|
||||||
private void logAppHeader() {
|
private void logAppHeader() {
|
||||||
System.out.flush();
|
System.out.flush();
|
||||||
System.out.println("------------------------------------------------------------");
|
System.out.println("------------------------------------------------------------");
|
||||||
System.out.println("\ud83d\udd25 " + ansi().bold() + " " + provideProductName() + ansi().boldOff() + " " + provideProductVersion() + " - Command Line Tool");
|
System.out.println("\ud83d\udd25 " + ansi().bold() + " " + provideProductName() + ansi().boldOff() + " " + provideProductVersion() + " - Command Line Tool");
|
||||||
System.out.println("------------------------------------------------------------");
|
System.out.println("------------------------------------------------------------");
|
||||||
System.out.println("Max configured JVM memory (Xmx): " + FileHelper.getFileSizeDisplay(Runtime.getRuntime().maxMemory(), 1));
|
System.out.println("Process ID : " + ManagementFactory.getRuntimeMXBean().getName());
|
||||||
System.out.println("Detected Java version: " + System.getProperty("java.version"));
|
System.out.println("Max configured JVM memory (Xmx) : " + FileHelper.getFileSizeDisplay(Runtime.getRuntime().maxMemory(), 1));
|
||||||
|
System.out.println("Detected Java version : " + System.getProperty("java.version"));
|
||||||
System.out.println("------------------------------------------------------------");
|
System.out.println("------------------------------------------------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +202,9 @@ public abstract class BaseApp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myShutdownHook = new MyShutdownHook(command);
|
||||||
|
Runtime.getRuntime().addShutdownHook(myShutdownHook);
|
||||||
|
|
||||||
Options options = command.getOptions();
|
Options options = command.getOptions();
|
||||||
DefaultParser parser = new DefaultParser();
|
DefaultParser parser = new DefaultParser();
|
||||||
CommandLine parsedOptions;
|
CommandLine parsedOptions;
|
||||||
|
@ -215,6 +223,9 @@ public abstract class BaseApp {
|
||||||
// Actually execute the command
|
// Actually execute the command
|
||||||
command.run(parsedOptions);
|
command.run(parsedOptions);
|
||||||
|
|
||||||
|
myShutdownHookHasNotRun = true;
|
||||||
|
runCleanupHookAndUnregister();
|
||||||
|
|
||||||
if (!"true".equals(System.getProperty("test"))) {
|
if (!"true".equals(System.getProperty("test"))) {
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
@ -225,9 +236,11 @@ public abstract class BaseApp {
|
||||||
System.err.println(" " + ansi().fg(Ansi.Color.RED).bold() + e.getMessage());
|
System.err.println(" " + ansi().fg(Ansi.Color.RED).bold() + e.getMessage());
|
||||||
System.err.println("" + ansi().fg(Ansi.Color.WHITE).boldOff());
|
System.err.println("" + ansi().fg(Ansi.Color.WHITE).boldOff());
|
||||||
logCommandUsageNoHeader(command);
|
logCommandUsageNoHeader(command);
|
||||||
|
runCleanupHookAndUnregister();
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
} catch (CommandFailureException e) {
|
} catch (CommandFailureException e) {
|
||||||
ourLog.error(e.getMessage());
|
ourLog.error(e.getMessage());
|
||||||
|
runCleanupHookAndUnregister();
|
||||||
if ("true".equals(System.getProperty("test"))) {
|
if ("true".equals(System.getProperty("test"))) {
|
||||||
throw e;
|
throw e;
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,12 +248,22 @@ public abstract class BaseApp {
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
ourLog.error("Error during execution: ", t);
|
ourLog.error("Error during execution: ", t);
|
||||||
|
runCleanupHookAndUnregister();
|
||||||
if ("true".equals(System.getProperty("test"))) {
|
if ("true".equals(System.getProperty("test"))) {
|
||||||
throw new CommandFailureException("Error: " + t.toString(), t);
|
throw new CommandFailureException("Error: " + t.toString(), t);
|
||||||
} else {
|
} else {
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runCleanupHookAndUnregister() {
|
||||||
|
if (myShutdownHookHasNotRun) {
|
||||||
|
Runtime.getRuntime().removeShutdownHook(myShutdownHook);
|
||||||
|
myShutdownHook.run();
|
||||||
|
myShutdownHookHasNotRun = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateJavaVersion() {
|
private void validateJavaVersion() {
|
||||||
|
@ -275,4 +298,17 @@ public abstract class BaseApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class MyShutdownHook extends Thread {
|
||||||
|
private final BaseCommand myFinalCommand;
|
||||||
|
|
||||||
|
public MyShutdownHook(BaseCommand theFinalCommand) {
|
||||||
|
myFinalCommand = theFinalCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ourLog.info(provideProductName() + " is shutting down...");
|
||||||
|
myFinalCommand.cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,13 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
||||||
addOptionalOption(theOptions, VERBOSE_LOGGING_PARAM, VERBOSE_LOGGING_PARAM_LONGOPT, false, VERBOSE_LOGGING_PARAM_DESC);
|
addOptionalOption(theOptions, VERBOSE_LOGGING_PARAM, VERBOSE_LOGGING_PARAM_LONGOPT, false, VERBOSE_LOGGING_PARAM_DESC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses may override if they want, to do any cleanup they need to do.
|
||||||
|
*/
|
||||||
|
public void cleanup() {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(BaseCommand theO) {
|
public int compareTo(BaseCommand theO) {
|
||||||
return getCommandName().compareTo(theO.getCommandName());
|
return getCommandName().compareTo(theO.getCommandName());
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.commons.cli.CommandLine;
|
||||||
import org.apache.commons.cli.Options;
|
import org.apache.commons.cli.Options;
|
||||||
import org.apache.commons.cli.ParseException;
|
import org.apache.commons.cli.ParseException;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.springframework.web.context.ContextLoader;
|
import org.springframework.web.context.ContextLoader;
|
||||||
|
@ -193,9 +194,22 @@ public class RunServerCommand extends BaseCommand {
|
||||||
ourLog.info("Web Testing UI : http://localhost:{}/", myPort);
|
ourLog.info("Web Testing UI : http://localhost:{}/", myPort);
|
||||||
ourLog.info("Server Base URL: http://localhost:{}{}", myPort, path);
|
ourLog.info("Server Base URL: http://localhost:{}{}", myPort, path);
|
||||||
|
|
||||||
|
// Never quit.. We'll let the user ctrl-C their way out.
|
||||||
|
loopForever();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("InfiniteLoopStatement")
|
||||||
|
private void loopForever() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(DateUtils.MILLIS_PER_MINUTE);
|
||||||
|
} catch (InterruptedException theE) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] theArgs) {
|
public static void main(String[] theArgs) {
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.cli;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.igpacks.parser.IgPackParserDstu2;
|
import ca.uhn.fhir.igpacks.parser.IgPackParserDstu2;
|
||||||
import ca.uhn.fhir.igpacks.parser.IgPackParserDstu3;
|
import ca.uhn.fhir.igpacks.parser.IgPackParserDstu3;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
import ca.uhn.fhir.parser.LenientErrorHandler;
|
import ca.uhn.fhir.parser.LenientErrorHandler;
|
||||||
import ca.uhn.fhir.validation.FhirValidator;
|
import ca.uhn.fhir.validation.FhirValidator;
|
||||||
import ca.uhn.fhir.validation.SingleValidationMessage;
|
import ca.uhn.fhir.validation.SingleValidationMessage;
|
||||||
|
@ -103,7 +104,7 @@ public class ValidateCommand extends BaseCommand {
|
||||||
parseFhirContext(theCommandLine);
|
parseFhirContext(theCommandLine);
|
||||||
|
|
||||||
String fileName = theCommandLine.getOptionValue("n");
|
String fileName = theCommandLine.getOptionValue("n");
|
||||||
String contents = theCommandLine.getOptionValue("c");
|
String contents = theCommandLine.getOptionValue("d");
|
||||||
if (isNotBlank(fileName) && isNotBlank(contents)) {
|
if (isNotBlank(fileName) && isNotBlank(contents)) {
|
||||||
throw new ParseException("Can not supply both a file (-n) and data (-d)");
|
throw new ParseException("Can not supply both a file (-n) and data (-d)");
|
||||||
}
|
}
|
||||||
|
@ -199,7 +200,12 @@ public class ValidateCommand extends BaseCommand {
|
||||||
val.setValidateAgainstStandardSchema(theCommandLine.hasOption("x"));
|
val.setValidateAgainstStandardSchema(theCommandLine.hasOption("x"));
|
||||||
val.setValidateAgainstStandardSchematron(theCommandLine.hasOption("s"));
|
val.setValidateAgainstStandardSchematron(theCommandLine.hasOption("s"));
|
||||||
|
|
||||||
ValidationResult results = val.validateWithResult(contents);
|
ValidationResult results;
|
||||||
|
try {
|
||||||
|
results = val.validateWithResult(contents);
|
||||||
|
} catch (DataFormatException e) {
|
||||||
|
throw new CommandFailureException(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder b = new StringBuilder("Validation results:" + ansi().boldOff());
|
StringBuilder b = new StringBuilder("Validation results:" + ansi().boldOff());
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
|
@ -53,7 +53,6 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
public class ValidationDataUploader extends BaseCommand {
|
public class ValidationDataUploader extends BaseCommand {
|
||||||
// TODO: Don't use qualified names for loggers in HAPI CLI.
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationDataUploader.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationDataUploader.class);
|
||||||
|
|
||||||
private ArrayList<IIdType> myExcludes = new ArrayList<>();
|
private ArrayList<IIdType> myExcludes = new ArrayList<>();
|
||||||
|
@ -354,9 +353,10 @@ public class ValidationDataUploader extends BaseCommand {
|
||||||
ourLog.info("Finished uploading ValueSets");
|
ourLog.info("Finished uploading ValueSets");
|
||||||
|
|
||||||
|
|
||||||
uploadDstu3Profiles(theCtx, client, "profiles-resources");
|
uploadDstu3Profiles(theCtx, client, "profile/profiles-resources");
|
||||||
uploadDstu3Profiles(theCtx, client, "profiles-types");
|
uploadDstu3Profiles(theCtx, client, "profile/profiles-types");
|
||||||
uploadDstu3Profiles(theCtx, client, "profiles-others");
|
uploadDstu3Profiles(theCtx, client, "profile/profiles-others");
|
||||||
|
uploadDstu3Profiles(theCtx, client, "extension/extension-definitions");
|
||||||
|
|
||||||
ourLog.info("Finished uploading ValueSets");
|
ourLog.info("Finished uploading ValueSets");
|
||||||
|
|
||||||
|
@ -446,9 +446,10 @@ public class ValidationDataUploader extends BaseCommand {
|
||||||
ourLog.info("Finished uploading ValueSets");
|
ourLog.info("Finished uploading ValueSets");
|
||||||
|
|
||||||
|
|
||||||
uploadR4Profiles(theCtx, client, "profiles-resources");
|
uploadR4Profiles(theCtx, client, "profile/profiles-resources");
|
||||||
uploadR4Profiles(theCtx, client, "profiles-types");
|
uploadR4Profiles(theCtx, client, "profile/profiles-types");
|
||||||
uploadR4Profiles(theCtx, client, "profiles-others");
|
uploadR4Profiles(theCtx, client, "profile/profiles-others");
|
||||||
|
uploadR4Profiles(theCtx, client, "extension/extension-definitions");
|
||||||
|
|
||||||
ourLog.info("Finished uploading ValueSets");
|
ourLog.info("Finished uploading ValueSets");
|
||||||
|
|
||||||
|
@ -457,14 +458,14 @@ public class ValidationDataUploader extends BaseCommand {
|
||||||
ourLog.info("Finished uploading definitions to server (took {} ms)", delay);
|
ourLog.info("Finished uploading definitions to server (took {} ms)", delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadDstu3Profiles(FhirContext ctx, IGenericClient client, String name) throws CommandFailureException {
|
private void uploadDstu3Profiles(FhirContext ctx, IGenericClient client, String theName) throws CommandFailureException {
|
||||||
int total;
|
int total;
|
||||||
int count;
|
int count;
|
||||||
org.hl7.fhir.dstu3.model.Bundle bundle;
|
org.hl7.fhir.dstu3.model.Bundle bundle;
|
||||||
ourLog.info("Uploading " + name);
|
ourLog.info("Uploading " + theName);
|
||||||
String vsContents;
|
String vsContents;
|
||||||
try {
|
try {
|
||||||
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/profile/" + name + ".xml"), "UTF-8");
|
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/dstu3/model/" + theName + ".xml"), "UTF-8");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new CommandFailureException(e.toString());
|
throw new CommandFailureException(e.toString());
|
||||||
}
|
}
|
||||||
|
@ -498,26 +499,26 @@ public class ValidationDataUploader extends BaseCommand {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] {name, count, total, next.getIdElement().getValue()});
|
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] {theName, count, total, next.getIdElement().getValue()});
|
||||||
client.update().resource(next).execute();
|
client.update().resource(next).execute();
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadR4Profiles(FhirContext ctx, IGenericClient client, String name) throws CommandFailureException {
|
private void uploadR4Profiles(FhirContext theContext, IGenericClient theClient, String theName) throws CommandFailureException {
|
||||||
int total;
|
int total;
|
||||||
int count;
|
int count;
|
||||||
org.hl7.fhir.r4.model.Bundle bundle;
|
org.hl7.fhir.r4.model.Bundle bundle;
|
||||||
ourLog.info("Uploading " + name);
|
ourLog.info("Uploading " + theName);
|
||||||
String vsContents;
|
String vsContents;
|
||||||
try {
|
try {
|
||||||
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/profile/" + name + ".xml"), "UTF-8");
|
vsContents = IOUtils.toString(ValidationDataUploader.class.getResourceAsStream("/org/hl7/fhir/r4/model/" + theName + ".xml"), "UTF-8");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new CommandFailureException(e.toString());
|
throw new CommandFailureException(e.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
bundle = ctx.newXmlParser().parseResource(org.hl7.fhir.r4.model.Bundle.class, vsContents);
|
bundle = theContext.newXmlParser().parseResource(org.hl7.fhir.r4.model.Bundle.class, vsContents);
|
||||||
filterBundle(bundle);
|
filterBundle(bundle);
|
||||||
total = bundle.getEntry().size();
|
total = bundle.getEntry().size();
|
||||||
count = 1;
|
count = 1;
|
||||||
|
@ -546,9 +547,9 @@ public class ValidationDataUploader extends BaseCommand {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] {name, count, total, next.getIdElement().getValue()});
|
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] {theName, count, total, next.getIdElement().getValue()});
|
||||||
try {
|
try {
|
||||||
client.update().resource(next).execute();
|
theClient.update().resource(next).execute();
|
||||||
} catch (BaseServerResponseException e) {
|
} catch (BaseServerResponseException e) {
|
||||||
ourLog.warn("Server responded HTTP " + e.getStatusCode() + ": " + e.toString());
|
ourLog.warn("Server responded HTTP " + e.getStatusCode() + ": " + e.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -511,6 +511,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected Set<String> extractResourceLinks(ResourceTable theEntity, IBaseResource theResource, Set<ResourceLink> theLinks, Date theUpdateTime) {
|
protected Set<String> extractResourceLinks(ResourceTable theEntity, IBaseResource theResource, Set<ResourceLink> theLinks, Date theUpdateTime) {
|
||||||
HashSet<String> retVal = new HashSet<>();
|
HashSet<String> retVal = new HashSet<>();
|
||||||
|
String resourceType = theEntity.getResourceType();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For now we don't try to load any of the links in a bundle if it's the actual bundle we're storing..
|
* For now we don't try to load any of the links in a bundle if it's the actual bundle we're storing..
|
||||||
|
@ -580,6 +581,9 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao,
|
||||||
}
|
}
|
||||||
} else if (myContext.getElementDefinition((Class<? extends IBase>) nextObject.getClass()).getName().equals("uri")) {
|
} else if (myContext.getElementDefinition((Class<? extends IBase>) nextObject.getClass()).getName().equals("uri")) {
|
||||||
continue;
|
continue;
|
||||||
|
} else if (resourceType.equals("Consent") && nextPathAndRef.getPath().equals("Consent.source")) {
|
||||||
|
// Consent#source-identifier has a path that isn't typed - This is a one-off to deal with that
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (!multiType) {
|
if (!multiType) {
|
||||||
if (nextSpDef.getName().equals("sourceuri")) {
|
if (nextSpDef.getName().equals("sourceuri")) {
|
||||||
|
|
|
@ -105,7 +105,8 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IBaseResource theResource) {
|
public Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IBaseResource theResource) {
|
||||||
HashSet<ResourceIndexedSearchParamDate> retVal = new HashSet<ResourceIndexedSearchParamDate>();
|
HashSet<ResourceIndexedSearchParamDate> retVal = new HashSet<>();
|
||||||
|
String resourceType = theEntity.getResourceType();
|
||||||
|
|
||||||
Collection<RuntimeSearchParam> searchParams = getSearchParams(theResource);
|
Collection<RuntimeSearchParam> searchParams = getSearchParams(theResource);
|
||||||
for (RuntimeSearchParam nextSpDef : searchParams) {
|
for (RuntimeSearchParam nextSpDef : searchParams) {
|
||||||
|
@ -164,6 +165,9 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
||||||
} else if (nextObject instanceof StringType) {
|
} else if (nextObject instanceof StringType) {
|
||||||
// CarePlan.activitydate can be a string
|
// CarePlan.activitydate can be a string
|
||||||
continue;
|
continue;
|
||||||
|
} else if (resourceType.equals("Consent") && nextPath.equals("Consent.source")) {
|
||||||
|
// Consent#source-identifier has a path that isn't typed - This is a one-off to deal with that
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (!multiType) {
|
if (!multiType) {
|
||||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
||||||
|
|
|
@ -20,12 +20,28 @@ package ca.uhn.fhir.jpa.dao.r4;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
||||||
|
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
||||||
import java.util.*;
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
|
import ca.uhn.fhir.jpa.util.DeleteConflict;
|
||||||
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||||
|
import ca.uhn.fhir.validation.FhirValidator;
|
||||||
|
import ca.uhn.fhir.validation.IValidationContext;
|
||||||
|
import ca.uhn.fhir.validation.IValidatorModule;
|
||||||
|
import ca.uhn.fhir.validation.ValidationResult;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.instance.model.api.*;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.IdType;
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
import org.hl7.fhir.r4.model.OperationOutcome;
|
import org.hl7.fhir.r4.model.OperationOutcome;
|
||||||
import org.hl7.fhir.r4.model.OperationOutcome.IssueSeverity;
|
import org.hl7.fhir.r4.model.OperationOutcome.IssueSeverity;
|
||||||
|
@ -33,20 +49,10 @@ import org.hl7.fhir.r4.model.OperationOutcome.OperationOutcomeIssueComponent;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import java.util.ArrayList;
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
import java.util.List;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
|
||||||
import ca.uhn.fhir.jpa.util.DeleteConflict;
|
|
||||||
import ca.uhn.fhir.model.api.Include;
|
|
||||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
|
||||||
import ca.uhn.fhir.rest.api.*;
|
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.*;
|
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
|
||||||
import ca.uhn.fhir.util.FhirTerser;
|
|
||||||
import ca.uhn.fhir.validation.*;
|
|
||||||
|
|
||||||
public class FhirResourceDaoR4<T extends IAnyResource> extends BaseHapiFhirResourceDao<T> {
|
public class FhirResourceDaoR4<T extends IAnyResource> extends BaseHapiFhirResourceDao<T> {
|
||||||
|
|
||||||
|
|
|
@ -468,6 +468,7 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String resourceType = theEntity.getResourceType();
|
||||||
String nextPath = nextSpDef.getPath();
|
String nextPath = nextSpDef.getPath();
|
||||||
if (isBlank(nextPath)) {
|
if (isBlank(nextPath)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -478,8 +479,8 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
|
||||||
multiType = true;
|
multiType = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> systems = new ArrayList<String>();
|
List<String> systems = new ArrayList<>();
|
||||||
List<String> codes = new ArrayList<String>();
|
List<String> codes = new ArrayList<>();
|
||||||
|
|
||||||
for (Object nextObject : extractValues(nextPath, theResource)) {
|
for (Object nextObject : extractValues(nextPath, theResource)) {
|
||||||
|
|
||||||
|
@ -555,9 +556,15 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
|
||||||
} else if (nextObject instanceof LocationPositionComponent) {
|
} else if (nextObject instanceof LocationPositionComponent) {
|
||||||
ourLog.warn("Position search not currently supported, not indexing location");
|
ourLog.warn("Position search not currently supported, not indexing location");
|
||||||
continue;
|
continue;
|
||||||
|
} else if (nextObject instanceof StructureDefinition.StructureDefinitionContextComponent) {
|
||||||
|
ourLog.warn("StructureDefinition context indexing not currently supported"); // TODO: implement this
|
||||||
|
continue;
|
||||||
|
} else if (resourceType.equals("Consent") && nextPath.equals("Consent.source")) {
|
||||||
|
// Consent#source-identifier has a path that isn't typed - This is a one-off to deal with that
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (!multiType) {
|
if (!multiType) {
|
||||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
throw new ConfigurationException("Search param " + nextSpDef.getName() + " with path " + nextPath + " is of unexpected datatype: " + nextObject.getClass());
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,6 +160,9 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
|
||||||
@Qualifier("myOrganizationDaoDstu3")
|
@Qualifier("myOrganizationDaoDstu3")
|
||||||
protected IFhirResourceDao<Organization> myOrganizationDao;
|
protected IFhirResourceDao<Organization> myOrganizationDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@Qualifier("myConsentDaoDstu3")
|
||||||
|
protected IFhirResourceDao<Consent> myConsentDao;
|
||||||
|
@Autowired
|
||||||
protected DatabaseBackedPagingProvider myPagingProvider;
|
protected DatabaseBackedPagingProvider myPagingProvider;
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("myPatientDaoDstu3")
|
@Qualifier("myPatientDaoDstu3")
|
||||||
|
|
|
@ -1,49 +1,53 @@
|
||||||
package ca.uhn.fhir.jpa.dao.dstu3;
|
package ca.uhn.fhir.jpa.dao.dstu3;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
import ca.uhn.fhir.jpa.dao.*;
|
||||||
import static org.hamcrest.Matchers.*;
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
||||||
import static org.junit.Assert.*;
|
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
||||||
import static org.mockito.Matchers.eq;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
import static org.mockito.Mockito.*;
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
|
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
||||||
import java.util.*;
|
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.*;
|
||||||
|
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||||
|
import ca.uhn.fhir.rest.param.*;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.*;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||||
|
import ca.uhn.fhir.util.TestUtil;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.hamcrest.core.StringContains;
|
import org.hamcrest.core.StringContains;
|
||||||
import org.hl7.fhir.dstu3.model.*;
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
import org.hl7.fhir.dstu3.model.Bundle.*;
|
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
||||||
|
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
|
||||||
|
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
|
||||||
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
||||||
import org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus;
|
import org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus;
|
||||||
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
|
import org.hl7.fhir.dstu3.model.Observation.ObservationStatus;
|
||||||
import org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity;
|
import org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity;
|
||||||
import org.hl7.fhir.dstu3.model.OperationOutcome.IssueType;
|
import org.hl7.fhir.dstu3.model.OperationOutcome.IssueType;
|
||||||
import org.hl7.fhir.dstu3.model.Quantity.QuantityComparator;
|
import org.hl7.fhir.dstu3.model.Quantity.QuantityComparator;
|
||||||
import org.hl7.fhir.instance.model.api.*;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import java.util.*;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.*;
|
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
import ca.uhn.fhir.jpa.entity.*;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import static org.hamcrest.Matchers.*;
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
import static org.junit.Assert.*;
|
||||||
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
import static org.mockito.Matchers.eq;
|
||||||
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
|
import static org.mockito.Mockito.*;
|
||||||
import ca.uhn.fhir.rest.api.*;
|
|
||||||
import ca.uhn.fhir.rest.api.Constants;
|
|
||||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
|
||||||
import ca.uhn.fhir.rest.param.*;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.*;
|
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
|
||||||
import ca.uhn.fhir.util.TestUtil;
|
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "deprecation" })
|
@SuppressWarnings({"unchecked", "deprecation"})
|
||||||
public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3Test.class);
|
||||||
|
@ -117,7 +121,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void sortCodings(List<Coding> theSecLabels) {
|
private void sortCodings(List<Coding> theSecLabels) {
|
||||||
Collections.sort(theSecLabels, new Comparator<Coding>() {
|
Collections.sort(theSecLabels, new Comparator<Coding>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -479,7 +482,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateDifferentTypesWithSameForcedId() {
|
public void testCreateDifferentTypesWithSameForcedId() {
|
||||||
String idName = "forcedId";
|
String idName = "forcedId";
|
||||||
|
@ -500,7 +502,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
obs = myObservationDao.read(obsId.toUnqualifiedVersionless(), mySrd);
|
obs = myObservationDao.read(obsId.toUnqualifiedVersionless(), mySrd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateDuplicateTagsDoesNotCauseDuplicates() {
|
public void testCreateDuplicateTagsDoesNotCauseDuplicates() {
|
||||||
Patient p = new Patient();
|
Patient p = new Patient();
|
||||||
|
@ -555,22 +556,22 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
public void testCreateLongString() {
|
public void testCreateLongString() {
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
String input = "<NamingSystem>\n" +
|
String input = "<NamingSystem>\n" +
|
||||||
" <name value=\"NDF-RT (National Drug File – Reference Terminology)\"/>\n" +
|
" <name value=\"NDF-RT (National Drug File – Reference Terminology)\"/>\n" +
|
||||||
" <status value=\"draft\"/>\n" +
|
" <status value=\"draft\"/>\n" +
|
||||||
" <kind value=\"codesystem\"/>\n" +
|
" <kind value=\"codesystem\"/>\n" +
|
||||||
" <publisher value=\"HL7, Inc\"/>\n" +
|
" <publisher value=\"HL7, Inc\"/>\n" +
|
||||||
" <date value=\"2015-08-21\"/>\n" +
|
" <date value=\"2015-08-21\"/>\n" +
|
||||||
" <uniqueId>\n" +
|
" <uniqueId>\n" +
|
||||||
" <type value=\"uri\"/>\n" +
|
" <type value=\"uri\"/>\n" +
|
||||||
" <value value=\"http://hl7.org/fhir/ndfrt\"/>\n" +
|
" <value value=\"http://hl7.org/fhir/ndfrt\"/>\n" +
|
||||||
" <preferred value=\"true\"/>\n" +
|
" <preferred value=\"true\"/>\n" +
|
||||||
" </uniqueId>\n" +
|
" </uniqueId>\n" +
|
||||||
" <uniqueId>\n" +
|
" <uniqueId>\n" +
|
||||||
" <type value=\"oid\"/>\n" +
|
" <type value=\"oid\"/>\n" +
|
||||||
" <value value=\"2.16.840.1.113883.6.209\"/>\n" +
|
" <value value=\"2.16.840.1.113883.6.209\"/>\n" +
|
||||||
" <preferred value=\"false\"/>\n" +
|
" <preferred value=\"false\"/>\n" +
|
||||||
" </uniqueId>\n" +
|
" </uniqueId>\n" +
|
||||||
" </NamingSystem>";
|
" </NamingSystem>";
|
||||||
//@formatter:on
|
//@formatter:on
|
||||||
|
|
||||||
NamingSystem res = myFhirCtx.newXmlParser().parseResource(NamingSystem.class, input);
|
NamingSystem res = myFhirCtx.newXmlParser().parseResource(NamingSystem.class, input);
|
||||||
|
@ -809,7 +810,6 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateWithInvalidReferenceFailsGracefully() {
|
public void testCreateWithInvalidReferenceFailsGracefully() {
|
||||||
Patient patient = new Patient();
|
Patient patient = new Patient();
|
||||||
|
@ -1088,7 +1088,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
patient.addIdentifier().setSystem("ZZZZZZZ").setValue("ZZZZZZZZZ");
|
patient.addIdentifier().setSystem("ZZZZZZZ").setValue("ZZZZZZZZZ");
|
||||||
id2b = myPatientDao.update(patient, mySrd).getId();
|
id2b = myPatientDao.update(patient, mySrd).getId();
|
||||||
}
|
}
|
||||||
ourLog.info("ID1:{} ID2:{} ID2b:{}", new Object[] { id1, id2, id2b });
|
ourLog.info("ID1:{} ID2:{} ID2b:{}", new Object[] {id1, id2, id2b});
|
||||||
|
|
||||||
SearchParameterMap params = new SearchParameterMap();
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
params.setLoadSynchronous(true);
|
params.setLoadSynchronous(true);
|
||||||
|
@ -1697,7 +1697,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
preDates.add(new Date());
|
preDates.add(new Date());
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
patient.setId(id);
|
patient.setId(id);
|
||||||
patient.getName().get(0).getFamilyElement().setValue(methodName + "_i"+i);
|
patient.getName().get(0).getFamilyElement().setValue(methodName + "_i" + i);
|
||||||
ids.add(myPatientDao.update(patient, mySrd).getId().toUnqualified().getValue());
|
ids.add(myPatientDao.update(patient, mySrd).getId().toUnqualified().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2057,7 +2057,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
String inputStr =
|
String inputStr =
|
||||||
"{" +
|
"{" +
|
||||||
" \"resourceType\":\"Organization\",\n" +
|
" \"resourceType\":\"Organization\",\n" +
|
||||||
" \"extension\":[\n" +
|
" \"extension\":[\n" +
|
||||||
" {\n" +
|
" {\n" +
|
||||||
|
@ -2131,7 +2131,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
dr01.setSubject(new Reference(patientId01));
|
dr01.setSubject(new Reference(patientId01));
|
||||||
IIdType drId01 = myDiagnosticReportDao.create(dr01, mySrd).getId();
|
IIdType drId01 = myDiagnosticReportDao.create(dr01, mySrd).getId();
|
||||||
|
|
||||||
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
|
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] {patientId01, patientId02, obsId01, obsId02, drId01});
|
||||||
|
|
||||||
List<Observation> result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam(patientId01.getIdPart())).setLoadSynchronous(true)));
|
List<Observation> result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam(patientId01.getIdPart())).setLoadSynchronous(true)));
|
||||||
assertEquals(1, result.size());
|
assertEquals(1, result.size());
|
||||||
|
@ -2141,7 +2141,8 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
assertEquals(1, result.size());
|
assertEquals(1, result.size());
|
||||||
assertEquals(obsId02.getIdPart(), result.get(0).getIdElement().getIdPart());
|
assertEquals(obsId02.getIdPart(), result.get(0).getIdElement().getIdPart());
|
||||||
|
|
||||||
result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam("999999999999")).setLoadSynchronous(true)));;
|
result = toList(myObservationDao.search(new SearchParameterMap(Observation.SP_SUBJECT, new ReferenceParam("999999999999")).setLoadSynchronous(true)));
|
||||||
|
;
|
||||||
assertEquals(0, result.size());
|
assertEquals(0, result.size());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2224,7 +2225,8 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
long id = outcome.getId().getIdPartAsLong();
|
long id = outcome.getId().getIdPartAsLong();
|
||||||
|
|
||||||
TokenParam value = new TokenParam("urn:system", "001testPersistSearchParams");
|
TokenParam value = new TokenParam("urn:system", "001testPersistSearchParams");
|
||||||
List<Patient> found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_IDENTIFIER, value).setLoadSynchronous(true)));;
|
List<Patient> found = toList(myPatientDao.search(new SearchParameterMap(Patient.SP_IDENTIFIER, value).setLoadSynchronous(true)));
|
||||||
|
;
|
||||||
assertEquals(1, found.size());
|
assertEquals(1, found.size());
|
||||||
assertEquals(id, found.get(0).getIdElement().getIdPartAsLong().longValue());
|
assertEquals(id, found.get(0).getIdElement().getIdPartAsLong().longValue());
|
||||||
|
|
||||||
|
@ -3535,6 +3537,16 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure this can upload successfully (indexer failed at one point)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testUploadConsentWithSourceAttachment() {
|
||||||
|
Consent consent = new Consent();
|
||||||
|
consent.setSource(new Attachment().setUrl("http://foo"));
|
||||||
|
myConsentDao.create(consent);
|
||||||
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
@ -3542,7 +3554,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
||||||
|
|
||||||
public static void assertConflictException(ResourceVersionConflictException e) {
|
public static void assertConflictException(ResourceVersionConflictException e) {
|
||||||
assertThat(e.getMessage(), matchesPattern(
|
assertThat(e.getMessage(), matchesPattern(
|
||||||
"Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource [a-zA-Z]+/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+"));
|
"Unable to delete [a-zA-Z]+/[0-9]+ because at least one resource has a reference to this resource. First reference found was resource [a-zA-Z]+/[0-9]+ in path [a-zA-Z]+.[a-zA-Z]+"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> toStringList(List<UriType> theUriType) {
|
private static List<String> toStringList(List<UriType> theUriType) {
|
||||||
|
|
|
@ -212,6 +212,9 @@ public abstract class BaseJpaR4Test extends BaseJpaTest {
|
||||||
@Qualifier("myStructureDefinitionDaoR4")
|
@Qualifier("myStructureDefinitionDaoR4")
|
||||||
protected IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
|
protected IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@Qualifier("myConsentDaoR4")
|
||||||
|
protected IFhirResourceDao<Consent> myConsentDao;
|
||||||
|
@Autowired
|
||||||
@Qualifier("mySubscriptionDaoR4")
|
@Qualifier("mySubscriptionDaoR4")
|
||||||
protected IFhirResourceDaoSubscription<Subscription> mySubscriptionDao;
|
protected IFhirResourceDaoSubscription<Subscription> mySubscriptionDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -21,6 +21,7 @@ import com.google.common.collect.Lists;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.hamcrest.core.StringContains;
|
import org.hamcrest.core.StringContains;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
@ -3738,6 +3739,26 @@ public class FhirResourceDaoR4Test extends BaseJpaR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure this can upload successfully (indexer failed at one point)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testUploadConsentWithSourceAttachment() {
|
||||||
|
Consent consent = new Consent();
|
||||||
|
consent.setSource(new Attachment().setUrl("http://foo"));
|
||||||
|
myConsentDao.create(consent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure this can upload successfully (indexer failed at one point)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testUploadExtensionStructureDefinition() {
|
||||||
|
StructureDefinition ext = myValidationSupport.fetchStructureDefinition(myFhirCtx, "http://hl7.org/fhir/StructureDefinition/familymemberhistory-type");
|
||||||
|
Validate.notNull(ext);
|
||||||
|
myStructureDefinitionDao.update(ext);
|
||||||
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
|
|
|
@ -86,7 +86,7 @@ public class FhirTesterConfig {
|
||||||
.withName("Health Intersections (DSTU2 FHIR)")
|
.withName("Health Intersections (DSTU2 FHIR)")
|
||||||
.addServer()
|
.addServer()
|
||||||
.withId("spark2")
|
.withId("spark2")
|
||||||
.withFhirVersion(FhirVersionEnum.DSTU2)
|
.withFhirVersion(FhirVersionEnum.DSTU3)
|
||||||
.withBaseUrl("http://vonk.furore.com/")
|
.withBaseUrl("http://vonk.furore.com/")
|
||||||
.withName("Vonk - Furore (STU3 FHIR)");
|
.withName("Vonk - Furore (STU3 FHIR)");
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||||
<level>DEBUG</level>
|
<level>INFO</level>
|
||||||
</filter>
|
</filter>
|
||||||
<file>${fhir.logdir}/fhirtest.log</file>
|
<file>${fhir.logdir}/fhirtest.log</file>
|
||||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
|
|
@ -19,42 +19,62 @@ package ca.uhn.fhir.rest.server;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
import java.lang.reflect.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
import java.util.jar.Manifest;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.UnavailableException;
|
|
||||||
import javax.servlet.http.*;
|
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.ProvidedResourceScanner;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.context.api.AddProfileTagEnum;
|
||||||
|
import ca.uhn.fhir.context.api.BundleInclusionRule;
|
||||||
|
import ca.uhn.fhir.parser.IParser;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Destroy;
|
||||||
|
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Initialize;
|
||||||
|
import ca.uhn.fhir.rest.api.Constants;
|
||||||
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.server.IFhirVersionServer;
|
||||||
|
import ca.uhn.fhir.rest.api.server.IRestfulServer;
|
||||||
|
import ca.uhn.fhir.rest.api.server.ParseAction;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.*;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.server.method.ConformanceMethodBinding;
|
||||||
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.tenant.ITenantIdentificationStrategy;
|
import ca.uhn.fhir.rest.server.tenant.ITenantIdentificationStrategy;
|
||||||
|
import ca.uhn.fhir.util.*;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
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.IBaseResource;
|
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 ca.uhn.fhir.context.*;
|
import javax.servlet.ServletException;
|
||||||
import ca.uhn.fhir.context.api.AddProfileTagEnum;
|
import javax.servlet.UnavailableException;
|
||||||
import ca.uhn.fhir.context.api.BundleInclusionRule;
|
import javax.servlet.http.HttpServlet;
|
||||||
import ca.uhn.fhir.parser.IParser;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import ca.uhn.fhir.rest.annotation.*;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import ca.uhn.fhir.rest.api.*;
|
import java.io.Closeable;
|
||||||
import ca.uhn.fhir.rest.api.server.*;
|
import java.io.IOException;
|
||||||
import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding;
|
import java.io.InputStream;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.*;
|
import java.io.Writer;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.*;
|
import java.lang.annotation.Annotation;
|
||||||
import ca.uhn.fhir.rest.server.method.*;
|
import java.lang.reflect.Method;
|
||||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
import java.lang.reflect.Modifier;
|
||||||
import ca.uhn.fhir.util.*;
|
import java.util.*;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import java.util.jar.Manifest;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
@SuppressWarnings("WeakerAccess")
|
||||||
public class RestfulServer extends HttpServlet implements IRestfulServer<ServletRequestDetails> {
|
public class RestfulServer extends HttpServlet implements IRestfulServer<ServletRequestDetails> {
|
||||||
|
@ -96,7 +116,9 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
private BaseMethodBinding<?> myServerConformanceMethod;
|
private BaseMethodBinding<?> myServerConformanceMethod;
|
||||||
private Object myServerConformanceProvider;
|
private Object myServerConformanceProvider;
|
||||||
private String myServerName = "HAPI FHIR Server";
|
private String myServerName = "HAPI FHIR Server";
|
||||||
/** This is configurable but by default we just use HAPI version */
|
/**
|
||||||
|
* This is configurable but by default we just use HAPI version
|
||||||
|
*/
|
||||||
private String myServerVersion = VersionUtil.getVersion();
|
private String myServerVersion = VersionUtil.getVersion();
|
||||||
private boolean myStarted;
|
private boolean myStarted;
|
||||||
private Map<String, IResourceProvider> myTypeToProvider = new HashMap<>();
|
private Map<String, IResourceProvider> myTypeToProvider = new HashMap<>();
|
||||||
|
@ -121,10 +143,6 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
myFhirContext = theCtx;
|
myFhirContext = theCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean partIsOperation(String nextString) {
|
|
||||||
return nextString.length() > 0 && (nextString.charAt(0) == '_' || nextString.charAt(0) == '$' || nextString.equals(Constants.URL_TOKEN_METADATA));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addContentLocationHeaders(RequestDetails theRequest, HttpServletResponse servletResponse, MethodOutcome response, String resourceName) {
|
private void addContentLocationHeaders(RequestDetails theRequest, HttpServletResponse servletResponse, MethodOutcome response, String resourceName) {
|
||||||
if (response != null && response.getId() != null) {
|
if (response != null && response.getId() != null) {
|
||||||
addLocationHeader(theRequest, servletResponse, response, Constants.HEADER_LOCATION, resourceName);
|
addLocationHeader(theRequest, servletResponse, response, Constants.HEADER_LOCATION, resourceName);
|
||||||
|
@ -140,15 +158,8 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public void addHeadersToResponse(HttpServletResponse theHttpResponse) {
|
public void addHeadersToResponse(HttpServletResponse theHttpResponse) {
|
||||||
StringBuilder b = new StringBuilder();
|
String b = createPoweredByHeader();
|
||||||
b.append("HAPI FHIR ");
|
theHttpResponse.addHeader("X-Powered-By", b);
|
||||||
b.append(VersionUtil.getVersion());
|
|
||||||
b.append(" REST Server (FHIR Server; FHIR ");
|
|
||||||
b.append(myFhirContext.getVersion().getVersion().getFhirVersionString());
|
|
||||||
b.append('/');
|
|
||||||
b.append(myFhirContext.getVersion().getVersion().name());
|
|
||||||
b.append(")");
|
|
||||||
theHttpResponse.addHeader("X-Powered-By", b.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addLocationHeader(RequestDetails theRequest, HttpServletResponse theResponse, MethodOutcome response, String headerLocation, String resourceName) {
|
private void addLocationHeader(RequestDetails theRequest, HttpServletResponse theResponse, MethodOutcome response, String headerLocation, String resourceName) {
|
||||||
|
@ -198,6 +209,33 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected List<String> createPoweredByAttributes() {
|
||||||
|
return Lists.newArrayList("FHIR Server", "FHIR " + myFhirContext.getVersion().getVersion().getFhirVersionString() + "/" + myFhirContext.getVersion().getVersion().name());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String createPoweredByHeader() {
|
||||||
|
StringBuilder b = new StringBuilder();
|
||||||
|
b.append(createPoweredByHeaderProductName());
|
||||||
|
b.append(" ");
|
||||||
|
b.append(VersionUtil.getVersion());
|
||||||
|
b.append(" REST Server (");
|
||||||
|
|
||||||
|
List<String> poweredByAttributes = createPoweredByAttributes();
|
||||||
|
for (ListIterator<String> iter = poweredByAttributes.listIterator(); iter.hasNext(); ) {
|
||||||
|
if (iter.nextIndex() > 0) {
|
||||||
|
b.append("; ");
|
||||||
|
}
|
||||||
|
b.append(iter.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
b.append(")");
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String createPoweredByHeaderProductName() {
|
||||||
|
return "HAPI FHIR";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
if (getResourceProviders() != null) {
|
if (getResourceProviders() != null) {
|
||||||
|
@ -253,6 +291,31 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
return resourceMethod;
|
return resourceMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
handleRequest(RequestTypeEnum.DELETE, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
handleRequest(RequestTypeEnum.GET, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doOptions(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
|
||||||
|
handleRequest(RequestTypeEnum.OPTIONS, theReq, theResp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
handleRequest(RequestTypeEnum.POST, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
handleRequest(RequestTypeEnum.PUT, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count length of URL string, but treating unescaped sequences (e.g. ' ') as their unescaped equivalent (%20)
|
* Count length of URL string, but treating unescaped sequences (e.g. ' ') as their unescaped equivalent (%20)
|
||||||
*/
|
*/
|
||||||
|
@ -356,7 +419,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated As of HAPI FHIR 1.5, this property has been moved to
|
* @deprecated As of HAPI FHIR 1.5, this property has been moved to
|
||||||
* {@link FhirContext#setAddProfileTagWhenEncoding(AddProfileTagEnum)}
|
* {@link FhirContext#setAddProfileTagWhenEncoding(AddProfileTagEnum)}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@ -369,10 +432,9 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
* (which is the default), the server will automatically add a profile tag based on
|
* (which is the default), the server will automatically add a profile tag based on
|
||||||
* the class of the resource(s) being returned.
|
* the class of the resource(s) being returned.
|
||||||
*
|
*
|
||||||
* @param theAddProfileTag
|
* @param theAddProfileTag The behaviour enum (must not be null)
|
||||||
* The behaviour enum (must not be null)
|
|
||||||
* @deprecated As of HAPI FHIR 1.5, this property has been moved to
|
* @deprecated As of HAPI FHIR 1.5, this property has been moved to
|
||||||
* {@link FhirContext#setAddProfileTagWhenEncoding(AddProfileTagEnum)}
|
* {@link FhirContext#setAddProfileTagWhenEncoding(AddProfileTagEnum)}
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@CoverageIgnore
|
@CoverageIgnore
|
||||||
|
@ -389,8 +451,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
/**
|
/**
|
||||||
* Set how bundle factory should decide whether referenced resources should be included in bundles
|
* Set how bundle factory should decide whether referenced resources should be included in bundles
|
||||||
*
|
*
|
||||||
* @param theBundleInclusionRule
|
* @param theBundleInclusionRule - inclusion rule (@see BundleInclusionRule for behaviors)
|
||||||
* - inclusion rule (@see BundleInclusionRule for behaviors)
|
|
||||||
*/
|
*/
|
||||||
public void setBundleInclusionRule(BundleInclusionRule theBundleInclusionRule) {
|
public void setBundleInclusionRule(BundleInclusionRule theBundleInclusionRule) {
|
||||||
myBundleInclusionRule = theBundleInclusionRule;
|
myBundleInclusionRule = theBundleInclusionRule;
|
||||||
|
@ -429,8 +490,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
* Sets (enables/disables) the server support for ETags. Must not be <code>null</code>. Default is
|
* Sets (enables/disables) the server support for ETags. Must not be <code>null</code>. Default is
|
||||||
* {@link #DEFAULT_ETAG_SUPPORT}
|
* {@link #DEFAULT_ETAG_SUPPORT}
|
||||||
*
|
*
|
||||||
* @param theETagSupport
|
* @param theETagSupport The ETag support mode
|
||||||
* The ETag support mode
|
|
||||||
*/
|
*/
|
||||||
public void setETagSupport(ETagSupportEnum theETagSupport) {
|
public void setETagSupport(ETagSupportEnum theETagSupport) {
|
||||||
if (theETagSupport == null) {
|
if (theETagSupport == null) {
|
||||||
|
@ -477,8 +537,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
/**
|
/**
|
||||||
* Sets (or clears) the list of interceptors
|
* Sets (or clears) the list of interceptors
|
||||||
*
|
*
|
||||||
* @param theList
|
* @param theList The list of interceptors (may be null)
|
||||||
* The list of interceptors (may be null)
|
|
||||||
*/
|
*/
|
||||||
public void setInterceptors(IServerInterceptor... theList) {
|
public void setInterceptors(IServerInterceptor... theList) {
|
||||||
myInterceptors.clear();
|
myInterceptors.clear();
|
||||||
|
@ -487,19 +546,6 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets (or clears) the list of interceptors
|
|
||||||
*
|
|
||||||
* @param theList
|
|
||||||
* The list of interceptors (may be null)
|
|
||||||
*/
|
|
||||||
public void setInterceptors(List<IServerInterceptor> theList) {
|
|
||||||
myInterceptors.clear();
|
|
||||||
if (theList != null) {
|
|
||||||
myInterceptors.addAll(theList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPagingProvider getPagingProvider() {
|
public IPagingProvider getPagingProvider() {
|
||||||
return myPagingProvider;
|
return myPagingProvider;
|
||||||
|
@ -533,25 +579,13 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the non-resource specific providers which implement method calls on this server.
|
|
||||||
*
|
|
||||||
* @see #setResourceProviders(Collection)
|
|
||||||
*/
|
|
||||||
public void setPlainProviders(Object... theProv) {
|
|
||||||
setPlainProviders(Arrays.asList(theProv));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows users of RestfulServer to override the getRequestPath method to let them build their custom request path
|
* Allows users of RestfulServer to override the getRequestPath method to let them build their custom request path
|
||||||
* implementation
|
* implementation
|
||||||
*
|
*
|
||||||
* @param requestFullPath
|
* @param requestFullPath the full request path
|
||||||
* the full request path
|
* @param servletContextPath the servelet context path
|
||||||
* @param servletContextPath
|
* @param servletPath the servelet path
|
||||||
* the servelet context path
|
|
||||||
* @param servletPath
|
|
||||||
* the servelet path
|
|
||||||
* @return created resource path
|
* @return created resource path
|
||||||
*/
|
*/
|
||||||
protected String getRequestPath(String requestFullPath, String servletContextPath, String servletPath) {
|
protected String getRequestPath(String requestFullPath, String servletContextPath, String servletPath) {
|
||||||
|
@ -579,16 +613,6 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the resource providers for this server
|
|
||||||
*/
|
|
||||||
public void setResourceProviders(IResourceProvider... theResourceProviders) {
|
|
||||||
myResourceProviders.clear();
|
|
||||||
if (theResourceProviders != null) {
|
|
||||||
myResourceProviders.addAll(Arrays.asList(theResourceProviders));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the server address strategy, which is used to determine what base URL to provide clients to refer to this
|
* Get the server address strategy, which is used to determine what base URL to provide clients to refer to this
|
||||||
* server. Defaults to an instance of {@link IncomingRequestAddressStrategy}
|
* server. Defaults to an instance of {@link IncomingRequestAddressStrategy}
|
||||||
|
@ -608,6 +632,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the server base URL (with no trailing '/') for a given request
|
* Returns the server base URL (with no trailing '/') for a given request
|
||||||
|
*
|
||||||
* @param theRequest
|
* @param theRequest
|
||||||
*/
|
*/
|
||||||
public String getServerBaseForRequest(ServletRequestDetails theRequest) {
|
public String getServerBaseForRequest(ServletRequestDetails theRequest) {
|
||||||
|
@ -656,9 +681,8 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
* </p>
|
* </p>
|
||||||
* Note that this method can only be called before the server is initialized.
|
* Note that this method can only be called before the server is initialized.
|
||||||
*
|
*
|
||||||
* @throws IllegalStateException
|
* @throws IllegalStateException Note that this method can only be called prior to {@link #init() initialization} and will throw an
|
||||||
* Note that this method can only be called prior to {@link #init() initialization} and will throw an
|
* {@link IllegalStateException} if called after that.
|
||||||
* {@link IllegalStateException} if called after that.
|
|
||||||
*/
|
*/
|
||||||
public void setServerConformanceProvider(Object theServerConformanceProvider) {
|
public void setServerConformanceProvider(Object theServerConformanceProvider) {
|
||||||
if (myStarted) {
|
if (myStarted) {
|
||||||
|
@ -670,9 +694,9 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
// passing the server into the constructor. Having that sort
|
// passing the server into the constructor. Having that sort
|
||||||
// of cross linkage causes reference cycles in Spring wiring
|
// of cross linkage causes reference cycles in Spring wiring
|
||||||
try {
|
try {
|
||||||
Method setRestfulServer = theServerConformanceProvider.getClass().getMethod("setRestfulServer", new Class[] { RestfulServer.class });
|
Method setRestfulServer = theServerConformanceProvider.getClass().getMethod("setRestfulServer", new Class[] {RestfulServer.class});
|
||||||
if (setRestfulServer != null) {
|
if (setRestfulServer != null) {
|
||||||
setRestfulServer.invoke(theServerConformanceProvider, new Object[] { this });
|
setRestfulServer.invoke(theServerConformanceProvider, new Object[] {this});
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
ourLog.warn("Error calling IServerConformanceProvider.setRestfulServer", e);
|
ourLog.warn("Error calling IServerConformanceProvider.setRestfulServer", e);
|
||||||
|
@ -680,15 +704,6 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
myServerConformanceProvider = theServerConformanceProvider;
|
myServerConformanceProvider = theServerConformanceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* If provided (default is <code>null</code>), the tenant identification
|
|
||||||
* strategy provides a mechanism for a multitenant server to identify which tenant
|
|
||||||
* a given request corresponds to.
|
|
||||||
*/
|
|
||||||
public void setTenantIdentificationStrategy(ITenantIdentificationStrategy theTenantIdentificationStrategy) {
|
|
||||||
myTenantIdentificationStrategy = theTenantIdentificationStrategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the server's name, as exported in conformance profiles exported by the server. This is informational only,
|
* Gets the server's name, as exported in conformance profiles exported by the server. This is informational only,
|
||||||
* but can be helpful to set with something appropriate.
|
* but can be helpful to set with something appropriate.
|
||||||
|
@ -1029,10 +1044,9 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
* This method may be overridden by subclasses to do perform initialization that needs to be performed prior to the
|
* This method may be overridden by subclasses to do perform initialization that needs to be performed prior to the
|
||||||
* server being used.
|
* server being used.
|
||||||
*
|
*
|
||||||
* @throws ServletException
|
* @throws ServletException If the initialization failed. Note that you should consider throwing {@link UnavailableException}
|
||||||
* If the initialization failed. Note that you should consider throwing {@link UnavailableException}
|
* (which extends {@link ServletException}), as this is a flag to the servlet container
|
||||||
* (which extends {@link ServletException}), as this is a flag to the servlet container
|
* that the servlet is not usable.
|
||||||
* that the servlet is not usable.
|
|
||||||
*/
|
*/
|
||||||
protected void initialize() throws ServletException {
|
protected void initialize() throws ServletException {
|
||||||
// nothing by default
|
// nothing by default
|
||||||
|
@ -1056,6 +1070,24 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void invokeInitialize(Object theProvider) {
|
||||||
|
invokeInitialize(theProvider, theProvider.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void invokeInitialize(Object theProvider, Class<?> clazz) {
|
||||||
|
for (Method m : ReflectionUtil.getDeclaredMethods(clazz)) {
|
||||||
|
Initialize initialize = m.getAnnotation(Initialize.class);
|
||||||
|
if (initialize != null) {
|
||||||
|
invokeInitializeOrDestroyMethod(theProvider, m, "initialize");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> supertype = clazz.getSuperclass();
|
||||||
|
if (!Object.class.equals(supertype)) {
|
||||||
|
invokeInitialize(theProvider, supertype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void invokeInitializeOrDestroyMethod(Object theProvider, Method m, String theMethodDescription) {
|
private void invokeInitializeOrDestroyMethod(Object theProvider, Method m, String theMethodDescription) {
|
||||||
|
|
||||||
Class<?>[] paramTypes = m.getParameterTypes();
|
Class<?>[] paramTypes = m.getParameterTypes();
|
||||||
|
@ -1078,24 +1110,6 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void invokeInitialize(Object theProvider) {
|
|
||||||
invokeInitialize(theProvider, theProvider.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void invokeInitialize(Object theProvider, Class<?> clazz) {
|
|
||||||
for (Method m : ReflectionUtil.getDeclaredMethods(clazz)) {
|
|
||||||
Initialize initialize = m.getAnnotation(Initialize.class);
|
|
||||||
if (initialize != null) {
|
|
||||||
invokeInitializeOrDestroyMethod(theProvider, m, "initialize");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Class<?> supertype = clazz.getSuperclass();
|
|
||||||
if (!Object.class.equals(supertype)) {
|
|
||||||
invokeInitialize(theProvider, supertype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should the server "pretty print" responses by default (requesting clients can always override this default by
|
* Should the server "pretty print" responses by default (requesting clients can always override this default by
|
||||||
* supplying an <code>Accept</code> header in the request, or a <code>_pretty</code>
|
* supplying an <code>Accept</code> header in the request, or a <code>_pretty</code>
|
||||||
|
@ -1119,8 +1133,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
* The default is <code>false</code>
|
* The default is <code>false</code>
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param theDefaultPrettyPrint
|
* @param theDefaultPrettyPrint The default pretty print setting
|
||||||
* The default pretty print setting
|
|
||||||
*/
|
*/
|
||||||
public void setDefaultPrettyPrint(boolean theDefaultPrettyPrint) {
|
public void setDefaultPrettyPrint(boolean theDefaultPrettyPrint) {
|
||||||
myDefaultPrettyPrint = theDefaultPrettyPrint;
|
myDefaultPrettyPrint = theDefaultPrettyPrint;
|
||||||
|
@ -1174,8 +1187,8 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated This feature did not work well, and will be removed. Use {@link ResponseHighlighterInterceptor}
|
* @deprecated This feature did not work well, and will be removed. Use {@link ResponseHighlighterInterceptor}
|
||||||
* instead as an interceptor on your server and it will provide more useful syntax
|
* instead as an interceptor on your server and it will provide more useful syntax
|
||||||
* highlighting. Deprocated in 1.4
|
* highlighting. Deprocated in 1.4
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
|
@ -1185,8 +1198,8 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated This feature did not work well, and will be removed. Use {@link ResponseHighlighterInterceptor}
|
* @deprecated This feature did not work well, and will be removed. Use {@link ResponseHighlighterInterceptor}
|
||||||
* instead as an interceptor on your server and it will provide more useful syntax
|
* instead as an interceptor on your server and it will provide more useful syntax
|
||||||
* highlighting. Deprocated in 1.4
|
* highlighting. Deprocated in 1.4
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void setUseBrowserFriendlyContentTypes(boolean theUseBrowserFriendlyContentTypes) {
|
public void setUseBrowserFriendlyContentTypes(boolean theUseBrowserFriendlyContentTypes) {
|
||||||
|
@ -1285,8 +1298,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
/**
|
/**
|
||||||
* Register a group of providers. These could be Resource Providers, "plain" providers or a mixture of the two.
|
* Register a group of providers. These could be Resource Providers, "plain" providers or a mixture of the two.
|
||||||
*
|
*
|
||||||
* @param providers
|
* @param providers a {@code Collection} of providers. The parameter could be null or an empty {@code Collection}
|
||||||
* a {@code Collection} of providers. The parameter could be null or an empty {@code Collection}
|
|
||||||
*/
|
*/
|
||||||
public void registerProviders(Collection<? extends Object> providers) {
|
public void registerProviders(Collection<? extends Object> providers) {
|
||||||
myProviderRegistrationMutex.lock();
|
myProviderRegistrationMutex.lock();
|
||||||
|
@ -1327,7 +1339,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
String resourceName = getFhirContext().getResourceDefinition(resourceType).getName();
|
String resourceName = getFhirContext().getResourceDefinition(resourceType).getName();
|
||||||
if (myTypeToProvider.containsKey(resourceName)) {
|
if (myTypeToProvider.containsKey(resourceName)) {
|
||||||
throw new ConfigurationException("Multiple resource providers return resource type[" + resourceName + "]: First[" + myTypeToProvider.get(resourceName).getClass().getCanonicalName()
|
throw new ConfigurationException("Multiple resource providers return resource type[" + resourceName + "]: First[" + myTypeToProvider.get(resourceName).getClass().getCanonicalName()
|
||||||
+ "] and Second[" + rsrcProvider.getClass().getCanonicalName() + "]");
|
+ "] and Second[" + rsrcProvider.getClass().getCanonicalName() + "]");
|
||||||
}
|
}
|
||||||
if (!inInit) {
|
if (!inInit) {
|
||||||
myResourceProviders.add(rsrcProvider);
|
myResourceProviders.add(rsrcProvider);
|
||||||
|
@ -1376,7 +1388,7 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
/*
|
/*
|
||||||
* Remove registered RESTful methods for a Provider (and all superclasses) when it is being unregistered
|
* Remove registered RESTful methods for a Provider (and all superclasses) when it is being unregistered
|
||||||
*/
|
*/
|
||||||
private void removeResourceMethods(Object theProvider) throws Exception {
|
private void removeResourceMethods(Object theProvider) {
|
||||||
ourLog.info("Removing RESTful methods for: {}", theProvider.getClass());
|
ourLog.info("Removing RESTful methods for: {}", theProvider.getClass());
|
||||||
Class<?> clazz = theProvider.getClass();
|
Class<?> clazz = theProvider.getClass();
|
||||||
Class<?> supertype = clazz.getSuperclass();
|
Class<?> supertype = clazz.getSuperclass();
|
||||||
|
@ -1447,50 +1459,46 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case DELETE:
|
case DELETE:
|
||||||
doDelete(theReq, theResp);
|
doDelete(theReq, theResp);
|
||||||
break;
|
break;
|
||||||
case GET:
|
case GET:
|
||||||
doGet(theReq, theResp);
|
doGet(theReq, theResp);
|
||||||
break;
|
break;
|
||||||
case OPTIONS:
|
case OPTIONS:
|
||||||
doOptions(theReq, theResp);
|
doOptions(theReq, theResp);
|
||||||
break;
|
break;
|
||||||
case POST:
|
case POST:
|
||||||
doPost(theReq, theResp);
|
doPost(theReq, theResp);
|
||||||
break;
|
break;
|
||||||
case PUT:
|
case PUT:
|
||||||
doPut(theReq, theResp);
|
doPut(theReq, theResp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
handleRequest(method, theReq, theResp);
|
handleRequest(method, theReq, theResp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
* Sets (or clears) the list of interceptors
|
||||||
handleRequest(RequestTypeEnum.DELETE, request, response);
|
*
|
||||||
|
* @param theList The list of interceptors (may be null)
|
||||||
|
*/
|
||||||
|
public void setInterceptors(List<IServerInterceptor> theList) {
|
||||||
|
myInterceptors.clear();
|
||||||
|
if (theList != null) {
|
||||||
|
myInterceptors.addAll(theList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
* Sets the non-resource specific providers which implement method calls on this server.
|
||||||
handleRequest(RequestTypeEnum.GET, request, response);
|
*
|
||||||
}
|
* @see #setResourceProviders(Collection)
|
||||||
|
*/
|
||||||
@Override
|
public void setPlainProviders(Object... theProv) {
|
||||||
protected void doOptions(HttpServletRequest theReq, HttpServletResponse theResp) throws ServletException, IOException {
|
setPlainProviders(Arrays.asList(theProv));
|
||||||
handleRequest(RequestTypeEnum.OPTIONS, theReq, theResp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
handleRequest(RequestTypeEnum.POST, request, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
handleRequest(RequestTypeEnum.PUT, request, response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1505,6 +1513,25 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the resource providers for this server
|
||||||
|
*/
|
||||||
|
public void setResourceProviders(IResourceProvider... theResourceProviders) {
|
||||||
|
myResourceProviders.clear();
|
||||||
|
if (theResourceProviders != null) {
|
||||||
|
myResourceProviders.addAll(Arrays.asList(theResourceProviders));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If provided (default is <code>null</code>), the tenant identification
|
||||||
|
* strategy provides a mechanism for a multitenant server to identify which tenant
|
||||||
|
* a given request corresponds to.
|
||||||
|
*/
|
||||||
|
public void setTenantIdentificationStrategy(ITenantIdentificationStrategy theTenantIdentificationStrategy) {
|
||||||
|
myTenantIdentificationStrategy = theTenantIdentificationStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
public void unregisterInterceptor(IServerInterceptor theInterceptor) {
|
public void unregisterInterceptor(IServerInterceptor theInterceptor) {
|
||||||
Validate.notNull(theInterceptor, "Interceptor can not be null");
|
Validate.notNull(theInterceptor, "Interceptor can not be null");
|
||||||
myInterceptors.remove(theInterceptor);
|
myInterceptors.remove(theInterceptor);
|
||||||
|
@ -1567,6 +1594,10 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
||||||
theResponse.getWriter().write(theException.getMessage());
|
theResponse.getWriter().write(theException.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean partIsOperation(String nextString) {
|
||||||
|
return nextString.length() > 0 && (nextString.charAt(0) == '_' || nextString.charAt(0) == '$' || nextString.equals(Constants.URL_TOKEN_METADATA));
|
||||||
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Returns the read method binding for the given resource type, or
|
// * Returns the read method binding for the given resource type, or
|
||||||
// * returns <code>null</code> if not
|
// * returns <code>null</code> if not
|
||||||
|
|
|
@ -228,6 +228,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
|
||||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/profile/profiles-resources.xml");
|
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/profile/profiles-resources.xml");
|
||||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/profile/profiles-types.xml");
|
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/profile/profiles-types.xml");
|
||||||
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/profile/profiles-others.xml");
|
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/profile/profiles-others.xml");
|
||||||
|
loadStructureDefinitions(theContext, structureDefinitions, "/org/hl7/fhir/r4/model/extension/extension-definitions.xml");
|
||||||
|
|
||||||
myStructureDefinitions = structureDefinitions;
|
myStructureDefinitions = structureDefinitions;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -38,6 +38,7 @@ import org.mockito.stubbing.Answer;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.*;
|
import static org.hamcrest.Matchers.*;
|
||||||
|
@ -411,11 +412,8 @@ public class FhirInstanceValidatorR4Test {
|
||||||
ourLog.info("Took {} ms -- {}ms / pass", delay, per);
|
ourLog.info("Took {} ms -- {}ms / pass", delay, per);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* // TODO: reenable
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void testValidateBuiltInProfiles() throws Exception {
|
public void testValidateBuiltInProfiles() throws Exception {
|
||||||
org.hl7.fhir.r4.model.Bundle bundle;
|
org.hl7.fhir.r4.model.Bundle bundle;
|
||||||
String name = "profiles-resources";
|
String name = "profiles-resources";
|
||||||
|
@ -442,16 +440,23 @@ public class FhirInstanceValidatorR4Test {
|
||||||
ourLog.trace(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(next));
|
ourLog.trace(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(next));
|
||||||
|
|
||||||
ValidationResult output = myVal.validateWithResult(next);
|
ValidationResult output = myVal.validateWithResult(next);
|
||||||
List<SingleValidationMessage> errors = logResultsAndReturnNonInformationalOnes(output);
|
List<SingleValidationMessage> results = logResultsAndReturnAll(output);
|
||||||
|
|
||||||
// This isn't a validator problem but a definition problem.. it should get fixed at some point and
|
// This isn't a validator problem but a definition problem.. it should get fixed at some point and
|
||||||
// we can remove this
|
// we can remove this. Tracker #17207 was filed about this
|
||||||
if (next.getId().equalsIgnoreCase("http://hl7.org/fhir/OperationDefinition/StructureDefinition-generate")) {
|
// https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=17207
|
||||||
assertEquals(1, errors.size());
|
if (next.getId().equalsIgnoreCase("http://hl7.org/fhir/OperationDefinition/StructureDefinition-snapshot")) {
|
||||||
assertEquals("A search type can only be specified for parameters of type string [searchType implies type = 'string']", errors.get(0).getMessage());
|
assertEquals(1, results.size());
|
||||||
|
assertEquals("A search type can only be specified for parameters of type string [searchType.exists() implies type = 'string']", results.get(0).getMessage());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
List<SingleValidationMessage> errors = results
|
||||||
|
.stream()
|
||||||
|
.filter(t -> t.getSeverity() != ResultSeverityEnum.INFORMATION)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
assertThat("Failed to validate " + i.getFullUrl() + " - " + errors, errors, empty());
|
assertThat("Failed to validate " + i.getFullUrl() + " - " + errors, errors, empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,34 +185,52 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.karaf.tooling</groupId>
|
|
||||||
<artifactId>karaf-maven-plugin</artifactId>
|
|
||||||
<version>${apache_karaf_version}</version>
|
|
||||||
<configuration>
|
|
||||||
<descriptors>
|
|
||||||
<descriptor>file://${project.build.directory}/classes/${features.file}</descriptor>
|
|
||||||
<descriptor>mvn:org.apache.karaf.features/enterprise/${apache_karaf_version}/xml/features</descriptor>
|
|
||||||
</descriptors>
|
|
||||||
<distribution>org.apache.karaf.features:framework</distribution>
|
|
||||||
<javase>1.8</javase>
|
|
||||||
<framework>
|
|
||||||
<feature>framework</feature>
|
|
||||||
</framework>
|
|
||||||
<features>
|
|
||||||
<feature>hapi-fhir*</feature>
|
|
||||||
</features>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>validate</id>
|
|
||||||
<phase>process-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>verify</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The karaf verification step doesn't happen by default
|
||||||
|
because it doesn't seem to work on Windows.
|
||||||
|
|
||||||
|
See https://github.com/jamesagnew/hapi-fhir/issues/921
|
||||||
|
-->
|
||||||
|
<profile>
|
||||||
|
<id>DIST</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.karaf.tooling</groupId>
|
||||||
|
<artifactId>karaf-maven-plugin</artifactId>
|
||||||
|
<version>${apache_karaf_version}</version>
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>file://${project.build.directory}/classes/${features.file}</descriptor>
|
||||||
|
<descriptor>mvn:org.apache.karaf.features/enterprise/${apache_karaf_version}/xml/features</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
<distribution>org.apache.karaf.features:framework</distribution>
|
||||||
|
<javase>1.8</javase>
|
||||||
|
<framework>
|
||||||
|
<feature>framework</feature>
|
||||||
|
</framework>
|
||||||
|
<features>
|
||||||
|
<feature>hapi-fhir*</feature>
|
||||||
|
</features>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>validate</id>
|
||||||
|
<phase>process-resources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>verify</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -172,6 +172,18 @@
|
||||||
invocation at the type level as being at the instance level if the method
|
invocation at the type level as being at the instance level if the method
|
||||||
indicated that the IdParam parameter was optional. This has been fixed.
|
indicated that the IdParam parameter was optional. This has been fixed.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
StructureDefinitions for the FHIR standard extensions have been added to the
|
||||||
|
hapi-fhir-validation-resources-XXXX modules. Thanks to Patrick Werner for the
|
||||||
|
pull request! These have also been added to the list of definitions uploaded
|
||||||
|
by the CLI "upload-definitions" command.
|
||||||
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
A workaround for an invalid search parameter path in the R4 consent
|
||||||
|
resource has been implemented. This path was preventing some Consent
|
||||||
|
resources from successfully being uploaded to the JPA server. Thanks to
|
||||||
|
Anthony Sute for identifying this.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.3.0" date="2018-03-29">
|
<release version="3.3.0" date="2018-03-29">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
|
@ -60,3 +60,4 @@ cp ~/workspace/fhir/trunk/build/publish/profiles-*.xml hapi-fhir-validatio
|
||||||
cp ~/workspace/fhir/trunk/build/publish/v2-tables.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/
|
cp ~/workspace/fhir/trunk/build/publish/v2-tables.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/
|
||||||
cp ~/workspace/fhir/trunk/build/publish/v3-codesystems.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/
|
cp ~/workspace/fhir/trunk/build/publish/v3-codesystems.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/
|
||||||
cp ~/workspace/fhir/trunk/build/publish/valuesets.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/
|
cp ~/workspace/fhir/trunk/build/publish/valuesets.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/valueset/
|
||||||
|
cp ~/workspace/fhir/trunk/build/publish/extension-definitions.xml hapi-fhir-validation-resources-r4/src/main/resources/org/hl7/fhir/r4/model/extension/
|
||||||
|
|
Loading…
Reference in New Issue