- add TLS support for JaxRsClient and OkHttpClient
- add tests
This commit is contained in:
parent
5388f729fb
commit
25d8a0f5e1
|
@ -911,6 +911,7 @@ public class FhirContext {
|
|||
* </p>
|
||||
*
|
||||
* @param theServerBase The URL of the base for the restful FHIR server to connect to
|
||||
* @param theTlsAuthentication Optional configuration to authenticate HTTPS server requests
|
||||
*/
|
||||
public IGenericClient newRestfulGenericClient(final String theServerBase, final Optional<TlsAuthentication> theTlsAuthentication) {
|
||||
return getRestfulClientFactory().newGenericClient(theServerBase, theTlsAuthentication);
|
||||
|
|
|
@ -94,6 +94,24 @@ public interface IRestfulClientFactory {
|
|||
*/
|
||||
IHttpClient getHttpClient(StringBuilder theUrl, Map<String, List<String>> theIfNoneExistParams, String theIfNoneExistString, RequestTypeEnum theRequestType, List<Header> theHeaders);
|
||||
|
||||
/**
|
||||
* Returns the HTTP client instance. This method will not return null.
|
||||
* @param theUrl
|
||||
* The complete FHIR url to which the http request will be sent
|
||||
* @param theTlsAuthentication
|
||||
* Optional configuration to authenticate HTTPS server requests
|
||||
* @param theIfNoneExistParams
|
||||
* The params for header "If-None-Exist" as a hashmap
|
||||
* @param theIfNoneExistString
|
||||
* The param for header "If-None-Exist" as a string
|
||||
* @param theRequestType
|
||||
* the type of HTTP request (GET, DELETE, ..)
|
||||
* @param theHeaders
|
||||
* the headers to be sent together with the http request
|
||||
* @return the HTTP client instance
|
||||
*/
|
||||
IHttpClient getHttpClient(StringBuilder theUrl, Optional<TlsAuthentication> theTlsAuthentication, Map<String, List<String>> theIfNoneExistParams, String theIfNoneExistString, RequestTypeEnum theRequestType, List<Header> theHeaders);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getServerValidationMode()} instead (this method is a synonym for that method, but this method is poorly named and will be removed at some point)
|
||||
*/
|
||||
|
@ -164,6 +182,8 @@ public interface IRestfulClientFactory {
|
|||
*
|
||||
* @param theServerBase
|
||||
* The URL of the base for the restful FHIR server to connect to
|
||||
* @param
|
||||
* theTlsAuthentication Optional configuration to authenticate HTTPS server requests
|
||||
* @return A newly created client
|
||||
*/
|
||||
IGenericClient newGenericClient(String theServerBase, Optional<TlsAuthentication> theTlsAuthentication);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package ca.uhn.fhir.rest.https;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.http.ssl.PrivateKeyStrategy;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
|
@ -18,6 +17,7 @@ public class KeyStoreInfo {
|
|||
myStorePass = toCharArrayOrNull(theStorePass);
|
||||
myKeyPass = toCharArrayOrNull(theKeyPass);
|
||||
myAlias = theAlias;
|
||||
|
||||
String extension = FilenameUtils.getExtension(myFilePath);
|
||||
myType = KeyStoreType.fromFileExtension(extension);
|
||||
}
|
||||
|
@ -39,8 +39,7 @@ public class KeyStoreInfo {
|
|||
}
|
||||
|
||||
public KeyStoreType getType(){
|
||||
String extension = FilenameUtils.getExtension(myFilePath);
|
||||
return KeyStoreType.fromFileExtension(extension);
|
||||
return myType;
|
||||
}
|
||||
|
||||
private char[] toCharArrayOrNull(String theString){
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package ca.uhn.fhir.rest.https;
|
||||
|
||||
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.ssl.PrivateKeyStrategy;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
public class TlsAuthenticationSvc {
|
||||
|
||||
private TlsAuthenticationSvc(){}
|
||||
|
||||
public static Optional<SSLContext> createSslContext(Optional<TlsAuthentication> theTlsAuthentication){
|
||||
if(theTlsAuthentication.isEmpty()){
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
try{
|
||||
SSLContextBuilder contextBuilder = SSLContexts.custom();
|
||||
|
||||
TlsAuthentication tlsAuth = theTlsAuthentication.get();
|
||||
if(tlsAuth.getKeyStoreInfo().isPresent()){
|
||||
KeyStoreInfo keyStoreInfo = tlsAuth.getKeyStoreInfo().get();
|
||||
PrivateKeyStrategy privateKeyStrategy = null;
|
||||
if(isNotBlank(keyStoreInfo.getAlias())){
|
||||
privateKeyStrategy = (aliases, socket) -> keyStoreInfo.getAlias();
|
||||
}
|
||||
contextBuilder.loadKeyMaterial(new File(keyStoreInfo.getFilePath()), keyStoreInfo.getStorePass(), keyStoreInfo.getKeyPass(), privateKeyStrategy);
|
||||
}
|
||||
|
||||
if(tlsAuth.getTrustStoreInfo().isPresent()){
|
||||
TrustStoreInfo trustStoreInfo = tlsAuth.getTrustStoreInfo().get();
|
||||
contextBuilder.loadTrustMaterial(new File(trustStoreInfo.getFilePath()), trustStoreInfo.getStorePass(), TrustSelfSignedStrategy.INSTANCE);
|
||||
}
|
||||
|
||||
return Optional.of(contextBuilder.build());
|
||||
}
|
||||
catch (Exception e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static X509TrustManager createTrustManager(Optional<TrustStoreInfo> theTrustStoreInfo) {
|
||||
try {
|
||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
||||
if (theTrustStoreInfo.isEmpty()) {
|
||||
trustManagerFactory.init((KeyStore) null); // Load Trust Manager Factory with default Java truststore
|
||||
} else {
|
||||
TrustStoreInfo trustStoreInfo = theTrustStoreInfo.get();
|
||||
KeyStore trustStore = KeyStore.getInstance(trustStoreInfo.getType().toString());
|
||||
trustStore.load(new FileInputStream(trustStoreInfo.getFilePath()), trustStoreInfo.getStorePass());
|
||||
trustManagerFactory.init(trustStore);
|
||||
}
|
||||
for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) {
|
||||
if (trustManager instanceof X509TrustManager) {
|
||||
return (X509TrustManager) trustManager;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Could not find Trust Manager");
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static HostnameVerifier createHostnameVerifier(Optional<TrustStoreInfo> theTrustStoreInfo){
|
||||
return theTrustStoreInfo.isPresent() ? new DefaultHostnameVerifier() : new NoopHostnameVerifier();
|
||||
}
|
||||
}
|
|
@ -9,10 +9,13 @@ public class TrustStoreInfo {
|
|||
private final String myFilePath;
|
||||
private final char[] myStorePass;
|
||||
private final KeyStoreType myType;
|
||||
private final String myAlias;
|
||||
|
||||
public TrustStoreInfo(String theFilePath, String theStorePass) {
|
||||
public TrustStoreInfo(String theFilePath, String theStorePass, String theAlias) {
|
||||
myFilePath = theFilePath;
|
||||
myStorePass = toCharArrayOrNull(theStorePass);
|
||||
myAlias = theAlias;
|
||||
|
||||
String extension = FilenameUtils.getExtension(myFilePath);
|
||||
myType = KeyStoreType.fromFileExtension(extension);
|
||||
}
|
||||
|
@ -26,11 +29,14 @@ public class TrustStoreInfo {
|
|||
}
|
||||
|
||||
public KeyStoreType getType(){
|
||||
String extension = FilenameUtils.getExtension(myFilePath);
|
||||
return KeyStoreType.fromFileExtension(extension);
|
||||
return myType;
|
||||
}
|
||||
|
||||
private char[] toCharArrayOrNull(String theString){
|
||||
return isBlank(theString) ? null : theString.toCharArray();
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
return myAlias;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||
protected static final String BASE_URL_PARAM_DESC = "Base URL for the target server (e.g. \"http://example.com/fhir\").";
|
||||
protected static final String TLS_AUTH_PARAM_LONGOPT = "tls-auth";
|
||||
protected static final String TLS_AUTH_PARAM_NAME = "tls-auth";
|
||||
protected static final String TLS_AUTH_PARAM_DESC = "If specified, this parameter supplies a path and filename for a json authentication file that will be used to authenticate https requests.";
|
||||
protected static final String TLS_AUTH_PARAM_DESC = "If specified, this parameter supplies a path and filename for a json authentication file that will be used to authenticate HTTPS requests.";
|
||||
protected static final String BASIC_AUTH_PARAM = "b";
|
||||
protected static final String BASIC_AUTH_PARAM_LONGOPT = "basic-auth";
|
||||
protected static final String BASIC_AUTH_PARAM_NAME = "basic-auth";
|
||||
|
@ -475,7 +475,7 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||
}
|
||||
|
||||
protected IGenericClient newClient(CommandLine theCommandLine, String theBaseUrlParamName, String theBasicAuthOptionName,
|
||||
String theBearerTokenOptionName, String theHttpsAuthOptionName) throws ParseException {
|
||||
String theBearerTokenOptionName, String theTlsAuthOptionName) throws ParseException {
|
||||
String baseUrl = theCommandLine.getOptionValue(theBaseUrlParamName);
|
||||
if (isBlank(baseUrl)) {
|
||||
throw new ParseException(Msg.code(1579) + "No target server (-" + BASE_URL_PARAM + ") specified.");
|
||||
|
@ -483,15 +483,15 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||
throw new ParseException(Msg.code(1580) + "Invalid target server specified, must begin with 'http' or 'file'.");
|
||||
}
|
||||
|
||||
return newClientWithBaseUrl(theCommandLine, baseUrl, theBasicAuthOptionName, theBearerTokenOptionName, theHttpsAuthOptionName);
|
||||
return newClientWithBaseUrl(theCommandLine, baseUrl, theBasicAuthOptionName, theBearerTokenOptionName, theTlsAuthOptionName);
|
||||
}
|
||||
|
||||
protected IGenericClient newClientWithBaseUrl(CommandLine theCommandLine, String theBaseUrl, String theBasicAuthOptionName,
|
||||
String theBearerTokenOptionName, String theHttpsAuthOptionName) throws ParseException {
|
||||
String theBearerTokenOptionName, String theTlsAuthOptionName) throws ParseException {
|
||||
myFhirCtx.getRestfulClientFactory().setSocketTimeout((int) DateUtils.MILLIS_PER_HOUR);
|
||||
|
||||
|
||||
Optional<TlsAuthentication> tlsConfig = createTlsConfig(theCommandLine, theHttpsAuthOptionName);
|
||||
Optional<TlsAuthentication> tlsConfig = createTlsConfig(theCommandLine, theTlsAuthOptionName);
|
||||
IGenericClient retVal = myFhirCtx.newRestfulGenericClient(theBaseUrl, tlsConfig);
|
||||
|
||||
String basicAuthHeaderValue = getAndParseOptionBasicAuthHeader(theCommandLine, theBasicAuthOptionName);
|
||||
|
@ -509,8 +509,8 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private Optional<TlsAuthentication> createTlsConfig(CommandLine theCommandLine, String theHttpsAuthOptionName){
|
||||
String httpAuthFilePath = theCommandLine.getOptionValue(theHttpsAuthOptionName);
|
||||
private Optional<TlsAuthentication> createTlsConfig(CommandLine theCommandLine, String theTlsAuthOptionName){
|
||||
String httpAuthFilePath = theCommandLine.getOptionValue(theTlsAuthOptionName);
|
||||
if(isBlank(httpAuthFilePath)){
|
||||
return Optional.empty();
|
||||
}
|
||||
|
@ -529,28 +529,39 @@ public abstract class BaseCommand implements Comparable<BaseCommand> {
|
|||
}
|
||||
}
|
||||
|
||||
private Optional<KeyStoreInfo> createKeyStoreInfo(JsonObject theJson){
|
||||
private Optional<KeyStoreInfo> createKeyStoreInfo(JsonObject theJson) throws ParseException {
|
||||
String filePath = theJson.get("filePath").getAsString();
|
||||
if(isBlank(filePath)){
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String storePass = theJson.get("storePass").getAsString();
|
||||
if (PROMPT.equals(storePass)) {
|
||||
storePass = trim(promptUser("Enter the store password for the keystore: "));
|
||||
}
|
||||
String keyPass = theJson.get("keyPass").getAsString();
|
||||
if (PROMPT.equals(keyPass)) {
|
||||
keyPass = trim(promptUser("Enter the key password for the keystore: "));
|
||||
}
|
||||
String alias = theJson.get("alias").getAsString();
|
||||
|
||||
KeyStoreInfo keyStoreInfo = new KeyStoreInfo(filePath, storePass, keyPass, alias);
|
||||
return Optional.of(keyStoreInfo);
|
||||
}
|
||||
|
||||
private Optional<TrustStoreInfo> createTrustStoreInfo(JsonObject theJson){
|
||||
private Optional<TrustStoreInfo> createTrustStoreInfo(JsonObject theJson) throws ParseException {
|
||||
String filePath = theJson.get("filePath").getAsString();
|
||||
if(isBlank(filePath)){
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String storePass = theJson.get("storePass").getAsString();
|
||||
TrustStoreInfo trustStoreInfo = new TrustStoreInfo(filePath, storePass);
|
||||
if (PROMPT.equals(storePass)) {
|
||||
storePass = trim(promptUser("Enter the store password for the truststore: "));
|
||||
}
|
||||
|
||||
String alias = theJson.get("alias").getAsString();
|
||||
TrustStoreInfo trustStoreInfo = new TrustStoreInfo(filePath, storePass, alias);
|
||||
return Optional.of(trustStoreInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -94,9 +94,10 @@ public abstract class BaseRequestGeneratingCommand extends BaseCommand {
|
|||
|
||||
@Override
|
||||
protected IGenericClient newClientWithBaseUrl(CommandLine theCommandLine, String theBaseUrl,
|
||||
String theBasicAuthOptionName, String theBearerTokenOptionName, String theHttpsAuthOptionName) throws ParseException {
|
||||
String theBasicAuthOptionName, String theBearerTokenOptionName, String theTlsAuthOptionName) throws ParseException {
|
||||
|
||||
IGenericClient client = super.newClientWithBaseUrl(theCommandLine, theBaseUrl, theBasicAuthOptionName, theBearerTokenOptionName, theHttpsAuthOptionName);
|
||||
IGenericClient client = super.newClientWithBaseUrl(
|
||||
theCommandLine, theBaseUrl, theBasicAuthOptionName, theBearerTokenOptionName, theTlsAuthOptionName);
|
||||
registerHeaderPassthrough(theCommandLine, client);
|
||||
|
||||
return client;
|
||||
|
|
|
@ -46,6 +46,7 @@ import java.util.concurrent.ExecutionException;
|
|||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
|
||||
public class ExportConceptMapToCsvCommand extends AbstractImportExportCsvConceptMapCommand {
|
||||
public static final String COMMAND = "export-conceptmap-to-csv";
|
||||
// TODO: Don't use qualified names for loggers in HAPI CLI.
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExportConceptMapToCsvCommand.class);
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
|
|||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
public class ImportCsvToConceptMapCommand extends AbstractImportExportCsvConceptMapCommand {
|
||||
public static final String COMMAND = "import-csv-to-conceptmap";
|
||||
|
||||
// TODO: Don't use qualified names for loggers in HAPI CLI.
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ImportCsvToConceptMapCommand.class);
|
||||
|
||||
|
@ -58,22 +60,11 @@ public class ImportCsvToConceptMapCommand extends AbstractImportExportCsvConcept
|
|||
protected static final String SOURCE_VALUE_SET_PARAM_LONGOPT = "input";
|
||||
protected static final String SOURCE_VALUE_SET_PARAM_NAME = "input";
|
||||
protected static final String SOURCE_VALUE_SET_PARAM_DESC = "The source value set of the ConceptMap to be imported (i.e. ConceptMap.sourceUri).";
|
||||
|
||||
protected static final String TARGET_VALUE_SET_PARAM = "o";
|
||||
protected static final String TARGET_VALUE_SET_PARAM_LONGOPT = "output";
|
||||
protected static final String TARGET_VALUE_SET_PARAM_NAME = "output";
|
||||
protected static final String TARGET_VALUE_SET_PARAM_DESC = "The target value set of the ConceptMap to be imported (i.e. ConceptMap.targetUri).";
|
||||
|
||||
protected static final String CLIENT_CERTIFICATION_PARAM = "c";
|
||||
protected static final String CLIENT_CERTIFICATION_PARAM_LONGOPT = "cert";
|
||||
protected static final String CLIENT_CERTIFICATION_PARAM_NAME = "cert";
|
||||
protected static final String CLIENT_CERTIFICATION_PARAM_DESC = "The client certification to be used for TLS";
|
||||
|
||||
protected static final String CLIENT_KEY_PARAM = "k";
|
||||
protected static final String CLIENT_KEY_PARAM_LONGOPT = "key";
|
||||
protected static final String CLIENT_KEY_PARAM_NAME = "key";
|
||||
protected static final String CLIENT_KEY_PARAM_DESC = "The client key to be used for TLS";
|
||||
|
||||
protected String sourceValueSet;
|
||||
protected String targetValueSet;
|
||||
|
||||
|
@ -98,9 +89,6 @@ public class ImportCsvToConceptMapCommand extends AbstractImportExportCsvConcept
|
|||
// </editor-fold desc="Additional parameters.">
|
||||
addOptionalOption(options, SOURCE_VALUE_SET_PARAM, SOURCE_VALUE_SET_PARAM_LONGOPT, SOURCE_VALUE_SET_PARAM_NAME, SOURCE_VALUE_SET_PARAM_DESC);
|
||||
addOptionalOption(options, TARGET_VALUE_SET_PARAM, TARGET_VALUE_SET_PARAM_LONGOPT, TARGET_VALUE_SET_PARAM_NAME, TARGET_VALUE_SET_PARAM_DESC);
|
||||
|
||||
addOptionalOption(options, CLIENT_CERTIFICATION_PARAM, CLIENT_CERTIFICATION_PARAM_LONGOPT, CLIENT_CERTIFICATION_PARAM_NAME, CLIENT_CERTIFICATION_PARAM_DESC);
|
||||
addOptionalOption(options, CLIENT_KEY_PARAM, CLIENT_KEY_PARAM_LONGOPT, CLIENT_KEY_PARAM_NAME, CLIENT_KEY_PARAM_DESC);
|
||||
// </editor-fold>
|
||||
addRequiredOption(options, FILE_PARAM, FILE_PARAM_LONGOPT, FILE_PARAM_NAME, FILE_PARAM_DESC);
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ public class ToggleSearchParametersCommand extends BaseCommand {
|
|||
addBaseUrlOption(options);
|
||||
addRequiredOption(options, "u", "url", true, "The code system URL associated with this upload (e.g. " + ITermLoaderSvc.SCT_URI + ")");
|
||||
addBasicAuthOption(options);
|
||||
addHttpsAuthOption(options);
|
||||
return options;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
package ca.uhn.fhir.cli;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
|
||||
import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
|
||||
import ca.uhn.fhir.test.utilities.BaseRequestGeneratingCommandTestUtil;
|
||||
import ca.uhn.fhir.test.utilities.RestServerR4Helper;
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
@ -24,10 +28,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
|
||||
class ExampleDataUploaderTest {
|
||||
|
||||
private FhirContext myCtx = FhirContext.forR4();
|
||||
|
||||
@RegisterExtension
|
||||
public final RestfulServerExtension myRestfulServerExtension = new RestfulServerExtension(myCtx);
|
||||
public final RestServerR4Helper myRestServerR4Helper = new RestServerR4Helper();
|
||||
@RegisterExtension
|
||||
public BaseRequestGeneratingCommandTestUtil myBaseRequestGeneratingCommandTestUtil = new BaseRequestGeneratingCommandTestUtil();
|
||||
|
||||
private final CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor();
|
||||
private final ExampleDataUploader testedCommand = new RequestCapturingExampleDataUploader(myCapturingInterceptor);
|
||||
|
@ -40,19 +44,20 @@ class ExampleDataUploaderTest {
|
|||
inputFilePath = resourcesPath + "/sample.json.zip";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testHeaderPassthrough() throws ParseException {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testHeaderPassthrough(boolean theIncludeTls) throws ParseException {
|
||||
String headerKey = "test-header-key";
|
||||
String headerValue = "test header value";
|
||||
|
||||
String[] args = new String[] {
|
||||
"-v", "r4", // BaseRequestGeneratingCommandTest required
|
||||
"-t", "http://localhost:8000", // BaseRequestGeneratingCommandTest required
|
||||
"-d", inputFilePath,
|
||||
"-hp", headerKey + ":" + headerValue // optional
|
||||
};
|
||||
String[] args = myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
"-v", "r4", // BaseRequestGeneratingCommandTest required
|
||||
"-d", inputFilePath,
|
||||
"-hp", headerKey + ":" + headerValue // optional
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper // BaseRequestGeneratingCommandTest required
|
||||
);
|
||||
|
||||
final CommandLine commandLine = new DefaultParser().parse(testedCommand.getOptions(), args, true);
|
||||
testedCommand.run(commandLine);
|
||||
|
@ -65,8 +70,13 @@ class ExampleDataUploaderTest {
|
|||
assertEquals(1, allHeaders.get(headerKey).size());
|
||||
|
||||
assertThat(allHeaders.get(headerKey), hasItems(headerValue));
|
||||
}
|
||||
|
||||
assertEquals(1, myRestServerR4Helper.getTransactions().size());
|
||||
Bundle bundle = myRestServerR4Helper.getTransactions().get(0);
|
||||
Resource resource = bundle.getEntry().get(0).getResource();
|
||||
assertEquals(Patient.class, resource.getClass());
|
||||
assertEquals("EX3152", resource.getIdElement().getIdPart());
|
||||
}
|
||||
|
||||
private static class RequestCapturingExampleDataUploader extends ExampleDataUploader {
|
||||
private final CapturingInterceptor myCapturingInterceptor;
|
||||
|
|
|
@ -1,25 +1,21 @@
|
|||
package ca.uhn.fhir.cli;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.interceptor.VerboseLoggingInterceptor;
|
||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||
import ca.uhn.fhir.test.utilities.LoggingExtension;
|
||||
import ca.uhn.fhir.test.utilities.BaseRequestGeneratingCommandTestUtil;
|
||||
import ca.uhn.fhir.test.utilities.RestServerDstu3Helper;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.dstu3.model.ConceptMap;
|
||||
import org.hl7.fhir.dstu3.model.Enumerations.ConceptMapEquivalence;
|
||||
import org.hl7.fhir.dstu3.model.UriType;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -38,30 +34,50 @@ public class ExportConceptMapToCsvCommandDstu3Test {
|
|||
private static final String CS_URL_3 = "http://example.com/codesystem/3";
|
||||
private static final String FILE = "./target/output_dstu3.csv";
|
||||
|
||||
private static String ourBase;
|
||||
private static IGenericClient ourClient;
|
||||
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static String ourVersion = "dstu3";
|
||||
private final FhirContext myCtx = FhirContext.forDstu3();
|
||||
private final String myVersion = "dstu3";
|
||||
|
||||
static {
|
||||
System.setProperty("test", "true");
|
||||
}
|
||||
|
||||
@RegisterExtension
|
||||
public LoggingExtension myLoggingExtension = new LoggingExtension();
|
||||
public final RestServerDstu3Helper myRestServerDstu3Helper = new RestServerDstu3Helper(true);
|
||||
@RegisterExtension
|
||||
public BaseRequestGeneratingCommandTestUtil myBaseRequestGeneratingCommandTestUtil = new BaseRequestGeneratingCommandTestUtil();
|
||||
|
||||
@Test
|
||||
public void testExportConceptMapToCsvCommand() throws IOException {
|
||||
ourLog.debug("ConceptMap:\n" + ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(createConceptMap()));
|
||||
@BeforeEach
|
||||
public void before(){
|
||||
myRestServerDstu3Helper.setConceptMapResourceProvider(new HashMapResourceProviderConceptMapDstu3(myCtx));
|
||||
myRestServerDstu3Helper.getClient().create().resource(createConceptMap()).execute();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
myRestServerDstu3Helper.clearDataAndCounts();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterAll(){
|
||||
TestUtil.randomizeLocaleAndTimezone();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testExportConceptMapToCsvCommandNoTls(boolean theIncludeTls) throws IOException {
|
||||
ourLog.debug("ConceptMap:\n" + myCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(createConceptMap()));
|
||||
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ExportConceptMapToCsvCommand.COMMAND,
|
||||
"-v", myVersion,
|
||||
"-u", CM_URL,
|
||||
"-f", FILE,
|
||||
"-l"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerDstu3Helper
|
||||
));
|
||||
|
||||
App.main(new String[]{"export-conceptmap-to-csv",
|
||||
"-v", ourVersion,
|
||||
"-t", ourBase,
|
||||
"-u", CM_URL,
|
||||
"-f", FILE,
|
||||
"-l"});
|
||||
await().until(() -> new File(FILE).exists());
|
||||
|
||||
String expected = "\"SOURCE_CODE_SYSTEM\",\"SOURCE_CODE_SYSTEM_VERSION\",\"TARGET_CODE_SYSTEM\",\"TARGET_CODE_SYSTEM_VERSION\",\"SOURCE_CODE\",\"SOURCE_DISPLAY\",\"TARGET_CODE\",\"TARGET_DISPLAY\",\"EQUIVALENCE\",\"COMMENT\"\n" +
|
||||
|
@ -85,36 +101,6 @@ public class ExportConceptMapToCsvCommandDstu3Test {
|
|||
FileUtils.deleteQuietly(new File(FILE));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClassClearContext() throws Exception {
|
||||
JettyUtil.closeServer(ourServer);
|
||||
TestUtil.randomizeLocaleAndTimezone();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
ourServer = new Server(0);
|
||||
|
||||
ServletHandler servletHandler = new ServletHandler();
|
||||
|
||||
RestfulServer restfulServer = new RestfulServer(ourCtx);
|
||||
restfulServer.registerInterceptor(new VerboseLoggingInterceptor());
|
||||
restfulServer.setResourceProviders(new HashMapResourceProviderConceptMapDstu3(ourCtx));
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder(restfulServer);
|
||||
servletHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(servletHandler);
|
||||
|
||||
JettyUtil.startServer(ourServer);
|
||||
ourPort = JettyUtil.getPortForStartedServer(ourServer);
|
||||
|
||||
ourBase = "http://localhost:" + ourPort;
|
||||
|
||||
ourClient = ourCtx.newRestfulGenericClient(ourBase);
|
||||
|
||||
ourClient.create().resource(createConceptMap()).execute();
|
||||
}
|
||||
|
||||
static ConceptMap createConceptMap() {
|
||||
ConceptMap conceptMap = new ConceptMap();
|
||||
conceptMap
|
||||
|
|
|
@ -1,23 +1,21 @@
|
|||
package ca.uhn.fhir.cli;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.interceptor.VerboseLoggingInterceptor;
|
||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||
import ca.uhn.fhir.test.utilities.BaseRequestGeneratingCommandTestUtil;
|
||||
import ca.uhn.fhir.test.utilities.RestServerR4Helper;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.r4.model.ConceptMap;
|
||||
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
|
||||
import org.hl7.fhir.r4.model.UriType;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -36,27 +34,50 @@ public class ExportConceptMapToCsvCommandR4Test {
|
|||
private static final String CS_URL_3 = "http://example.com/codesystem/3";
|
||||
private static final String FILE = new File("./target/output_r4.csv").getAbsolutePath();
|
||||
|
||||
private static String ourBase;
|
||||
private static IGenericClient ourClient;
|
||||
private static FhirContext ourCtx = FhirContext.forR4();
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static String ourVersion = "r4";
|
||||
|
||||
static {
|
||||
System.setProperty("test", "true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportConceptMapToCsvCommand() throws IOException {
|
||||
ourLog.info("ConceptMap:\n" + ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(createConceptMap()));
|
||||
@RegisterExtension
|
||||
public final RestServerR4Helper myRestServerR4Helper = new RestServerR4Helper(true);
|
||||
@RegisterExtension
|
||||
public BaseRequestGeneratingCommandTestUtil myBaseRequestGeneratingCommandTestUtil = new BaseRequestGeneratingCommandTestUtil();
|
||||
|
||||
private final FhirContext myCtx = FhirContext.forR4();
|
||||
private final String myVersion = "r4";
|
||||
|
||||
@BeforeEach
|
||||
public void before(){
|
||||
myRestServerR4Helper.setConceptMapResourceProvider(new HashMapResourceProviderConceptMapR4(myCtx));
|
||||
myRestServerR4Helper.getClient().create().resource(createConceptMap()).execute();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
myRestServerR4Helper.clearDataAndCounts();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterAll(){
|
||||
TestUtil.randomizeLocaleAndTimezone();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testExportConceptMapToCsvCommand(boolean theIncludeTls) throws IOException {
|
||||
ourLog.info("ConceptMap:\n" + myCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(createConceptMap()));
|
||||
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ExportConceptMapToCsvCommand.COMMAND,
|
||||
"-v", myVersion,
|
||||
"-u", CM_URL,
|
||||
"-f", FILE,
|
||||
"-l"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
|
||||
App.main(new String[]{"export-conceptmap-to-csv",
|
||||
"-v", ourVersion,
|
||||
"-t", ourBase,
|
||||
"-u", CM_URL,
|
||||
"-f", FILE,
|
||||
"-l"});
|
||||
await().until(() -> new File(FILE).exists());
|
||||
|
||||
String expected = "\"SOURCE_CODE_SYSTEM\",\"SOURCE_CODE_SYSTEM_VERSION\",\"TARGET_CODE_SYSTEM\",\"TARGET_CODE_SYSTEM_VERSION\",\"SOURCE_CODE\",\"SOURCE_DISPLAY\",\"TARGET_CODE\",\"TARGET_DISPLAY\",\"EQUIVALENCE\",\"COMMENT\"\n" +
|
||||
|
@ -78,36 +99,6 @@ public class ExportConceptMapToCsvCommandR4Test {
|
|||
FileUtils.deleteQuietly(new File(FILE));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClassClearContext() throws Exception {
|
||||
JettyUtil.closeServer(ourServer);
|
||||
TestUtil.randomizeLocaleAndTimezone();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
ourServer = new Server(0);
|
||||
|
||||
ServletHandler servletHandler = new ServletHandler();
|
||||
|
||||
RestfulServer restfulServer = new RestfulServer(ourCtx);
|
||||
restfulServer.registerInterceptor(new VerboseLoggingInterceptor());
|
||||
restfulServer.setResourceProviders(new HashMapResourceProviderConceptMapR4(ourCtx));
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder(restfulServer);
|
||||
servletHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(servletHandler);
|
||||
|
||||
JettyUtil.startServer(ourServer);
|
||||
ourPort = JettyUtil.getPortForStartedServer(ourServer);
|
||||
|
||||
ourBase = "http://localhost:" + ourPort;
|
||||
|
||||
ourClient = ourCtx.newRestfulGenericClient(ourBase);
|
||||
|
||||
ourClient.create().resource(createConceptMap()).execute();
|
||||
}
|
||||
|
||||
static ConceptMap createConceptMap() {
|
||||
ConceptMap conceptMap = new ConceptMap();
|
||||
conceptMap
|
||||
|
|
|
@ -2,14 +2,9 @@ package ca.uhn.fhir.cli;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.interceptor.VerboseLoggingInterceptor;
|
||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||
import ca.uhn.fhir.test.utilities.BaseRequestGeneratingCommandTestUtil;
|
||||
import ca.uhn.fhir.test.utilities.RestServerDstu3Helper;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.dstu3.model.Bundle;
|
||||
import org.hl7.fhir.dstu3.model.ConceptMap;
|
||||
import org.hl7.fhir.dstu3.model.ConceptMap.ConceptMapGroupComponent;
|
||||
|
@ -19,8 +14,11 @@ import org.hl7.fhir.dstu3.model.Enumerations.ConceptMapEquivalence;
|
|||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
@ -37,26 +35,32 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
|||
private static final String CS_URL_3 = "http://example.com/codesystem/3";
|
||||
private static final String FILENAME = "import-csv-to-conceptmap-command-test-input.csv";
|
||||
|
||||
private static String file;
|
||||
private static String ourBase;
|
||||
private static IGenericClient ourClient;
|
||||
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static String ourVersion = "dstu3";
|
||||
|
||||
private static RestfulServer restfulServer;
|
||||
|
||||
private static HashMapResourceProviderConceptMapDstu3 hashMapResourceProviderConceptMapDstu3;
|
||||
private final FhirContext myCtx = FhirContext.forDstu3();
|
||||
private final String myVersion = "dstu3";
|
||||
private String myFile;
|
||||
|
||||
static {
|
||||
System.setProperty("test", "true");
|
||||
}
|
||||
|
||||
@RegisterExtension
|
||||
public final RestServerDstu3Helper myRestServerDstu3Helper = new RestServerDstu3Helper(true);
|
||||
@RegisterExtension
|
||||
public BaseRequestGeneratingCommandTestUtil myBaseRequestGeneratingCommandTestUtil = new BaseRequestGeneratingCommandTestUtil();
|
||||
|
||||
@BeforeEach
|
||||
public void before(){
|
||||
myRestServerDstu3Helper.setConceptMapResourceProvider(new HashMapResourceProviderConceptMapDstu3(myCtx));
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterClearResourceProvider() {
|
||||
HashMapResourceProviderConceptMapDstu3 resourceProvider = (HashMapResourceProviderConceptMapDstu3) restfulServer.getResourceProviders().iterator().next();
|
||||
resourceProvider.clear();
|
||||
public void afterEach() {
|
||||
myRestServerDstu3Helper.clearDataAndCounts();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterAll(){
|
||||
TestUtil.randomizeLocaleAndTimezone();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -65,7 +69,7 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
|||
String conceptMapUrl = conceptMap.getUrl();
|
||||
|
||||
ourLog.info("Searching for existing ConceptMap with specified URL (i.e. ConceptMap.url): {}", conceptMapUrl);
|
||||
MethodOutcome methodOutcome = ourClient
|
||||
MethodOutcome methodOutcome = myRestServerDstu3Helper.getClient()
|
||||
.update()
|
||||
.resource(conceptMap)
|
||||
.conditional()
|
||||
|
@ -78,11 +82,11 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
|||
@Test
|
||||
public void testConditionalUpdateResultsInUpdate() {
|
||||
ConceptMap conceptMap = ExportConceptMapToCsvCommandDstu3Test.createConceptMap();
|
||||
ourClient.create().resource(conceptMap).execute();
|
||||
myRestServerDstu3Helper.getClient().create().resource(conceptMap).execute();
|
||||
String conceptMapUrl = conceptMap.getUrl();
|
||||
|
||||
ourLog.info("Searching for existing ConceptMap with specified URL (i.e. ConceptMap.url): {}", conceptMapUrl);
|
||||
MethodOutcome methodOutcome = ourClient
|
||||
MethodOutcome methodOutcome = myRestServerDstu3Helper.getClient()
|
||||
.update()
|
||||
.resource(conceptMap)
|
||||
.conditional()
|
||||
|
@ -95,9 +99,9 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
|||
@Test
|
||||
public void testNonConditionalUpdate() {
|
||||
ConceptMap conceptMap = ExportConceptMapToCsvCommandDstu3Test.createConceptMap();
|
||||
ourClient.create().resource(conceptMap).execute();
|
||||
myRestServerDstu3Helper.getClient().create().resource(conceptMap).execute();
|
||||
|
||||
Bundle response = ourClient
|
||||
Bundle response = myRestServerDstu3Helper.getClient()
|
||||
.search()
|
||||
.forResource(ConceptMap.class)
|
||||
.where(ConceptMap.URL.matches().value(CM_URL))
|
||||
|
@ -106,7 +110,7 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
|||
|
||||
ConceptMap resultConceptMap = (ConceptMap) response.getEntryFirstRep().getResource();
|
||||
|
||||
MethodOutcome methodOutcome = ourClient
|
||||
MethodOutcome methodOutcome = myRestServerDstu3Helper.getClient()
|
||||
.update()
|
||||
.resource(resultConceptMap)
|
||||
.withId(resultConceptMap.getIdElement())
|
||||
|
@ -115,22 +119,27 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
|||
assertNull(methodOutcome.getCreated());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportCsvToConceptMapCommand() throws FHIRException {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testImportCsvToConceptMapCommandNoTls(boolean theIncludeTls) throws FHIRException {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
File fileToImport = new File(classLoader.getResource(FILENAME).getFile());
|
||||
ImportCsvToConceptMapCommandDstu3Test.file = fileToImport.getAbsolutePath();
|
||||
myFile = fileToImport.getAbsolutePath();
|
||||
|
||||
App.main(new String[]{"import-csv-to-conceptmap",
|
||||
"-v", ourVersion,
|
||||
"-t", ourBase,
|
||||
"-u", CM_URL,
|
||||
"-i", VS_URL_1,
|
||||
"-o", VS_URL_2,
|
||||
"-f", file,
|
||||
"-l"});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ImportCsvToConceptMapCommand.COMMAND,
|
||||
"-v", myVersion,
|
||||
"-u", CM_URL,
|
||||
"-i", VS_URL_1,
|
||||
"-o", VS_URL_2,
|
||||
"-f", myFile,
|
||||
"-l"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerDstu3Helper
|
||||
));
|
||||
|
||||
Bundle response = ourClient
|
||||
Bundle response = myRestServerDstu3Helper.getClient()
|
||||
.search()
|
||||
.forResource(ConceptMap.class)
|
||||
.where(ConceptMap.URL.matches().value(CM_URL))
|
||||
|
@ -139,9 +148,9 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
|||
|
||||
ConceptMap conceptMap = (ConceptMap) response.getEntryFirstRep().getResource();
|
||||
|
||||
ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
ourLog.info(myCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
||||
assertEquals("http://localhost:" + ourPort + "/ConceptMap/1/_history/1", conceptMap.getId());
|
||||
assertEquals(myRestServerDstu3Helper.getBase() + "/ConceptMap/1/_history/1", conceptMap.getId());
|
||||
|
||||
assertEquals(CM_URL, conceptMap.getUrl());
|
||||
assertEquals(VS_URL_1, conceptMap.getSourceUriType().getValueAsString());
|
||||
|
@ -317,16 +326,20 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
|||
assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
|
||||
assertEquals("3d This is a comment.", target.getComment());
|
||||
|
||||
App.main(new String[]{"import-csv-to-conceptmap",
|
||||
"-v", ourVersion,
|
||||
"-t", ourBase,
|
||||
"-u", CM_URL,
|
||||
"-i", VS_URL_1,
|
||||
"-o", VS_URL_2,
|
||||
"-f", file,
|
||||
"-l"});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ImportCsvToConceptMapCommand.COMMAND,
|
||||
"-v", myVersion,
|
||||
"-u", CM_URL,
|
||||
"-i", VS_URL_1,
|
||||
"-o", VS_URL_2,
|
||||
"-f", myFile,
|
||||
"-l"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerDstu3Helper
|
||||
));
|
||||
|
||||
response = ourClient
|
||||
response = myRestServerDstu3Helper.getClient()
|
||||
.search()
|
||||
.forResource(ConceptMap.class)
|
||||
.where(ConceptMap.URL.matches().value(CM_URL))
|
||||
|
@ -335,34 +348,7 @@ public class ImportCsvToConceptMapCommandDstu3Test {
|
|||
|
||||
conceptMap = (ConceptMap) response.getEntryFirstRep().getResource();
|
||||
|
||||
assertEquals("http://localhost:" + ourPort + "/ConceptMap/1/_history/2", conceptMap.getId());
|
||||
assertEquals(myRestServerDstu3Helper.getBase() + "/ConceptMap/1/_history/2", conceptMap.getId());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClassClearContext() throws Exception {
|
||||
JettyUtil.closeServer(ourServer);
|
||||
TestUtil.randomizeLocaleAndTimezone();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
ourServer = new Server(0);
|
||||
|
||||
ServletHandler servletHandler = new ServletHandler();
|
||||
|
||||
restfulServer = new RestfulServer(ourCtx);
|
||||
restfulServer.registerInterceptor(new VerboseLoggingInterceptor());
|
||||
restfulServer.setResourceProviders(new HashMapResourceProviderConceptMapDstu3(ourCtx));
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder(restfulServer);
|
||||
servletHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(servletHandler);
|
||||
|
||||
JettyUtil.startServer(ourServer);
|
||||
ourPort = JettyUtil.getPortForStartedServer(ourServer);
|
||||
|
||||
ourBase = "http://localhost:" + ourPort;
|
||||
|
||||
ourClient = ourCtx.newRestfulGenericClient(ourBase);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,9 @@ package ca.uhn.fhir.cli;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.interceptor.VerboseLoggingInterceptor;
|
||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||
import ca.uhn.fhir.test.utilities.BaseRequestGeneratingCommandTestUtil;
|
||||
import ca.uhn.fhir.test.utilities.RestServerR4Helper;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.ConceptMap;
|
||||
|
@ -19,8 +14,11 @@ import org.hl7.fhir.r4.model.ConceptMap.TargetElementComponent;
|
|||
import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
@ -38,26 +36,32 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
private static final String CS_URL_3 = "http://example.com/codesystem/3";
|
||||
private static final String FILENAME = "import-csv-to-conceptmap-command-test-input.csv";
|
||||
|
||||
private static String file;
|
||||
private static String ourBase;
|
||||
private static IGenericClient ourClient;
|
||||
private static FhirContext ourCtx = FhirContext.forR4();
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static String ourVersion = "r4";
|
||||
|
||||
private static RestfulServer restfulServer;
|
||||
|
||||
private static HashMapResourceProviderConceptMapR4 hashMapResourceProviderConceptMapR4;
|
||||
|
||||
static {
|
||||
System.setProperty("test", "true");
|
||||
}
|
||||
|
||||
private final FhirContext myFhirContext = FhirContext.forR4();
|
||||
private final String myVersion = "r4";
|
||||
private String myFilePath;
|
||||
|
||||
@RegisterExtension
|
||||
public final RestServerR4Helper myRestServerR4Helper = new RestServerR4Helper(true);
|
||||
@RegisterExtension
|
||||
public BaseRequestGeneratingCommandTestUtil myBaseRequestGeneratingCommandTestUtil = new BaseRequestGeneratingCommandTestUtil();
|
||||
|
||||
@BeforeEach
|
||||
public void before(){
|
||||
myRestServerR4Helper.setConceptMapResourceProvider(new HashMapResourceProviderConceptMapR4(myFhirContext));
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterClearResourceProvider() {
|
||||
HashMapResourceProviderConceptMapR4 resourceProvider = (HashMapResourceProviderConceptMapR4) restfulServer.getResourceProviders().iterator().next();
|
||||
resourceProvider.clear();
|
||||
public void afterEach() {
|
||||
myRestServerR4Helper.clearDataAndCounts();
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterAll(){
|
||||
TestUtil.randomizeLocaleAndTimezone();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -66,7 +70,7 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
String conceptMapUrl = conceptMap.getUrl();
|
||||
|
||||
ourLog.info("Searching for existing ConceptMap with specified URL (i.e. ConceptMap.url): {}", conceptMapUrl);
|
||||
MethodOutcome methodOutcome = ourClient
|
||||
MethodOutcome methodOutcome = myRestServerR4Helper.getClient()
|
||||
.update()
|
||||
.resource(conceptMap)
|
||||
.conditional()
|
||||
|
@ -80,11 +84,11 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
@Test
|
||||
public void testConditionalUpdateResultsInUpdate() {
|
||||
ConceptMap conceptMap = ExportConceptMapToCsvCommandR4Test.createConceptMap();
|
||||
ourClient.create().resource(conceptMap).execute();
|
||||
myRestServerR4Helper.getClient().create().resource(conceptMap).execute();
|
||||
String conceptMapUrl = conceptMap.getUrl();
|
||||
|
||||
ourLog.info("Searching for existing ConceptMap with specified URL (i.e. ConceptMap.url): {}", conceptMapUrl);
|
||||
MethodOutcome methodOutcome = ourClient
|
||||
MethodOutcome methodOutcome = myRestServerR4Helper.getClient()
|
||||
.update()
|
||||
.resource(conceptMap)
|
||||
.conditional()
|
||||
|
@ -98,9 +102,9 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
@Test
|
||||
public void testNonConditionalUpdate() {
|
||||
ConceptMap conceptMap = ExportConceptMapToCsvCommandR4Test.createConceptMap();
|
||||
ourClient.create().resource(conceptMap).execute();
|
||||
myRestServerR4Helper.getClient().create().resource(conceptMap).execute();
|
||||
|
||||
Bundle response = ourClient
|
||||
Bundle response = myRestServerR4Helper.getClient()
|
||||
.search()
|
||||
.forResource(ConceptMap.class)
|
||||
.where(ConceptMap.URL.matches().value(CM_URL))
|
||||
|
@ -109,7 +113,7 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
|
||||
ConceptMap resultConceptMap = (ConceptMap) response.getEntryFirstRep().getResource();
|
||||
|
||||
MethodOutcome methodOutcome = ourClient
|
||||
MethodOutcome methodOutcome = myRestServerR4Helper.getClient()
|
||||
.update()
|
||||
.resource(resultConceptMap)
|
||||
.withId(resultConceptMap.getIdElement())
|
||||
|
@ -121,22 +125,27 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
assertTrue(!Boolean.TRUE.equals(methodOutcome.getCreated()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportCsvToConceptMapCommand() throws FHIRException {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testImportCsvToConceptMapCommand(boolean theIncludeTls) throws Exception {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
File fileToImport = new File(classLoader.getResource(FILENAME).getFile());
|
||||
ImportCsvToConceptMapCommandR4Test.file = fileToImport.getAbsolutePath();
|
||||
myFilePath = fileToImport.getAbsolutePath();
|
||||
|
||||
App.main(new String[]{"import-csv-to-conceptmap",
|
||||
"-v", ourVersion,
|
||||
"-t", ourBase,
|
||||
"-u", CM_URL,
|
||||
"-i", VS_URL_1,
|
||||
"-o", VS_URL_2,
|
||||
"-f", file,
|
||||
"-l"});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ImportCsvToConceptMapCommand.COMMAND,
|
||||
"-v", myVersion,
|
||||
"-u", CM_URL,
|
||||
"-i", VS_URL_1,
|
||||
"-o", VS_URL_2,
|
||||
"-f", myFilePath,
|
||||
"-l"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
|
||||
Bundle response = ourClient
|
||||
Bundle response = myRestServerR4Helper.getClient()
|
||||
.search()
|
||||
.forResource(ConceptMap.class)
|
||||
.where(ConceptMap.URL.matches().value(CM_URL))
|
||||
|
@ -145,9 +154,9 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
|
||||
ConceptMap conceptMap = (ConceptMap) response.getEntryFirstRep().getResource();
|
||||
|
||||
ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
ourLog.info(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
||||
assertEquals("http://localhost:" + ourPort + "/ConceptMap/1/_history/1", conceptMap.getId());
|
||||
assertEquals(myRestServerR4Helper.getBase() + "/ConceptMap/1/_history/1", conceptMap.getId());
|
||||
|
||||
assertEquals(CM_URL, conceptMap.getUrl());
|
||||
assertEquals(VS_URL_1, conceptMap.getSourceUriType().getValueAsString());
|
||||
|
@ -323,16 +332,20 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
assertEquals(ConceptMapEquivalence.EQUAL, target.getEquivalence());
|
||||
assertEquals("3d This is a comment.", target.getComment());
|
||||
|
||||
App.main(new String[]{"import-csv-to-conceptmap",
|
||||
"-v", ourVersion,
|
||||
"-t", ourBase,
|
||||
"-u", CM_URL,
|
||||
"-i", VS_URL_1,
|
||||
"-o", VS_URL_2,
|
||||
"-f", file,
|
||||
"-l"});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ImportCsvToConceptMapCommand.COMMAND,
|
||||
"-v", myVersion,
|
||||
"-u", CM_URL,
|
||||
"-i", VS_URL_1,
|
||||
"-o", VS_URL_2,
|
||||
"-f", myFilePath,
|
||||
"-l"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
|
||||
response = ourClient
|
||||
response = myRestServerR4Helper.getClient()
|
||||
.search()
|
||||
.forResource(ConceptMap.class)
|
||||
.where(ConceptMap.URL.matches().value(CM_URL))
|
||||
|
@ -341,25 +354,30 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
|
||||
conceptMap = (ConceptMap) response.getEntryFirstRep().getResource();
|
||||
|
||||
assertEquals("http://localhost:" + ourPort + "/ConceptMap/1/_history/2", conceptMap.getId());
|
||||
assertEquals(myRestServerR4Helper.getBase() + "/ConceptMap/1/_history/2", conceptMap.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImportCsvToConceptMapCommandWithByteOrderMark() throws FHIRException {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testImportCsvToConceptMapCommandWithByteOrderMark(boolean theIncludeTls) throws FHIRException {
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
File fileToImport = new File(classLoader.getResource("loinc-to-phenx.csv").getFile());
|
||||
ImportCsvToConceptMapCommandR4Test.file = fileToImport.getAbsolutePath();
|
||||
myFilePath = fileToImport.getAbsolutePath();
|
||||
|
||||
App.main(new String[]{"import-csv-to-conceptmap",
|
||||
"-v", ourVersion,
|
||||
"-t", ourBase,
|
||||
"-u", "http://loinc.org/cm/loinc-to-phenx",
|
||||
"-i", "http://loinc.org",
|
||||
"-o", "http://phenxtoolkit.org",
|
||||
"-f", file,
|
||||
"-l"});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ImportCsvToConceptMapCommand.COMMAND,
|
||||
"-v", myVersion,
|
||||
"-u", "http://loinc.org/cm/loinc-to-phenx",
|
||||
"-i", "http://loinc.org",
|
||||
"-o", "http://phenxtoolkit.org",
|
||||
"-f", myFilePath,
|
||||
"-l"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
|
||||
Bundle response = ourClient
|
||||
Bundle response = myRestServerR4Helper.getClient()
|
||||
.search()
|
||||
.forResource(ConceptMap.class)
|
||||
.where(ConceptMap.URL.matches().value("http://loinc.org/cm/loinc-to-phenx"))
|
||||
|
@ -368,9 +386,9 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
|
||||
ConceptMap conceptMap = (ConceptMap) response.getEntryFirstRep().getResource();
|
||||
|
||||
ourLog.info(ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
ourLog.info(myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(conceptMap));
|
||||
|
||||
assertEquals("http://localhost:" + ourPort + "/ConceptMap/1/_history/1", conceptMap.getId());
|
||||
assertEquals(myRestServerR4Helper.getBase() + "/ConceptMap/1/_history/1", conceptMap.getId());
|
||||
|
||||
assertEquals("http://loinc.org/cm/loinc-to-phenx", conceptMap.getUrl());
|
||||
assertEquals("http://loinc.org", conceptMap.getSourceUriType().getValueAsString());
|
||||
|
@ -398,16 +416,20 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
assertEquals(ConceptMapEquivalence.EQUIVALENT, target.getEquivalence());
|
||||
assertNull(target.getComment());
|
||||
|
||||
App.main(new String[]{"import-csv-to-conceptmap",
|
||||
"-v", ourVersion,
|
||||
"-t", ourBase,
|
||||
"-u", "http://loinc.org/cm/loinc-to-phenx",
|
||||
"-i", "http://loinc.org",
|
||||
"-o", "http://phenxtoolkit.org",
|
||||
"-f", file,
|
||||
"-l"});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ImportCsvToConceptMapCommand.COMMAND,
|
||||
"-v", myVersion,
|
||||
"-u", "http://loinc.org/cm/loinc-to-phenx",
|
||||
"-i", "http://loinc.org",
|
||||
"-o", "http://phenxtoolkit.org",
|
||||
"-f", myFilePath,
|
||||
"-l"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
|
||||
response = ourClient
|
||||
response = myRestServerR4Helper.getClient()
|
||||
.search()
|
||||
.forResource(ConceptMap.class)
|
||||
.where(ConceptMap.URL.matches().value("http://loinc.org/cm/loinc-to-phenx"))
|
||||
|
@ -416,34 +438,6 @@ public class ImportCsvToConceptMapCommandR4Test {
|
|||
|
||||
conceptMap = (ConceptMap) response.getEntryFirstRep().getResource();
|
||||
|
||||
assertEquals("http://localhost:" + ourPort + "/ConceptMap/1/_history/2", conceptMap.getId());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void afterClassClearContext() throws Exception {
|
||||
JettyUtil.closeServer(ourServer);
|
||||
TestUtil.randomizeLocaleAndTimezone();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeClass() throws Exception {
|
||||
ourServer = new Server(0);
|
||||
|
||||
ServletHandler servletHandler = new ServletHandler();
|
||||
|
||||
restfulServer = new RestfulServer(ourCtx);
|
||||
restfulServer.registerInterceptor(new VerboseLoggingInterceptor());
|
||||
restfulServer.setResourceProviders(new HashMapResourceProviderConceptMapR4(ourCtx));
|
||||
|
||||
ServletHolder servletHolder = new ServletHolder(restfulServer);
|
||||
servletHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(servletHandler);
|
||||
|
||||
JettyUtil.startServer(ourServer);
|
||||
ourPort = JettyUtil.getPortForStartedServer(ourServer);
|
||||
|
||||
ourBase = "http://localhost:" + ourPort;
|
||||
|
||||
ourClient = ourCtx.newRestfulGenericClient(ourBase);
|
||||
assertEquals(myRestServerR4Helper.getBase() + "/ConceptMap/1/_history/2", conceptMap.getId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,15 @@ package ca.uhn.fhir.cli;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProvider;
|
||||
import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
|
||||
import ca.uhn.fhir.test.utilities.BaseRequestGeneratingCommandTestUtil;
|
||||
import ca.uhn.fhir.test.utilities.RestServerR4Helper;
|
||||
import ca.uhn.fhir.util.ParametersUtil;
|
||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
|
@ -31,8 +34,9 @@ class ReindexTerminologyCommandTest {
|
|||
private BaseJpaSystemProvider<?, ?> myProvider = spy(new BaseJpaSystemProvider<>());
|
||||
|
||||
@RegisterExtension
|
||||
public final RestfulServerExtension myRestfulServerExtension =
|
||||
new RestfulServerExtension(myContext, myProvider);
|
||||
public final RestServerR4Helper myRestServerR4Helper = new RestServerR4Helper(true);
|
||||
@RegisterExtension
|
||||
public BaseRequestGeneratingCommandTestUtil myBaseRequestGeneratingCommandTestUtil = new BaseRequestGeneratingCommandTestUtil();
|
||||
|
||||
|
||||
private final ByteArrayOutputStream outputStreamCaptor = new ByteArrayOutputStream();
|
||||
|
@ -41,65 +45,85 @@ class ReindexTerminologyCommandTest {
|
|||
System.setProperty("test", "true");
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach(){
|
||||
myRestServerR4Helper.registerProvider(myProvider);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProviderMethodInvoked() {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testProviderMethodInvoked(boolean theIncludeTls) {
|
||||
System.setOut(new PrintStream(outputStreamCaptor));
|
||||
IBaseParameters retVal = ParametersUtil.newInstance(myContext);
|
||||
ParametersUtil.addParameterToParametersBoolean(myContext, retVal, RESP_PARAM_SUCCESS, true);
|
||||
doReturn(retVal).when(myProvider).reindexTerminology(any());
|
||||
|
||||
App.main(new String[]{
|
||||
ReindexTerminologyCommand.REINDEX_TERMINOLOGY,
|
||||
"-v", "r4",
|
||||
"-t", myRestfulServerExtension.getBaseUrl()
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ReindexTerminologyCommand.REINDEX_TERMINOLOGY,
|
||||
"-v", "r4"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
|
||||
assertThat(outputStreamCaptor.toString().trim(),
|
||||
outputStreamCaptor.toString().trim(), containsString("<valueBoolean value=\"true\"/>"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoVersionThrows() {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testNoVersionThrows(boolean theIncludeTls) {
|
||||
IBaseParameters retVal = ParametersUtil.newInstance(myContext);
|
||||
ParametersUtil.addParameterToParametersBoolean(myContext, retVal, RESP_PARAM_SUCCESS, true);
|
||||
doReturn(retVal).when(myProvider).reindexTerminology(any());
|
||||
|
||||
Error thrown = assertThrows(Error.class, () ->
|
||||
App.main(new String[]{
|
||||
ReindexTerminologyCommand.REINDEX_TERMINOLOGY,
|
||||
"-t", myRestfulServerExtension.getBaseUrl()
|
||||
})
|
||||
);
|
||||
Error thrown = assertThrows(Error.class, () -> {
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ReindexTerminologyCommand.REINDEX_TERMINOLOGY
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
});
|
||||
assertThat(thrown.getMessage(), containsString("Missing required option: v"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoTargetThrows() {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testNoTargetThrows(boolean theIncludeTls) {
|
||||
IBaseParameters retVal = ParametersUtil.newInstance(myContext);
|
||||
ParametersUtil.addParameterToParametersBoolean(myContext, retVal, RESP_PARAM_SUCCESS, true);
|
||||
doReturn(retVal).when(myProvider).reindexTerminology(any());
|
||||
|
||||
Error thrown = assertThrows(Error.class, () ->
|
||||
App.main(new String[]{ReindexTerminologyCommand.REINDEX_TERMINOLOGY, "-v", "r4"})
|
||||
);
|
||||
Error thrown = assertThrows(Error.class, () -> {
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ReindexTerminologyCommand.REINDEX_TERMINOLOGY,
|
||||
"-v", "r4"
|
||||
},
|
||||
null, theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
});
|
||||
assertThat(thrown.getMessage(), containsString("Missing required option: t"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testHandleUnexpectedResponse() {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testHandleUnexpectedResponse(boolean theIncludeTls) {
|
||||
System.setOut(new PrintStream(outputStreamCaptor));
|
||||
IBaseParameters retVal = ParametersUtil.newInstance(myContext);
|
||||
doReturn(retVal).when(myProvider).reindexTerminology(any());
|
||||
|
||||
App.main(new String[]{
|
||||
ReindexTerminologyCommand.REINDEX_TERMINOLOGY,
|
||||
"-v", "r4",
|
||||
"-t", myRestfulServerExtension.getBaseUrl()
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ReindexTerminologyCommand.REINDEX_TERMINOLOGY,
|
||||
"-v", "r4"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
|
||||
assertThat(outputStreamCaptor.toString().trim(),
|
||||
outputStreamCaptor.toString().trim(), containsString("<valueBoolean value=\"false\"/>"));
|
||||
|
@ -110,8 +134,9 @@ class ReindexTerminologyCommandTest {
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testHandleServiceError() {
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = {true, false})
|
||||
public void testHandleServiceError(boolean theIncludeTls) {
|
||||
System.setOut(new PrintStream(outputStreamCaptor));
|
||||
IBaseParameters retVal = ParametersUtil.newInstance(myContext);
|
||||
ParametersUtil.addParameterToParametersBoolean(myContext, retVal, RESP_PARAM_SUCCESS, false);
|
||||
|
@ -119,11 +144,13 @@ class ReindexTerminologyCommandTest {
|
|||
"Freetext service is not configured. Operation didn't run.");
|
||||
doReturn(retVal).when(myProvider).reindexTerminology(any());
|
||||
|
||||
App.main(new String[]{
|
||||
ReindexTerminologyCommand.REINDEX_TERMINOLOGY,
|
||||
"-v", "r4",
|
||||
"-t", myRestfulServerExtension.getBaseUrl()
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
ReindexTerminologyCommand.REINDEX_TERMINOLOGY,
|
||||
"-v", "r4"
|
||||
},
|
||||
"-t", theIncludeTls, myRestServerR4Helper
|
||||
));
|
||||
|
||||
assertThat(outputStreamCaptor.toString().trim(),
|
||||
outputStreamCaptor.toString().trim(), containsString("<valueBoolean value=\"false\"/>"));
|
||||
|
|
|
@ -5,20 +5,21 @@ import ca.uhn.fhir.i18n.Msg;
|
|||
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
|
||||
import ca.uhn.fhir.jpa.term.UploadStatistics;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||
import ca.uhn.fhir.test.utilities.BaseRequestGeneratingCommandTestUtil;
|
||||
import ca.uhn.fhir.test.utilities.BaseRestServerHelper;
|
||||
import ca.uhn.fhir.test.utilities.RestServerDstu3Helper;
|
||||
import ca.uhn.fhir.test.utilities.RestServerR4Helper;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.TestInfo;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
|
@ -69,8 +70,6 @@ public class UploadTerminologyCommandTest {
|
|||
private final String myICD10URL = "http://hl7.org/fhir/sid/icd-10-cm";
|
||||
private final String myICD10FileName = new File("src/test/resources").getAbsolutePath() + "/icd10cm_tabular_2021.xml";
|
||||
private File myICD10File = new File(myICD10FileName);
|
||||
private Server myServer;
|
||||
private int myPort;
|
||||
|
||||
@Mock
|
||||
protected ITermLoaderSvc myTermLoaderSvc;
|
||||
|
@ -82,35 +81,43 @@ public class UploadTerminologyCommandTest {
|
|||
System.setProperty("test", "true");
|
||||
}
|
||||
|
||||
static Stream<String> paramsProvider() {
|
||||
return Stream.of(FHIR_VERSION_DSTU3, FHIR_VERSION_R4);
|
||||
static Stream<Arguments> paramsProvider(){
|
||||
return Stream.of(
|
||||
// [0] theFhirVersion, [1] theIncludeTls
|
||||
Arguments.arguments(FHIR_VERSION_DSTU3, true),
|
||||
Arguments.arguments(FHIR_VERSION_DSTU3, false),
|
||||
Arguments.arguments(FHIR_VERSION_R4, true),
|
||||
Arguments.arguments(FHIR_VERSION_R4, false)
|
||||
);
|
||||
}
|
||||
|
||||
@RegisterExtension
|
||||
public final RestServerR4Helper myRestServerR4Helper = new RestServerR4Helper(true);
|
||||
@RegisterExtension
|
||||
public final RestServerDstu3Helper myRestServerDstu3Helper = new RestServerDstu3Helper(true);
|
||||
@RegisterExtension
|
||||
public BaseRequestGeneratingCommandTestUtil myBaseRequestGeneratingCommandTestUtil = new BaseRequestGeneratingCommandTestUtil();
|
||||
|
||||
private BaseRestServerHelper myBaseRestServerHelper;
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach(TestInfo testInfo) throws Exception {
|
||||
writeConceptAndHierarchyFiles();
|
||||
if (testInfo.getDisplayName().endsWith(FHIR_VERSION_DSTU3)) {
|
||||
if (testInfo.getDisplayName().contains(FHIR_VERSION_DSTU3)) {
|
||||
myCtx = FhirContext.forDstu3();
|
||||
} else if (testInfo.getDisplayName().endsWith(FHIR_VERSION_R4)) {
|
||||
myRestServerDstu3Helper.registerProvider(new TerminologyUploaderProvider(myCtx, myTermLoaderSvc));
|
||||
myBaseRestServerHelper = myRestServerDstu3Helper;
|
||||
} else if (testInfo.getDisplayName().contains(FHIR_VERSION_R4)) {
|
||||
myCtx = FhirContext.forR4();
|
||||
myRestServerR4Helper.registerProvider(new TerminologyUploaderProvider(myCtx, myTermLoaderSvc));
|
||||
myBaseRestServerHelper = myRestServerR4Helper;
|
||||
} else {
|
||||
fail("Unknown FHIR Version param provided: " + testInfo.getDisplayName());
|
||||
}
|
||||
myServer = new Server(0);
|
||||
TerminologyUploaderProvider provider = new TerminologyUploaderProvider(myCtx, myTermLoaderSvc);
|
||||
ServletHandler proxyHandler = new ServletHandler();
|
||||
RestfulServer servlet = new RestfulServer(myCtx);
|
||||
servlet.registerProvider(provider);
|
||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||
myServer.setHandler(proxyHandler);
|
||||
JettyUtil.startServer(myServer);
|
||||
myPort = JettyUtil.getPortForStartedServer(myServer);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() throws Exception {
|
||||
JettyUtil.closeServer(myServer);
|
||||
FileUtils.deleteQuietly(myConceptsFile);
|
||||
FileUtils.deleteQuietly(myHierarchyFile);
|
||||
FileUtils.deleteQuietly(myCodeSystemFile);
|
||||
|
@ -122,7 +129,7 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testDeltaAdd(String theFhirVersion) throws IOException {
|
||||
public void testDeltaAdd(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||
when(myTermLoaderSvc.loadDeltaAdd(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.dstu3.model.IdType("CodeSystem/101")));
|
||||
} else if (FHIR_VERSION_R4.equals(theFhirVersion)) {
|
||||
|
@ -131,15 +138,17 @@ public class UploadTerminologyCommandTest {
|
|||
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||
}
|
||||
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName,
|
||||
"-d", myHierarchyFileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName,
|
||||
"-d", myHierarchyFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
|
||||
verify(myTermLoaderSvc, times(1)).loadDeltaAdd(eq("http://foo"), myDescriptorListCaptor.capture(), any());
|
||||
|
||||
|
@ -151,7 +160,7 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testDeltaAddUsingCodeSystemResource(String theFhirVersion) throws IOException {
|
||||
public void testDeltaAddUsingCodeSystemResource(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||
try (FileWriter w = new FileWriter(myCodeSystemFile, false)) {
|
||||
org.hl7.fhir.dstu3.model.CodeSystem cs = new org.hl7.fhir.dstu3.model.CodeSystem();
|
||||
|
@ -170,14 +179,16 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
when(myTermLoaderSvc.loadDeltaAdd(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.r4.model.IdType("CodeSystem/101")));
|
||||
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myCodeSystemFileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-u", "http://foo",
|
||||
"-d", myCodeSystemFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
|
||||
verify(myTermLoaderSvc, times(1)).loadDeltaAdd(eq("http://foo"), myDescriptorListCaptor.capture(), any());
|
||||
|
||||
|
@ -190,7 +201,7 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testDeltaAddInvalidResource(String theFhirVersion) throws IOException {
|
||||
public void testDeltaAddInvalidResource(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||
try (FileWriter w = new FileWriter(myCodeSystemFile, false)) {
|
||||
org.hl7.fhir.dstu3.model.Patient patient = new org.hl7.fhir.dstu3.model.Patient();
|
||||
|
@ -208,14 +219,16 @@ public class UploadTerminologyCommandTest {
|
|||
}
|
||||
|
||||
try {
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myCodeSystemFileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-u", "http://foo",
|
||||
"-d", myCodeSystemFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
fail();
|
||||
} catch (Error e) {
|
||||
assertThat(e.toString(), containsString("HTTP 400 Bad Request: " + Msg.code(362) + "Request has parameter codeSystem of type Patient but method expects type CodeSystem"));
|
||||
|
@ -224,20 +237,23 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testDeltaAddInvalidFileType(String theFhirVersion) throws IOException {
|
||||
public void testDeltaAddInvalidFileType(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
try (FileWriter w = new FileWriter(myTextFileName, false)) {
|
||||
w.append("Help I'm a Bug");
|
||||
}
|
||||
|
||||
try {
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myTextFileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-u", "http://foo",
|
||||
"-d", myTextFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
|
||||
fail();
|
||||
} catch (Error e) {
|
||||
assertThat(e.toString(), containsString("Don't know how to handle file:"));
|
||||
|
@ -246,19 +262,21 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testDeltaAddUsingCompressedFile(String theFhirVersion) throws IOException {
|
||||
public void testDeltaAddUsingCompressedFile(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
writeArchiveFile(myConceptsFile, myHierarchyFile);
|
||||
|
||||
when(myTermLoaderSvc.loadDeltaAdd(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.r4.model.IdType("CodeSystem/101")));
|
||||
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myArchiveFileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-u", "http://foo",
|
||||
"-d", myArchiveFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
|
||||
verify(myTermLoaderSvc, times(1)).loadDeltaAdd(eq("http://foo"), myDescriptorListCaptor.capture(), any());
|
||||
|
||||
|
@ -270,17 +288,20 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testDeltaAddInvalidFileName(String theFhirVersion) throws IOException {
|
||||
public void testDeltaAddInvalidFileName(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
try {
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName + "/foo.csv",
|
||||
"-d", myHierarchyFileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "ADD",
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName + "/foo.csv",
|
||||
"-d", myHierarchyFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
fail();
|
||||
} catch (Error e) {
|
||||
assertThat(e.toString(), Matchers.containsString("FileNotFoundException: target/concepts.csv/foo.csv"));
|
||||
}
|
||||
|
@ -288,7 +309,7 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testDeltaRemove(String theFhirVersion) throws IOException {
|
||||
public void testDeltaRemove(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||
when(myTermLoaderSvc.loadDeltaRemove(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.dstu3.model.IdType("CodeSystem/101")));
|
||||
} else if (FHIR_VERSION_R4.equals(theFhirVersion)) {
|
||||
|
@ -297,15 +318,17 @@ public class UploadTerminologyCommandTest {
|
|||
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||
}
|
||||
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "REMOVE",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName,
|
||||
"-d", myHierarchyFileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "REMOVE",
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName,
|
||||
"-d", myHierarchyFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
|
||||
verify(myTermLoaderSvc, times(1)).loadDeltaRemove(eq("http://foo"), myDescriptorListCaptor.capture(), any());
|
||||
|
||||
|
@ -317,7 +340,7 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testSnapshot(String theFhirVersion) throws IOException {
|
||||
public void testSnapshot(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||
when(myTermLoaderSvc.loadCustom(any(), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.dstu3.model.IdType("CodeSystem/101")));
|
||||
} else if (FHIR_VERSION_R4.equals(theFhirVersion)) {
|
||||
|
@ -326,15 +349,17 @@ public class UploadTerminologyCommandTest {
|
|||
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||
}
|
||||
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "SNAPSHOT",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName,
|
||||
"-d", myHierarchyFileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "SNAPSHOT",
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName,
|
||||
"-d", myHierarchyFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
|
||||
verify(myTermLoaderSvc, times(1)).loadCustom(any(), myDescriptorListCaptor.capture(), any());
|
||||
|
||||
|
@ -346,7 +371,7 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testPropertiesFile(String theFhirVersion) throws IOException {
|
||||
public void testPropertiesFile(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
try (FileWriter w = new FileWriter(myPropertiesFileName, false)) {
|
||||
w.append("a=b\n");
|
||||
}
|
||||
|
@ -359,14 +384,16 @@ public class UploadTerminologyCommandTest {
|
|||
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||
}
|
||||
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "SNAPSHOT",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myPropertiesFileName,
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "SNAPSHOT",
|
||||
"-u", "http://foo",
|
||||
"-d", myPropertiesFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
|
||||
verify(myTermLoaderSvc, times(1)).loadCustom(any(), myDescriptorListCaptor.capture(), any());
|
||||
|
||||
|
@ -378,7 +405,7 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testSnapshotLargeFile(String theFhirVersion) throws IOException {
|
||||
public void testSnapshotLargeFile(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
UploadTerminologyCommand.setTransferSizeLimitForUnitTest(10);
|
||||
|
||||
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||
|
@ -389,15 +416,17 @@ public class UploadTerminologyCommandTest {
|
|||
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||
}
|
||||
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "SNAPSHOT",
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName,
|
||||
"-d", myHierarchyFileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-m", "SNAPSHOT",
|
||||
"-u", "http://foo",
|
||||
"-d", myConceptsFileName,
|
||||
"-d", myHierarchyFileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
|
||||
verify(myTermLoaderSvc, times(1)).loadCustom(any(), myDescriptorListCaptor.capture(), any());
|
||||
|
||||
|
@ -409,7 +438,7 @@ public class UploadTerminologyCommandTest {
|
|||
|
||||
@ParameterizedTest
|
||||
@MethodSource("paramsProvider")
|
||||
public void testUploadICD10UsingCompressedFile(String theFhirVersion) throws IOException {
|
||||
public void testUploadICD10UsingCompressedFile(String theFhirVersion, boolean theIncludeTls) throws IOException {
|
||||
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||
when(myTermLoaderSvc.loadIcd10cm(anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.dstu3.model.IdType("CodeSystem/101")));
|
||||
} else if (FHIR_VERSION_R4.equals(theFhirVersion)) {
|
||||
|
@ -418,13 +447,15 @@ public class UploadTerminologyCommandTest {
|
|||
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||
}
|
||||
|
||||
App.main(new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-t", "http://localhost:" + myPort,
|
||||
"-u", myICD10URL,
|
||||
"-d", myICD10FileName
|
||||
});
|
||||
App.main(myBaseRequestGeneratingCommandTestUtil.createArgs(
|
||||
new String[]{
|
||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||
"-v", theFhirVersion,
|
||||
"-u", myICD10URL,
|
||||
"-d", myICD10FileName
|
||||
},
|
||||
"-t", theIncludeTls, myBaseRestServerHelper
|
||||
));
|
||||
|
||||
verify(myTermLoaderSvc, times(1)).loadIcd10cm(myDescriptorListCaptor.capture(), any());
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
package client;
|
||||
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.rest.client.apache.ApacheRestfulClientFactory;
|
||||
import ca.uhn.fhir.test.BaseFhirVersionParameterizedTest;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class ApacheNativeClientTest extends BaseFhirVersionParameterizedTest {
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("baseParamsProvider")
|
||||
public void testNativeClientHttp(FhirVersionEnum theFhirVersion) {
|
||||
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
|
||||
ApacheRestfulClientFactory clientFactory = new ApacheRestfulClientFactory(fhirVersionParams.getFhirContext());
|
||||
HttpClient client = clientFactory.getNativeHttpClient();
|
||||
|
||||
assertDoesNotThrow(() -> {
|
||||
HttpUriRequest request = new HttpGet(fhirVersionParams.getPatientEndpoint());
|
||||
HttpResponse response = client.execute(request);
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
|
||||
String json = EntityUtils.toString(response.getEntity());
|
||||
IBaseResource bundle = fhirVersionParams.parseResource(json);
|
||||
assertEquals(fhirVersionParams.getFhirVersion(), bundle.getStructureFhirVersionEnum());
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("baseParamsProvider")
|
||||
public void testNativeClientHttps(FhirVersionEnum theFhirVersion) {
|
||||
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
|
||||
ApacheRestfulClientFactory clientFactory = new ApacheRestfulClientFactory(fhirVersionParams.getFhirContext());
|
||||
HttpClient authenticatedClient = clientFactory.getNativeHttpClient(getTlsAuthentication());
|
||||
|
||||
assertDoesNotThrow(() -> {
|
||||
HttpUriRequest request = new HttpGet(fhirVersionParams.getSecuredPatientEndpoint());
|
||||
HttpResponse response = authenticatedClient.execute(request);
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
|
||||
String json = EntityUtils.toString(response.getEntity());
|
||||
IBaseResource bundle = fhirVersionParams.parseResource(json);
|
||||
assertEquals(fhirVersionParams.getFhirVersion(), bundle.getStructureFhirVersionEnum());
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("baseParamsProvider")
|
||||
public void testNativeClientHttpsNoCredentials(FhirVersionEnum theFhirVersion) {
|
||||
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
|
||||
ApacheRestfulClientFactory clientFactory = new ApacheRestfulClientFactory(fhirVersionParams.getFhirContext());
|
||||
HttpClient unauthenticatedClient = clientFactory.getNativeHttpClient();
|
||||
|
||||
assertThrows(SSLHandshakeException.class, () -> {
|
||||
HttpUriRequest request = new HttpGet(fhirVersionParams.getSecuredPatientEndpoint());
|
||||
unauthenticatedClient.execute(request);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -57,6 +57,12 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-structures-r4</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Unit test dependencies -->
|
||||
<dependency>
|
||||
|
|
|
@ -6,9 +6,15 @@ import ca.uhn.fhir.rest.client.api.Header;
|
|||
import ca.uhn.fhir.rest.client.api.IHttpClient;
|
||||
import ca.uhn.fhir.rest.client.impl.RestfulClientFactory;
|
||||
import ca.uhn.fhir.rest.https.TlsAuthentication;
|
||||
import ca.uhn.fhir.rest.https.TlsAuthenticationSvc;
|
||||
import ca.uhn.fhir.rest.https.TrustStoreInfo;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.util.List;
|
||||
|
@ -25,18 +31,18 @@ public class OkHttpRestfulClientFactory extends RestfulClientFactory {
|
|||
|
||||
private Call.Factory myNativeClient;
|
||||
|
||||
public OkHttpRestfulClientFactory() {
|
||||
super();
|
||||
}
|
||||
public OkHttpRestfulClientFactory() {
|
||||
super();
|
||||
}
|
||||
|
||||
public OkHttpRestfulClientFactory(FhirContext theFhirContext) {
|
||||
super(theFhirContext);
|
||||
}
|
||||
public OkHttpRestfulClientFactory(FhirContext theFhirContext) {
|
||||
super(theFhirContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IHttpClient getHttpClient(String theServerBase) {
|
||||
return getHttpClient(theServerBase, Optional.empty());
|
||||
}
|
||||
@Override
|
||||
protected IHttpClient getHttpClient(String theServerBase) {
|
||||
return getHttpClient(theServerBase, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IHttpClient getHttpClient(String theServerBase, Optional<TlsAuthentication> theTlsAuthentication) {
|
||||
|
@ -44,52 +50,70 @@ public class OkHttpRestfulClientFactory extends RestfulClientFactory {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void resetHttpClient() {
|
||||
myNativeClient = null;
|
||||
}
|
||||
protected void resetHttpClient() {
|
||||
myNativeClient = null;
|
||||
}
|
||||
|
||||
public synchronized Call.Factory getNativeClient() {
|
||||
return getNativeClient(Optional.empty());
|
||||
}
|
||||
|
||||
// FIXME ND add authentication
|
||||
public synchronized Call.Factory getNativeClient(Optional<TlsAuthentication> theTlsAuthentication) {
|
||||
if (myNativeClient == null) {
|
||||
myNativeClient = new OkHttpClient()
|
||||
.newBuilder()
|
||||
public synchronized Call.Factory getNativeClient(Optional<TlsAuthentication> theTlsAuthentication) {
|
||||
if (myNativeClient == null) {
|
||||
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
|
||||
.connectTimeout(getConnectTimeout(), TimeUnit.MILLISECONDS)
|
||||
.readTimeout(getSocketTimeout(), TimeUnit.MILLISECONDS)
|
||||
.writeTimeout(getSocketTimeout(), TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
}
|
||||
.readTimeout(getSocketTimeout(), TimeUnit.MILLISECONDS)
|
||||
.writeTimeout(getSocketTimeout(), TimeUnit.MILLISECONDS);
|
||||
|
||||
return myNativeClient;
|
||||
}
|
||||
Optional<SSLContext> optionalSslContext = TlsAuthenticationSvc.createSslContext(theTlsAuthentication);
|
||||
if (optionalSslContext.isPresent()) {
|
||||
SSLContext sslContext = optionalSslContext.get();
|
||||
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
||||
Optional<TrustStoreInfo> trustStoreInfo = theTlsAuthentication.get().getTrustStoreInfo();
|
||||
X509TrustManager trustManager = TlsAuthenticationSvc.createTrustManager(trustStoreInfo);
|
||||
clientBuilder.sslSocketFactory(sslSocketFactory, trustManager);
|
||||
HostnameVerifier hostnameVerifier = TlsAuthenticationSvc.createHostnameVerifier(trustStoreInfo);
|
||||
clientBuilder.hostnameVerifier(hostnameVerifier);
|
||||
}
|
||||
myNativeClient = (Call.Factory) clientBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IHttpClient getHttpClient(StringBuilder theUrl,
|
||||
Map<String, List<String>> theIfNoneExistParams,
|
||||
String theIfNoneExistString,
|
||||
RequestTypeEnum theRequestType,
|
||||
List<Header> theHeaders) {
|
||||
return new OkHttpRestfulClient(getNativeClient(), theUrl, theIfNoneExistParams, theIfNoneExistString, theRequestType, theHeaders);
|
||||
}
|
||||
return myNativeClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only accepts clients of type {@link OkHttpClient}
|
||||
*
|
||||
* @param okHttpClient
|
||||
*/
|
||||
@Override
|
||||
public void setHttpClient(Object okHttpClient) {
|
||||
myNativeClient = (Call.Factory) okHttpClient;
|
||||
}
|
||||
@Override
|
||||
public IHttpClient getHttpClient(StringBuilder theUrl,
|
||||
Map<String, List<String>> theIfNoneExistParams,
|
||||
String theIfNoneExistString,
|
||||
RequestTypeEnum theRequestType,
|
||||
List<Header> theHeaders) {
|
||||
return getHttpClient(theUrl, Optional.empty(), theIfNoneExistParams, theIfNoneExistString, theRequestType, theHeaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProxy(String theHost, Integer thePort) {
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(theHost, thePort));
|
||||
OkHttpClient.Builder builder = ((OkHttpClient)getNativeClient()).newBuilder().proxy(proxy);
|
||||
setHttpClient(builder.build());
|
||||
}
|
||||
@Override
|
||||
public IHttpClient getHttpClient(StringBuilder theUrl,
|
||||
Optional<TlsAuthentication> theTlsAuthentication,
|
||||
Map<String, List<String>> theIfNoneExistParams,
|
||||
String theIfNoneExistString,
|
||||
RequestTypeEnum theRequestType,
|
||||
List<Header> theHeaders) {
|
||||
return new OkHttpRestfulClient(getNativeClient(theTlsAuthentication), theUrl, theIfNoneExistParams, theIfNoneExistString, theRequestType, theHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only accepts clients of type {@link OkHttpClient}
|
||||
*
|
||||
* @param okHttpClient
|
||||
*/
|
||||
@Override
|
||||
public void setHttpClient(Object okHttpClient) {
|
||||
myNativeClient = (Call.Factory) okHttpClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProxy(String theHost, Integer thePort) {
|
||||
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(theHost, thePort));
|
||||
OkHttpClient.Builder builder = ((OkHttpClient) getNativeClient()).newBuilder().proxy(proxy);
|
||||
setHttpClient(builder.build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
package ca.uhn.fhir.okhttp;
|
||||
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.okhttp.client.OkHttpRestfulClientFactory;
|
||||
import ca.uhn.fhir.test.BaseFhirVersionParameterizedTest;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class OkHttpRestfulClientFactoryTest {
|
||||
public class OkHttpRestfulClientFactoryTest extends BaseFhirVersionParameterizedTest {
|
||||
|
||||
private OkHttpRestfulClientFactory clientFactory;
|
||||
|
||||
|
@ -56,4 +68,60 @@ public class OkHttpRestfulClientFactoryTest {
|
|||
|
||||
assertEquals(1516, ((OkHttpClient)clientFactory.getNativeClient()).connectTimeoutMillis());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("baseParamsProvider")
|
||||
public void testNativeClientHttp(FhirVersionEnum theFhirVersion) {
|
||||
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
|
||||
OkHttpRestfulClientFactory clientFactory = new OkHttpRestfulClientFactory(fhirVersionParams.getFhirContext());
|
||||
OkHttpClient client = (OkHttpClient) clientFactory.getNativeClient();
|
||||
|
||||
assertDoesNotThrow(() -> {
|
||||
Request request = new Request.Builder()
|
||||
.url(fhirVersionParams.getPatientEndpoint())
|
||||
.build();
|
||||
|
||||
Response response = client.newCall(request).execute();
|
||||
assertEquals(200, response.code());
|
||||
String json = response.body().string();
|
||||
IBaseResource bundle = fhirVersionParams.getFhirContext().newJsonParser().parseResource(json);
|
||||
assertEquals(fhirVersionParams.getFhirVersion(), bundle.getStructureFhirVersionEnum());
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("baseParamsProvider")
|
||||
public void testNativeClientHttps(FhirVersionEnum theFhirVersion) {
|
||||
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
|
||||
OkHttpRestfulClientFactory clientFactory = new OkHttpRestfulClientFactory(fhirVersionParams.getFhirContext());
|
||||
OkHttpClient authenticatedClient = (OkHttpClient) clientFactory.getNativeClient(getTlsAuthentication());
|
||||
|
||||
assertDoesNotThrow(() -> {
|
||||
Request request = new Request.Builder()
|
||||
.url(fhirVersionParams.getSecuredPatientEndpoint())
|
||||
.build();
|
||||
|
||||
Response response = authenticatedClient.newCall(request).execute();
|
||||
assertEquals(200, response.code());
|
||||
String json = response.body().string();
|
||||
IBaseResource bundle = fhirVersionParams.getFhirContext().newJsonParser().parseResource(json);
|
||||
assertEquals(fhirVersionParams.getFhirVersion(), bundle.getStructureFhirVersionEnum());
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("baseParamsProvider")
|
||||
public void testNativeClientHttpsNoCredentials(FhirVersionEnum theFhirVersion) {
|
||||
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
|
||||
OkHttpRestfulClientFactory clientFactory = new OkHttpRestfulClientFactory(fhirVersionParams.getFhirContext());
|
||||
OkHttpClient unauthenticatedClient = (OkHttpClient) clientFactory.getNativeClient();
|
||||
|
||||
assertThrows(SSLHandshakeException.class, () -> {
|
||||
Request request = new Request.Builder()
|
||||
.url(fhirVersionParams.getSecuredPatientEndpoint())
|
||||
.build();
|
||||
unauthenticatedClient.newCall(request).execute();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,9 +25,8 @@ import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
|||
import ca.uhn.fhir.rest.client.api.Header;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpClient;
|
||||
import ca.uhn.fhir.rest.client.impl.RestfulClientFactory;
|
||||
import ca.uhn.fhir.rest.https.KeyStoreInfo;
|
||||
import ca.uhn.fhir.rest.https.TlsAuthentication;
|
||||
import ca.uhn.fhir.rest.https.TrustStoreInfo;
|
||||
import ca.uhn.fhir.rest.https.TlsAuthenticationSvc;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
|
@ -38,19 +37,13 @@ import org.apache.http.config.Registry;
|
|||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.client.ProxyAuthenticationStrategy;
|
||||
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.ssl.PrivateKeyStrategy;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
@ -65,8 +58,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
*/
|
||||
public class ApacheRestfulClientFactory extends RestfulClientFactory {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ApacheRestfulClientFactory.class);
|
||||
|
||||
private HttpClient myHttpClient;
|
||||
private HttpHost myProxy;
|
||||
|
||||
|
@ -89,8 +80,7 @@ public class ApacheRestfulClientFactory extends RestfulClientFactory {
|
|||
|
||||
@Override
|
||||
protected synchronized ApacheHttpClient getHttpClient(String theServerBase) {
|
||||
return new ApacheHttpClient(getNativeHttpClient(), new StringBuilder(theServerBase),
|
||||
null, null, null, null);
|
||||
return getHttpClient(theServerBase, Optional.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -101,8 +91,15 @@ public class ApacheRestfulClientFactory extends RestfulClientFactory {
|
|||
@Override
|
||||
public synchronized IHttpClient getHttpClient(StringBuilder theUrl, Map<String, List<String>> theIfNoneExistParams,
|
||||
String theIfNoneExistString, RequestTypeEnum theRequestType, List<Header> theHeaders) {
|
||||
return new ApacheHttpClient(getNativeHttpClient(), theUrl, theIfNoneExistParams, theIfNoneExistString, theRequestType,
|
||||
theHeaders);
|
||||
return getHttpClient(theUrl, Optional.empty(), theIfNoneExistParams, theIfNoneExistString, theRequestType, theHeaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized IHttpClient getHttpClient(StringBuilder theUrl, Optional<TlsAuthentication> theTlsAuthentication,
|
||||
Map<String, List<String>> theIfNoneExistParams, String theIfNoneExistString,
|
||||
RequestTypeEnum theRequestType, List<Header> theHeaders) {
|
||||
return new ApacheHttpClient(getNativeHttpClient(theTlsAuthentication), theUrl, theIfNoneExistParams, theIfNoneExistString, theRequestType,
|
||||
theHeaders);
|
||||
}
|
||||
|
||||
public HttpClient getNativeHttpClient() {
|
||||
|
@ -127,9 +124,11 @@ public class ApacheRestfulClientFactory extends RestfulClientFactory {
|
|||
.setDefaultRequestConfig(defaultRequestConfig)
|
||||
.disableCookieManagement();
|
||||
|
||||
SSLConnectionSocketFactory sslConnectionSocketFactory = createSslConnectionSocketFactory(theTlsAuthentication);
|
||||
Optional<SSLContext> optionalSslContext = TlsAuthenticationSvc.createSslContext(theTlsAuthentication);
|
||||
PoolingHttpClientConnectionManager connectionManager;
|
||||
if(sslConnectionSocketFactory != null){
|
||||
if(optionalSslContext.isPresent()){
|
||||
SSLContext sslContext = optionalSslContext.get();
|
||||
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext);
|
||||
builder.setSSLSocketFactory(sslConnectionSocketFactory);
|
||||
Registry<ConnectionSocketFactory> registry = RegistryBuilder
|
||||
.<ConnectionSocketFactory> create()
|
||||
|
@ -162,37 +161,6 @@ public class ApacheRestfulClientFactory extends RestfulClientFactory {
|
|||
return myHttpClient;
|
||||
}
|
||||
|
||||
private SSLConnectionSocketFactory createSslConnectionSocketFactory(Optional<TlsAuthentication> theTlsAuthentication){
|
||||
if(theTlsAuthentication.isEmpty()){
|
||||
return null;
|
||||
}
|
||||
|
||||
try{
|
||||
SSLContextBuilder contextBuilder = SSLContexts.custom();
|
||||
|
||||
TlsAuthentication tlsAuth = theTlsAuthentication.get();
|
||||
if(tlsAuth.getKeyStoreInfo().isPresent()){
|
||||
KeyStoreInfo keyStoreInfo = tlsAuth.getKeyStoreInfo().get();
|
||||
PrivateKeyStrategy privateKeyStrategy = null;
|
||||
if(isNotBlank(keyStoreInfo.getAlias())){
|
||||
privateKeyStrategy = (aliases, socket) -> keyStoreInfo.getAlias();
|
||||
}
|
||||
contextBuilder.loadKeyMaterial(new File(keyStoreInfo.getFilePath()), keyStoreInfo.getStorePass(), keyStoreInfo.getKeyPass(), privateKeyStrategy);
|
||||
}
|
||||
|
||||
if(tlsAuth.getTrustStoreInfo().isPresent()){
|
||||
TrustStoreInfo trustStoreInfo = tlsAuth.getTrustStoreInfo().get();
|
||||
contextBuilder.loadTrustMaterial(new File(trustStoreInfo.getFilePath()), trustStoreInfo.getStorePass(), TrustSelfSignedStrategy.INSTANCE);
|
||||
}
|
||||
|
||||
SSLContext sslContext = contextBuilder.build();
|
||||
return new SSLConnectionSocketFactory(sslContext);
|
||||
}
|
||||
catch (Exception e){
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected HttpClientBuilder getHttpClientBuilder() {
|
||||
return HttpClients.custom();
|
||||
}
|
||||
|
|
|
@ -384,7 +384,9 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory {
|
|||
* Get the http client for the given server base
|
||||
*
|
||||
* @param theServerBase
|
||||
* the server base
|
||||
* the server base
|
||||
* @param theTlsAuthentication
|
||||
* Optional configuration to authenticate HTTPS server requests
|
||||
* @return the http client
|
||||
*/
|
||||
protected abstract IHttpClient getHttpClient(String theServerBase, Optional<TlsAuthentication> theTlsAuthentication);
|
||||
|
|
|
@ -1,39 +1,20 @@
|
|||
package ca.uhn.fhir.jaxrs.client;
|
||||
|
||||
import ca.uhn.fhir.i18n.Msg;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JAX-RS Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.i18n.Msg;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.client.api.Header;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpClient;
|
||||
import ca.uhn.fhir.rest.client.impl.RestfulClientFactory;
|
||||
import ca.uhn.fhir.rest.https.TlsAuthentication;
|
||||
import ca.uhn.fhir.rest.https.TlsAuthenticationSvc;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A Restful Client Factory, based on Jax Rs
|
||||
|
@ -68,24 +49,33 @@ public class JaxRsRestfulClientFactory extends RestfulClientFactory {
|
|||
}
|
||||
|
||||
public synchronized Client getNativeClientClient(Optional<TlsAuthentication> theTlsAuthentication) {
|
||||
//FIXME - add HTTPS
|
||||
if (myNativeClient == null) {
|
||||
ClientBuilder builder = ClientBuilder.newBuilder();
|
||||
Optional<SSLContext> optionalSslContext = TlsAuthenticationSvc.createSslContext(theTlsAuthentication);
|
||||
if(optionalSslContext.isPresent()){
|
||||
SSLContext sslContext = optionalSslContext.get();
|
||||
builder.sslContext(sslContext);
|
||||
}
|
||||
myNativeClient = builder.build();
|
||||
}
|
||||
|
||||
if (registeredComponents != null && !registeredComponents.isEmpty()) {
|
||||
for (Class<?> c : registeredComponents) {
|
||||
myNativeClient = myNativeClient.register(c);
|
||||
}
|
||||
}
|
||||
if (registeredComponents != null && !registeredComponents.isEmpty()) {
|
||||
for (Class<?> c : registeredComponents) {
|
||||
myNativeClient = myNativeClient.register(c);
|
||||
}
|
||||
}
|
||||
|
||||
return myNativeClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized IHttpClient getHttpClient(StringBuilder url, Map<String, List<String>> theIfNoneExistParams, String theIfNoneExistString, RequestTypeEnum theRequestType, List<Header> theHeaders) {
|
||||
Client client = getNativeClientClient();
|
||||
return getHttpClient(url, Optional.empty(), theIfNoneExistParams, theIfNoneExistString, theRequestType, theHeaders);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized IHttpClient getHttpClient(StringBuilder url, Optional<TlsAuthentication> theTlsAuthentication, Map<String, List<String>> theIfNoneExistParams, String theIfNoneExistString, RequestTypeEnum theRequestType, List<Header> theHeaders) {
|
||||
Client client = getNativeClientClient(theTlsAuthentication);
|
||||
return new JaxRsHttpClient(client, url, theIfNoneExistParams, theIfNoneExistString, theRequestType, theHeaders);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,46 @@
|
|||
package ca.uhn.fhir.jaxrs.client;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.test.BaseFhirVersionParameterizedTest;
|
||||
import com.google.common.net.MediaType;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.ws.rs.ProcessingException;
|
||||
import javax.ws.rs.client.Client;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.hasItem;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.core.IsNot.not;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
/**
|
||||
* Created by Sebastien Riviere on 31/07/2017.
|
||||
*/
|
||||
public class JaxRsRestfulClientFactoryTest {
|
||||
public class JaxRsRestfulClientFactoryTest extends BaseFhirVersionParameterizedTest {
|
||||
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(JaxRsRestfulClientFactoryTest.class);
|
||||
private final FhirContext context = FhirContext.forDstu2();
|
||||
private JaxRsRestfulClientFactory factory;
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() throws Exception {
|
||||
factory = new JaxRsRestfulClientFactory(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyConstructorTest() {
|
||||
assertNotNull(new JaxRsRestfulClientFactory());
|
||||
|
@ -52,8 +69,59 @@ public class JaxRsRestfulClientFactoryTest {
|
|||
assertThat(result.getConfiguration().getClasses(), hasItem(ca.uhn.fhir.jaxrs.client.MyFilter.class));
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
factory = new JaxRsRestfulClientFactory(context);
|
||||
@ParameterizedTest
|
||||
@MethodSource("baseParamsProvider")
|
||||
public void testNativeClientHttp(FhirVersionEnum theFhirVersion) {
|
||||
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
|
||||
JaxRsRestfulClientFactory factory = new JaxRsRestfulClientFactory(fhirVersionParams.getFhirContext());
|
||||
Client client = factory.getNativeClientClient();
|
||||
|
||||
assertDoesNotThrow(() -> {
|
||||
Response response = client
|
||||
.target(fhirVersionParams.getPatientEndpoint())
|
||||
.request(MediaType.JSON_UTF_8.toString())
|
||||
.get(Response.class);
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
String json = response.readEntity(String.class);
|
||||
IBaseResource bundle = fhirVersionParams.parseResource(json);
|
||||
assertEquals(fhirVersionParams.getFhirVersion(), bundle.getStructureFhirVersionEnum());
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("baseParamsProvider")
|
||||
public void testNativeClientHttps(FhirVersionEnum theFhirVersion) {
|
||||
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
|
||||
JaxRsRestfulClientFactory factory = new JaxRsRestfulClientFactory(fhirVersionParams.getFhirContext());
|
||||
Client authenticatedClient = factory.getNativeClientClient(getTlsAuthentication());
|
||||
|
||||
assertDoesNotThrow(() -> {
|
||||
Response response = authenticatedClient
|
||||
.target(fhirVersionParams.getSecuredPatientEndpoint())
|
||||
.request(MediaType.JSON_UTF_8.toString())
|
||||
.get(Response.class);
|
||||
|
||||
assertEquals(200, response.getStatus());
|
||||
String json = response.readEntity(String.class);
|
||||
IBaseResource bundle = fhirVersionParams.parseResource(json);
|
||||
assertEquals(fhirVersionParams.getFhirVersion(), bundle.getStructureFhirVersionEnum());
|
||||
});
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("baseParamsProvider")
|
||||
public void testNativeClientHttpsNoCredentials(FhirVersionEnum theFhirVersion) {
|
||||
FhirVersionParams fhirVersionParams = getFhirVersionParams(theFhirVersion);
|
||||
JaxRsRestfulClientFactory factory = new JaxRsRestfulClientFactory(fhirVersionParams.getFhirContext());
|
||||
Client unauthenticatedClient = factory.getNativeClientClient();
|
||||
|
||||
Throwable thrown = assertThrows(ProcessingException.class, () -> {
|
||||
unauthenticatedClient
|
||||
.target(fhirVersionParams.getSecuredPatientEndpoint())
|
||||
.request(MediaType.JSON_UTF_8.toString())
|
||||
.get(Response.class);
|
||||
});
|
||||
assertEquals(SSLHandshakeException.class, thrown.getCause().getClass());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
package ca.uhn.fhir.test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.rest.https.TlsAuthentication;
|
||||
import ca.uhn.fhir.test.utilities.BaseRequestGeneratingCommandTestUtil;
|
||||
import ca.uhn.fhir.test.utilities.BaseRestServerHelper;
|
||||
import ca.uhn.fhir.test.utilities.RestServerDstu3Helper;
|
||||
import ca.uhn.fhir.test.utilities.RestServerR4Helper;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class BaseFhirVersionParameterizedTest {
|
||||
|
||||
@RegisterExtension
|
||||
public final RestServerR4Helper myRestServerR4Helper = new RestServerR4Helper();
|
||||
@RegisterExtension
|
||||
public final RestServerDstu3Helper myRestServerDstu3Helper = new RestServerDstu3Helper();
|
||||
@RegisterExtension
|
||||
public BaseRequestGeneratingCommandTestUtil myBaseRequestGeneratingCommandTestUtil = new BaseRequestGeneratingCommandTestUtil();
|
||||
|
||||
protected final FhirContext myR4FhirContext = FhirContext.forR4();
|
||||
protected final FhirContext myDstu3FhirContext = FhirContext.forDstu3();
|
||||
|
||||
protected static Stream<Arguments> baseParamsProvider(){
|
||||
return Stream.of(
|
||||
Arguments.arguments(FhirVersionEnum.R4),
|
||||
Arguments.arguments(FhirVersionEnum.DSTU3)
|
||||
);
|
||||
}
|
||||
|
||||
protected FhirVersionParams getFhirVersionParams(FhirVersionEnum theFhirVersion){
|
||||
switch(theFhirVersion){
|
||||
case R4:
|
||||
return new FhirVersionParams(myRestServerR4Helper, myR4FhirContext);
|
||||
case DSTU3:
|
||||
return new FhirVersionParams(myRestServerDstu3Helper, myDstu3FhirContext);
|
||||
default:
|
||||
throw new RuntimeException("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||
}
|
||||
}
|
||||
|
||||
protected Optional<TlsAuthentication> getTlsAuthentication(){
|
||||
return myBaseRequestGeneratingCommandTestUtil.getTlsAuthentication();
|
||||
}
|
||||
|
||||
protected class FhirVersionParams {
|
||||
private final BaseRestServerHelper myBaseRestServerHelper;
|
||||
private final FhirContext myFhirContext;
|
||||
private final FhirVersionEnum myFhirVersion;
|
||||
|
||||
public FhirVersionParams(BaseRestServerHelper theBaseRestServerHelper, FhirContext theFhirContext) {
|
||||
myBaseRestServerHelper = theBaseRestServerHelper;
|
||||
myFhirContext = theFhirContext;
|
||||
myFhirVersion = theFhirContext.getVersion().getVersion();
|
||||
}
|
||||
|
||||
public FhirContext getFhirContext() {
|
||||
return myFhirContext;
|
||||
}
|
||||
|
||||
public FhirVersionEnum getFhirVersion() {
|
||||
return myFhirVersion;
|
||||
}
|
||||
|
||||
public String getPatientEndpoint(){
|
||||
return myBaseRestServerHelper.getBase()+"/Patient";
|
||||
}
|
||||
|
||||
public String getSecuredPatientEndpoint(){
|
||||
return myBaseRestServerHelper.getSecureBase()+"/Patient";
|
||||
}
|
||||
|
||||
public IBaseResource parseResource(String json){
|
||||
return myFhirContext.newJsonParser().parseResource(json);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package ca.uhn.fhir.test;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR Test Utilities
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.test.utilities.BaseRestServerHelper;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.google.common.io.Files;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class TlsAuthenticationUtil {
|
||||
|
||||
private TlsAuthenticationUtil(){}
|
||||
|
||||
public static File createTlsAuthenticationFile() {
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
ObjectNode keyStore = mapper.createObjectNode();
|
||||
URL keyStoreUrl = TlsAuthenticationUtil.class.getResource("/tls/client-keystore.p12");
|
||||
|
||||
keyStore.put("filePath", keyStoreUrl.getPath());
|
||||
keyStore.put("storePass", "changeit");
|
||||
keyStore.put("keyPass", "changeit");
|
||||
keyStore.put("alias", "1");
|
||||
|
||||
ObjectNode trustStore = mapper.createObjectNode();
|
||||
URL trustStoreUrl = TlsAuthenticationUtil.class.getResource("/tls/client-truststore.p12");
|
||||
trustStore.put("filePath", trustStoreUrl.getPath());
|
||||
trustStore.put("storePass", "changeit");
|
||||
|
||||
ObjectNode json = mapper.createObjectNode();
|
||||
json.set("keyStore", keyStore);
|
||||
json.set("trustStore", trustStore);
|
||||
|
||||
File tempSourceDir = Files.createTempDir();
|
||||
File inputFile = File.createTempFile("smile-unit-test", ".json", tempSourceDir);
|
||||
try (FileWriter inputFileWriter = new FileWriter(inputFile, StandardCharsets.UTF_8, false)) {
|
||||
IOUtils.write(json.toString(), inputFileWriter);
|
||||
}
|
||||
return inputFile;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package ca.uhn.fhir.test.utilities;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR Test Utilities
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.rest.https.KeyStoreInfo;
|
||||
import ca.uhn.fhir.rest.https.TlsAuthentication;
|
||||
import ca.uhn.fhir.rest.https.TrustStoreInfo;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class BaseRequestGeneratingCommandTestUtil implements AfterEachCallback {
|
||||
|
||||
private static final String KEYSTORE_RESOURCE_PATH = "/tls/client-keystore.p12";
|
||||
private static final String KEYSTORE_STOREPASS = "changeit";
|
||||
private static final String KEYSTORE_KEYPASS = "changeit";
|
||||
private static final String KEYSTORE_ALIAS = "1";
|
||||
|
||||
private static final String TRUSTSTORE_RESOURCE_PATH = "/tls/client-truststore.p12";
|
||||
private static final String TRUSTSTORE_STOREPASS = "changeit";
|
||||
private static final String TRUSTSTORE_ALIAS = "client";
|
||||
|
||||
private final Optional<TlsAuthentication> myTlsAuthentication;
|
||||
private final KeyStoreInfo myKeystoreInfo;
|
||||
private final TrustStoreInfo myTrustStoreInfo;
|
||||
private File myTempFile;
|
||||
|
||||
public BaseRequestGeneratingCommandTestUtil(){
|
||||
String keyStoreFilePath = BaseRequestGeneratingCommandTestUtil.class.getResource(KEYSTORE_RESOURCE_PATH).getPath();
|
||||
myKeystoreInfo = new KeyStoreInfo(keyStoreFilePath, KEYSTORE_STOREPASS, KEYSTORE_KEYPASS, KEYSTORE_ALIAS);
|
||||
|
||||
String trustStoreFilePath = BaseRequestGeneratingCommandTestUtil.class.getResource(TRUSTSTORE_RESOURCE_PATH).getPath();
|
||||
myTrustStoreInfo = new TrustStoreInfo(trustStoreFilePath, TRUSTSTORE_STOREPASS, TRUSTSTORE_ALIAS);
|
||||
|
||||
myTlsAuthentication = Optional.of(new TlsAuthentication(Optional.of(myKeystoreInfo), Optional.of(myTrustStoreInfo)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterEach(ExtensionContext theExtensionContext) throws Exception {
|
||||
if(myTempFile != null && myTempFile.exists()){
|
||||
assertTrue(myTempFile.delete());
|
||||
myTempFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
public String[] createArgs(String[] theBaseArgs, String theUrlFlag, boolean theAddTls, BaseRestServerHelper theRestServerHelper){
|
||||
if(isBlank(theUrlFlag)){
|
||||
return theBaseArgs;
|
||||
}
|
||||
|
||||
int newItems = theAddTls ? 4 : 2;
|
||||
String url = theAddTls ? theRestServerHelper.getSecureBase() : theRestServerHelper.getBase();
|
||||
|
||||
int newSize = theBaseArgs.length + newItems;
|
||||
String[] retVal = Arrays.copyOf(theBaseArgs, newSize);
|
||||
|
||||
retVal[newSize - 2] = theUrlFlag;
|
||||
retVal[newSize - 1] = url;
|
||||
|
||||
if(theAddTls){
|
||||
myTempFile = createTlsAuthenticationFile();
|
||||
retVal[newSize - 4] = "--tls-auth";
|
||||
retVal[newSize - 3] = myTempFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public Optional<TlsAuthentication> getTlsAuthentication(){
|
||||
return myTlsAuthentication;
|
||||
}
|
||||
|
||||
private File createTlsAuthenticationFile() {
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
ObjectNode keyStore = mapper.createObjectNode();
|
||||
keyStore.put("filePath", myKeystoreInfo.getFilePath());
|
||||
keyStore.put("storePass", new String(myKeystoreInfo.getStorePass()));
|
||||
keyStore.put("keyPass", new String(myKeystoreInfo.getKeyPass()));
|
||||
keyStore.put("alias", myKeystoreInfo.getAlias());
|
||||
|
||||
ObjectNode trustStore = mapper.createObjectNode();
|
||||
trustStore.put("filePath", myTrustStoreInfo.getFilePath());
|
||||
trustStore.put("storePass", new String(myTrustStoreInfo.getStorePass()));
|
||||
|
||||
ObjectNode json = mapper.createObjectNode();
|
||||
json.set("keyStore", keyStore);
|
||||
json.set("trustStore", trustStore);
|
||||
|
||||
File inputFile = File.createTempFile("smile-unit-test", ".json");
|
||||
try (FileWriter inputFileWriter = new FileWriter(inputFile, StandardCharsets.UTF_8, false)) {
|
||||
IOUtils.write(json.toString(), inputFileWriter);
|
||||
}
|
||||
return inputFile;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -172,6 +172,8 @@ public abstract class BaseRestServerHelper {
|
|||
|
||||
public abstract IResourceProvider getPatientResourceProvider();
|
||||
|
||||
public abstract IResourceProvider getConceptMapResourceProvider();
|
||||
|
||||
public abstract IIdType createPatientWithId(String theId);
|
||||
|
||||
public abstract IIdType createPatient(IBaseResource theBaseResource);
|
||||
|
|
|
@ -32,6 +32,7 @@ import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
|
|||
import ca.uhn.fhir.rest.server.provider.HashMapResourceProvider;
|
||||
import ca.uhn.test.concurrency.IPointcutLatch;
|
||||
import ca.uhn.test.concurrency.PointcutLatch;
|
||||
import org.hl7.fhir.dstu3.model.ConceptMap;
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
import org.hl7.fhir.dstu3.model.Organization;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
|
@ -52,8 +53,19 @@ public class RestServerDstu3Helper extends BaseRestServerHelper implements IPoin
|
|||
protected final MyRestfulServer myRestServer;
|
||||
|
||||
public RestServerDstu3Helper() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public RestServerDstu3Helper(boolean theInitialize) {
|
||||
super(FhirContext.forDstu3());
|
||||
myRestServer = new MyRestfulServer(myFhirContext);
|
||||
if(theInitialize){
|
||||
try {
|
||||
myRestServer.initialize();
|
||||
} catch (ServletException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -191,6 +203,7 @@ public class RestServerDstu3Helper extends BaseRestServerHelper implements IPoin
|
|||
private HashMapResourceProvider<Patient> myPatientResourceProvider;
|
||||
private HashMapResourceProvider<Observation> myObservationResourceProvider;
|
||||
private HashMapResourceProvider<Organization> myOrganizationResourceProvider;
|
||||
private HashMapResourceProvider<ConceptMap> myConceptMapResourceProvider;
|
||||
private MyPlainProvider myPlainProvider;
|
||||
|
||||
public MyRestfulServer(FhirContext theFhirContext) {
|
||||
|
@ -233,6 +246,10 @@ public class RestServerDstu3Helper extends BaseRestServerHelper implements IPoin
|
|||
return myOrganizationResourceProvider;
|
||||
}
|
||||
|
||||
public HashMapResourceProvider<ConceptMap> getConceptMapResourceProvider() {
|
||||
return myConceptMapResourceProvider;
|
||||
}
|
||||
|
||||
public HashMapResourceProvider<Patient> getPatientResourceProvider() {
|
||||
return myPatientResourceProvider;
|
||||
}
|
||||
|
@ -248,11 +265,21 @@ public class RestServerDstu3Helper extends BaseRestServerHelper implements IPoin
|
|||
registerProvider(myObservationResourceProvider);
|
||||
myOrganizationResourceProvider = new MyHashMapResourceProvider(fhirContext, Organization.class);
|
||||
registerProvider(myOrganizationResourceProvider);
|
||||
myConceptMapResourceProvider = new MyHashMapResourceProvider(fhirContext, ConceptMap.class);
|
||||
registerProvider(myConceptMapResourceProvider);
|
||||
|
||||
myPlainProvider = new MyPlainProvider();
|
||||
registerProvider(myPlainProvider);
|
||||
}
|
||||
|
||||
public void setConceptMapResourceProvider(HashMapResourceProvider<ConceptMap> theResourceProvider) {
|
||||
myConceptMapResourceProvider.getStoredResources().forEach(c -> theResourceProvider.store(c));
|
||||
|
||||
unregisterProvider(myConceptMapResourceProvider);
|
||||
registerProvider(theResourceProvider);
|
||||
myConceptMapResourceProvider = theResourceProvider;
|
||||
}
|
||||
|
||||
|
||||
public class MyHashMapResourceProvider<T extends IBaseResource> extends HashMapResourceProvider<T> {
|
||||
public MyHashMapResourceProvider(FhirContext theContext, Class theType) {
|
||||
|
@ -279,6 +306,11 @@ public class RestServerDstu3Helper extends BaseRestServerHelper implements IPoin
|
|||
return myRestServer.getPatientResourceProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMapResourceProvider<ConceptMap> getConceptMapResourceProvider() {
|
||||
return myRestServer.getConceptMapResourceProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIdType createPatientWithId(String theId) {
|
||||
Patient patient = new Patient();
|
||||
|
@ -305,4 +337,8 @@ public class RestServerDstu3Helper extends BaseRestServerHelper implements IPoin
|
|||
public IIdType createObservation(IBaseResource theBaseResource) {
|
||||
return myRestServer.getObservationResourceProvider().store((Observation) theBaseResource);
|
||||
}
|
||||
|
||||
public void setConceptMapResourceProvider(HashMapResourceProvider<ConceptMap> theResourceProvider) {
|
||||
myRestServer.setConceptMapResourceProvider(theResourceProvider);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.jetty.server.Request;
|
|||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.r4.model.Bundle;
|
||||
import org.hl7.fhir.r4.model.ConceptMap;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.Organization;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
|
@ -58,8 +59,19 @@ public class RestServerR4Helper extends BaseRestServerHelper implements BeforeEa
|
|||
protected final MyRestfulServer myRestServer;
|
||||
|
||||
public RestServerR4Helper() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public RestServerR4Helper(boolean theInitialize) {
|
||||
super(FhirContext.forR4Cached());
|
||||
myRestServer = new MyRestfulServer(myFhirContext);
|
||||
if(theInitialize){
|
||||
try {
|
||||
myRestServer.initialize();
|
||||
} catch (ServletException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -168,6 +180,15 @@ public class RestServerR4Helper extends BaseRestServerHelper implements BeforeEa
|
|||
return myRestServer.getPatientResourceProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMapResourceProvider<ConceptMap> getConceptMapResourceProvider() {
|
||||
return myRestServer.getConceptMapResourceProvider();
|
||||
}
|
||||
|
||||
public void setConceptMapResourceProvider(HashMapResourceProvider<ConceptMap> theResourceProvider) {
|
||||
myRestServer.setConceptMapResourceProvider(theResourceProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IIdType createPatientWithId(String theId) {
|
||||
Patient patient = new Patient();
|
||||
|
@ -224,6 +245,7 @@ public class RestServerR4Helper extends BaseRestServerHelper implements BeforeEa
|
|||
private HashMapResourceProvider<Patient> myPatientResourceProvider;
|
||||
private HashMapResourceProvider<Observation> myObservationResourceProvider;
|
||||
private HashMapResourceProvider<Organization> myOrganizationResourceProvider;
|
||||
private HashMapResourceProvider<ConceptMap> myConceptMapResourceProvider;
|
||||
private RestServerDstu3Helper.MyPlainProvider myPlainProvider;
|
||||
private final List<String> myRequestUrls = Collections.synchronizedList(new ArrayList<>());
|
||||
private final List<String> myRequestVerbs = Collections.synchronizedList(new ArrayList<>());
|
||||
|
@ -292,6 +314,10 @@ public class RestServerR4Helper extends BaseRestServerHelper implements BeforeEa
|
|||
return myOrganizationResourceProvider;
|
||||
}
|
||||
|
||||
public HashMapResourceProvider<ConceptMap> getConceptMapResourceProvider() {
|
||||
return myConceptMapResourceProvider;
|
||||
}
|
||||
|
||||
public HashMapResourceProvider<Patient> getPatientResourceProvider() {
|
||||
return myPatientResourceProvider;
|
||||
}
|
||||
|
@ -307,6 +333,8 @@ public class RestServerR4Helper extends BaseRestServerHelper implements BeforeEa
|
|||
registerProvider(myObservationResourceProvider);
|
||||
myOrganizationResourceProvider = new MyHashMapResourceProvider(fhirContext, Organization.class);
|
||||
registerProvider(myOrganizationResourceProvider);
|
||||
myConceptMapResourceProvider = new MyHashMapResourceProvider(fhirContext, ConceptMap.class);
|
||||
registerProvider(myConceptMapResourceProvider);
|
||||
|
||||
myPlainProvider = new RestServerDstu3Helper.MyPlainProvider();
|
||||
registerProvider(myPlainProvider);
|
||||
|
@ -322,6 +350,14 @@ public class RestServerR4Helper extends BaseRestServerHelper implements BeforeEa
|
|||
myObservationResourceProvider = theResourceProvider;
|
||||
}
|
||||
|
||||
public void setConceptMapResourceProvider(HashMapResourceProvider<ConceptMap> theResourceProvider) {
|
||||
myConceptMapResourceProvider.getStoredResources().forEach(c -> theResourceProvider.store(c));
|
||||
|
||||
unregisterProvider(myConceptMapResourceProvider);
|
||||
registerProvider(theResourceProvider);
|
||||
myConceptMapResourceProvider = theResourceProvider;
|
||||
}
|
||||
|
||||
|
||||
public class MyHashMapResourceProvider<T extends IBaseResource> extends HashMapResourceProvider<T> {
|
||||
public MyHashMapResourceProvider(FhirContext theContext, Class theType) {
|
||||
|
|
Loading…
Reference in New Issue