Merge branch 'master' into 2849_add_new_mdm_param
This commit is contained in:
commit
4cfe11a221
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ public enum VersionEnum {
|
||||||
V5_4_1,
|
V5_4_1,
|
||||||
V5_4_2,
|
V5_4_2,
|
||||||
V5_5_0,
|
V5_5_0,
|
||||||
|
V5_6_0
|
||||||
;
|
;
|
||||||
|
|
||||||
public static VersionEnum latestVersion() {
|
public static VersionEnum latestVersion() {
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-bom</artifactId>
|
<artifactId>hapi-fhir-bom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<name>HAPI FHIR BOM</name>
|
<name>HAPI FHIR BOM</name>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,8 @@ import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.io.input.CountingInputStream;
|
import org.apache.commons.io.input.CountingInputStream;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
import org.hl7.fhir.instance.model.api.IBaseParameters;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.hl7.fhir.instance.model.api.ICompositeType;
|
import org.hl7.fhir.instance.model.api.ICompositeType;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -154,7 +154,7 @@ public class UploadTerminologyCommand extends BaseRequestGeneratingCommand {
|
||||||
throw new ParseException("Could not detect FHIR encoding for file: " + nextDataFile);
|
throw new ParseException("Could not detect FHIR encoding for file: " + nextDataFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
CodeSystem resource = encoding.newParser(myFhirCtx).parseResource(CodeSystem.class, contents);
|
IBaseResource resource = encoding.newParser(myFhirCtx).parseResource(contents);
|
||||||
ParametersUtil.addParameterToParameters(myFhirCtx, inputParameters, TerminologyUploaderProvider.PARAM_CODESYSTEM, resource);
|
ParametersUtil.addParameterToParameters(myFhirCtx, inputParameters, TerminologyUploaderProvider.PARAM_CODESYSTEM, resource);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
package ca.uhn.fhir.cli;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
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.client.api.IGenericClient;
|
||||||
|
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
|
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||||
|
import org.apache.commons.cli.CommandLine;
|
||||||
|
import org.apache.commons.cli.DefaultParser;
|
||||||
|
import org.apache.commons.cli.ParseException;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.hl7.fhir.r4.model.IdType;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.hasItems;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyList;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class HeaderPassthroughOptionTest {
|
||||||
|
final String FHIR_VERSION = "r4";
|
||||||
|
private FhirContext myCtx = FhirContext.forR4();
|
||||||
|
private Server myServer;
|
||||||
|
private int myPort;
|
||||||
|
private final String headerKey1 = "test-header-key-1";
|
||||||
|
private final String headerValue1 = "test header value-1";
|
||||||
|
private static final String myConceptsFileName = "target/concepts.csv";
|
||||||
|
private static File myConceptsFile = new File(myConceptsFileName);
|
||||||
|
private static final String myHierarchyFileName = "target/hierarchy.csv";
|
||||||
|
private static File myHierarchyFile = new File(myHierarchyFileName);
|
||||||
|
private final CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor();
|
||||||
|
private final UploadTerminologyCommand testedCommand =
|
||||||
|
new RequestCapturingUploadTerminologyCommand(myCapturingInterceptor);
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
protected ITermLoaderSvc myTermLoaderSvc;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void beforeEach() throws Exception {
|
||||||
|
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);
|
||||||
|
writeConceptAndHierarchyFiles();
|
||||||
|
when(myTermLoaderSvc.loadCustom(eq("http://foo"), anyList(), any()))
|
||||||
|
.thenReturn(new UploadStatistics(100, new IdType("CodeSystem/101")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void oneHeader() throws Exception {
|
||||||
|
String[] args = new String[] {
|
||||||
|
"-v", FHIR_VERSION,
|
||||||
|
"-m", "SNAPSHOT",
|
||||||
|
"-t", "http://localhost:" + myPort,
|
||||||
|
"-u", "http://foo",
|
||||||
|
"-d", myConceptsFileName,
|
||||||
|
"-d", myHierarchyFileName,
|
||||||
|
"-hp", "\"" + headerKey1 + ":" + headerValue1 + "\""
|
||||||
|
};
|
||||||
|
|
||||||
|
final CommandLine commandLine = new DefaultParser().parse(testedCommand.getOptions(), args, true);
|
||||||
|
testedCommand.run(commandLine);
|
||||||
|
|
||||||
|
assertNotNull(myCapturingInterceptor.getLastRequest());
|
||||||
|
Map<String, List<String>> allHeaders = myCapturingInterceptor.getLastRequest().getAllHeaders();
|
||||||
|
assertFalse(allHeaders.isEmpty());
|
||||||
|
|
||||||
|
assertTrue(allHeaders.containsKey(headerKey1));
|
||||||
|
assertEquals(1, allHeaders.get(headerKey1).size());
|
||||||
|
|
||||||
|
assertThat(allHeaders.get(headerKey1), hasItems(headerValue1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void twoHeadersSameKey() throws Exception {
|
||||||
|
final String headerValue2 = "test header value-2";
|
||||||
|
|
||||||
|
String[] args = new String[] {
|
||||||
|
"-v", FHIR_VERSION,
|
||||||
|
"-m", "SNAPSHOT",
|
||||||
|
"-t", "http://localhost:" + myPort,
|
||||||
|
"-u", "http://foo",
|
||||||
|
"-d", myConceptsFileName,
|
||||||
|
"-d", myHierarchyFileName,
|
||||||
|
"-hp", "\"" + headerKey1 + ":" + headerValue1 + "\"",
|
||||||
|
"-hp", "\"" + headerKey1 + ":" + headerValue2 + "\""
|
||||||
|
};
|
||||||
|
|
||||||
|
final CommandLine commandLine = new DefaultParser().parse(testedCommand.getOptions(), args, true);
|
||||||
|
testedCommand.run(commandLine);
|
||||||
|
|
||||||
|
assertNotNull(myCapturingInterceptor.getLastRequest());
|
||||||
|
Map<String, List<String>> allHeaders = myCapturingInterceptor.getLastRequest().getAllHeaders();
|
||||||
|
assertFalse(allHeaders.isEmpty());
|
||||||
|
assertEquals(2, allHeaders.get(headerKey1).size());
|
||||||
|
|
||||||
|
assertTrue(allHeaders.containsKey(headerKey1));
|
||||||
|
assertEquals(2, allHeaders.get(headerKey1).size());
|
||||||
|
|
||||||
|
assertEquals(headerValue1, allHeaders.get(headerKey1).get(0));
|
||||||
|
assertEquals(headerValue2, allHeaders.get(headerKey1).get(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void twoHeadersDifferentKeys() throws Exception {
|
||||||
|
final String headerKey2 = "test-header-key-2";
|
||||||
|
final String headerValue2 = "test header value-2";
|
||||||
|
|
||||||
|
String[] args = new String[] {
|
||||||
|
"-v", FHIR_VERSION,
|
||||||
|
"-m", "SNAPSHOT",
|
||||||
|
"-t", "http://localhost:" + myPort,
|
||||||
|
"-u", "http://foo",
|
||||||
|
"-d", myConceptsFileName,
|
||||||
|
"-d", myHierarchyFileName,
|
||||||
|
"-hp", "\"" + headerKey1 + ":" + headerValue1 + "\"",
|
||||||
|
"-hp", "\"" + headerKey2 + ":" + headerValue2 + "\""
|
||||||
|
};
|
||||||
|
|
||||||
|
final CommandLine commandLine = new DefaultParser().parse(testedCommand.getOptions(), args, true);
|
||||||
|
testedCommand.run(commandLine);
|
||||||
|
|
||||||
|
assertNotNull(myCapturingInterceptor.getLastRequest());
|
||||||
|
Map<String, List<String>> allHeaders = myCapturingInterceptor.getLastRequest().getAllHeaders();
|
||||||
|
assertFalse(allHeaders.isEmpty());
|
||||||
|
|
||||||
|
assertTrue(allHeaders.containsKey(headerKey1));
|
||||||
|
assertEquals(1, allHeaders.get(headerKey1).size());
|
||||||
|
assertThat(allHeaders.get(headerKey1), hasItems(headerValue1));
|
||||||
|
|
||||||
|
assertTrue(allHeaders.containsKey(headerKey2));
|
||||||
|
assertEquals(1, allHeaders.get(headerKey2).size());
|
||||||
|
assertThat(allHeaders.get(headerKey2), hasItems(headerValue2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void writeConceptAndHierarchyFiles() throws IOException {
|
||||||
|
if (!myConceptsFile.exists()) {
|
||||||
|
try (FileWriter w = new FileWriter(myConceptsFile, false)) {
|
||||||
|
w.append("CODE,DISPLAY\n");
|
||||||
|
w.append("ANIMALS,Animals\n");
|
||||||
|
w.append("CATS,Cats\n");
|
||||||
|
w.append("DOGS,Dogs\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!myHierarchyFile.exists()) {
|
||||||
|
try (FileWriter w = new FileWriter(myHierarchyFile, false)) {
|
||||||
|
w.append("PARENT,CHILD\n");
|
||||||
|
w.append("ANIMALS,CATS\n");
|
||||||
|
w.append("ANIMALS,DOGS\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RequestCapturingUploadTerminologyCommand extends UploadTerminologyCommand {
|
||||||
|
private CapturingInterceptor myCapturingInterceptor;
|
||||||
|
|
||||||
|
public RequestCapturingUploadTerminologyCommand(CapturingInterceptor theCapturingInterceptor) {
|
||||||
|
myCapturingInterceptor = theCapturingInterceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IGenericClient newClient(CommandLine theCommandLine) throws ParseException {
|
||||||
|
IGenericClient client = super.newClient(theCommandLine);
|
||||||
|
client.getInterceptorService().registerInterceptor(myCapturingInterceptor);
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,31 +4,21 @@ import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
|
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
|
||||||
import ca.uhn.fhir.jpa.term.UploadStatistics;
|
import ca.uhn.fhir.jpa.term.UploadStatistics;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
||||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
|
||||||
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
|
|
||||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||||
import ca.uhn.fhir.test.BaseTest;
|
|
||||||
import ca.uhn.fhir.test.utilities.JettyUtil;
|
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||||
import ca.uhn.fhir.test.utilities.server.RestfulServerExtension;
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import org.apache.commons.cli.CommandLine;
|
|
||||||
import org.apache.commons.cli.DefaultParser;
|
|
||||||
import org.apache.commons.cli.ParseException;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.servlet.ServletHandler;
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
|
||||||
import org.hl7.fhir.r4.model.IdType;
|
|
||||||
import org.hl7.fhir.r4.model.Patient;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.TestInfo;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
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.MethodSource;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Captor;
|
import org.mockito.Captor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
@ -41,65 +31,108 @@ import java.io.FileOutputStream;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.stream.Stream;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.CoreMatchers.hasItems;
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.greaterThan;
|
import static org.hamcrest.Matchers.greaterThan;
|
||||||
import static org.hamcrest.Matchers.matchesPattern;
|
import static org.hamcrest.Matchers.matchesPattern;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyList;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.anyList;
|
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class UploadTerminologyCommandTest extends BaseTest {
|
public class UploadTerminologyCommandTest {
|
||||||
|
private static final String FHIR_VERSION_DSTU3 = "DSTU3";
|
||||||
|
private static final String FHIR_VERSION_R4 = "R4";
|
||||||
|
private FhirContext myCtx;
|
||||||
|
private final String myConceptsFileName = "target/concepts.csv";
|
||||||
|
private File myConceptsFile = new File(myConceptsFileName);
|
||||||
|
private final String myHierarchyFileName = "target/hierarchy.csv";
|
||||||
|
private File myHierarchyFile = new File(myHierarchyFileName);
|
||||||
|
private final String myCodeSystemFileName = "target/codesystem.json";
|
||||||
|
private File myCodeSystemFile = new File(myCodeSystemFileName);
|
||||||
|
private final String myTextFileName = "target/hello.txt";
|
||||||
|
private File myTextFile = new File(myTextFileName);
|
||||||
|
private final String myPropertiesFileName = "target/hello.properties";
|
||||||
|
private File myPropertiesFile = new File(myTextFileName);
|
||||||
|
private File myArchiveFile;
|
||||||
|
private String myArchiveFileName;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
protected ArgumentCaptor<List<ITermLoaderSvc.FileDescriptor>> myDescriptorListCaptor;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
System.setProperty("test", "true");
|
System.setProperty("test", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Server myServer;
|
static Stream<String> paramsProvider() {
|
||||||
private FhirContext myCtx = FhirContext.forR4();
|
return Stream.of(FHIR_VERSION_DSTU3, FHIR_VERSION_R4);
|
||||||
@Mock
|
}
|
||||||
private ITermLoaderSvc myTermLoaderSvc;
|
|
||||||
@Captor
|
|
||||||
private ArgumentCaptor<List<ITermLoaderSvc.FileDescriptor>> myDescriptorListCaptor;
|
|
||||||
|
|
||||||
private int myPort;
|
|
||||||
private String myConceptsFileName = "target/concepts.csv";
|
|
||||||
private File myConceptsFile = new File(myConceptsFileName);
|
|
||||||
private String myHierarchyFileName = "target/hierarchy.csv";
|
|
||||||
private File myHierarchyFile = new File(myHierarchyFileName);
|
|
||||||
private String myCodeSystemFileName = "target/codesystem.json";
|
|
||||||
private File myCodeSystemFile = new File(myCodeSystemFileName);
|
|
||||||
private String myTextFileName = "target/hello.txt";
|
|
||||||
private File myTextFile = new File(myTextFileName);
|
|
||||||
private File myArchiveFile;
|
|
||||||
private String myArchiveFileName;
|
|
||||||
private String myPropertiesFileName = "target/hello.properties";
|
|
||||||
private File myPropertiesFile = new File(myTextFileName);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeltaAdd() throws IOException {
|
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void beforeEach(TestInfo testInfo) throws Exception {
|
||||||
writeConceptAndHierarchyFiles();
|
writeConceptAndHierarchyFiles();
|
||||||
|
if (testInfo.getDisplayName().endsWith(FHIR_VERSION_DSTU3)) {
|
||||||
|
myCtx = FhirContext.forDstu3();
|
||||||
|
} else if (testInfo.getDisplayName().endsWith(FHIR_VERSION_R4)) {
|
||||||
|
myCtx = FhirContext.forR4();
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
|
||||||
when(myTermLoaderSvc.loadDeltaAdd(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new IdType("CodeSystem/101")));
|
@AfterEach
|
||||||
|
public void afterEach() throws Exception {
|
||||||
|
JettyUtil.closeServer(myServer);
|
||||||
|
FileUtils.deleteQuietly(myConceptsFile);
|
||||||
|
FileUtils.deleteQuietly(myHierarchyFile);
|
||||||
|
FileUtils.deleteQuietly(myCodeSystemFile);
|
||||||
|
FileUtils.deleteQuietly(myTextFile);
|
||||||
|
FileUtils.deleteQuietly(myArchiveFile);
|
||||||
|
FileUtils.deleteQuietly(myPropertiesFile);
|
||||||
|
UploadTerminologyCommand.setTransferSizeLimitForUnitTest(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("paramsProvider")
|
||||||
|
public void testDeltaAdd(String theFhirVersion) 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)) {
|
||||||
|
when(myTermLoaderSvc.loadDeltaAdd(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.r4.model.IdType("CodeSystem/101")));
|
||||||
|
} else {
|
||||||
|
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||||
|
}
|
||||||
|
|
||||||
App.main(new String[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "ADD",
|
"-m", "ADD",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -115,20 +148,30 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testDeltaAddUsingCodeSystemResource() throws IOException {
|
@MethodSource("paramsProvider")
|
||||||
|
public void testDeltaAddUsingCodeSystemResource(String theFhirVersion) throws IOException {
|
||||||
try (FileWriter w = new FileWriter(myCodeSystemFile, false)) {
|
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||||
CodeSystem cs = new CodeSystem();
|
try (FileWriter w = new FileWriter(myCodeSystemFile, false)) {
|
||||||
cs.addConcept().setCode("CODE").setDisplay("Display");
|
org.hl7.fhir.dstu3.model.CodeSystem cs = new org.hl7.fhir.dstu3.model.CodeSystem();
|
||||||
myCtx.newJsonParser().encodeResourceToWriter(cs, w);
|
cs.addConcept().setCode("CODE").setDisplay("Display");
|
||||||
|
myCtx.newJsonParser().encodeResourceToWriter(cs, w);
|
||||||
|
}
|
||||||
|
} else if (FHIR_VERSION_R4.equals(theFhirVersion)) {
|
||||||
|
try (FileWriter w = new FileWriter(myCodeSystemFile, false)) {
|
||||||
|
org.hl7.fhir.r4.model.CodeSystem cs = new org.hl7.fhir.r4.model.CodeSystem();
|
||||||
|
cs.addConcept().setCode("CODE").setDisplay("Display");
|
||||||
|
myCtx.newJsonParser().encodeResourceToWriter(cs, w);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
when(myTermLoaderSvc.loadDeltaAdd(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new IdType("CodeSystem/101")));
|
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[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "ADD",
|
"-m", "ADD",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -144,19 +187,29 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
assertThat(uploadFile, uploadFile, containsString("\"CODE\",\"Display\""));
|
assertThat(uploadFile, uploadFile, containsString("\"CODE\",\"Display\""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testDeltaAddInvalidResource() throws IOException {
|
@MethodSource("paramsProvider")
|
||||||
|
public void testDeltaAddInvalidResource(String theFhirVersion) throws IOException {
|
||||||
try (FileWriter w = new FileWriter(myCodeSystemFile, false)) {
|
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||||
Patient patient = new Patient();
|
try (FileWriter w = new FileWriter(myCodeSystemFile, false)) {
|
||||||
patient.setActive(true);
|
org.hl7.fhir.dstu3.model.Patient patient = new org.hl7.fhir.dstu3.model.Patient();
|
||||||
myCtx.newJsonParser().encodeResourceToWriter(patient, w);
|
patient.setActive(true);
|
||||||
|
myCtx.newJsonParser().encodeResourceToWriter(patient, w);
|
||||||
|
}
|
||||||
|
} else if (FHIR_VERSION_R4.equals(theFhirVersion)) {
|
||||||
|
try (FileWriter w = new FileWriter(myCodeSystemFile, false)) {
|
||||||
|
org.hl7.fhir.r4.model.Patient patient = new org.hl7.fhir.r4.model.Patient();
|
||||||
|
patient.setActive(true);
|
||||||
|
myCtx.newJsonParser().encodeResourceToWriter(patient, w);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
App.main(new String[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "ADD",
|
"-m", "ADD",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -164,13 +217,13 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
});
|
});
|
||||||
fail();
|
fail();
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
assertThat(e.toString(), containsString("Incorrect resource type found, expected \"CodeSystem\" but found \"Patient\""));
|
assertThat(e.toString(), containsString("HTTP 400 Bad Request: Request has parameter codeSystem of type Patient but method expects type CodeSystem"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testDeltaAddInvalidFileType() throws IOException {
|
@MethodSource("paramsProvider")
|
||||||
|
public void testDeltaAddInvalidFileType(String theFhirVersion) throws IOException {
|
||||||
try (FileWriter w = new FileWriter(myTextFileName, false)) {
|
try (FileWriter w = new FileWriter(myTextFileName, false)) {
|
||||||
w.append("Help I'm a Bug");
|
w.append("Help I'm a Bug");
|
||||||
}
|
}
|
||||||
|
@ -178,7 +231,7 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
try {
|
try {
|
||||||
App.main(new String[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "ADD",
|
"-m", "ADD",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -190,17 +243,16 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testDeltaAddUsingCompressedFile() throws IOException {
|
@MethodSource("paramsProvider")
|
||||||
|
public void testDeltaAddUsingCompressedFile(String theFhirVersion) throws IOException {
|
||||||
writeConceptAndHierarchyFiles();
|
|
||||||
writeArchiveFile(myConceptsFile, myHierarchyFile);
|
writeArchiveFile(myConceptsFile, myHierarchyFile);
|
||||||
|
|
||||||
when(myTermLoaderSvc.loadDeltaAdd(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new IdType("CodeSystem/101")));
|
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[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "ADD",
|
"-m", "ADD",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -215,15 +267,13 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testDeltaAddInvalidFileName() throws IOException {
|
@MethodSource("paramsProvider")
|
||||||
|
public void testDeltaAddInvalidFileName(String theFhirVersion) throws IOException {
|
||||||
writeConceptAndHierarchyFiles();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
App.main(new String[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "ADD",
|
"-m", "ADD",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -235,15 +285,20 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testDeltaRemove() throws IOException {
|
@MethodSource("paramsProvider")
|
||||||
writeConceptAndHierarchyFiles();
|
public void testDeltaRemove(String theFhirVersion) throws IOException {
|
||||||
|
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||||
when(myTermLoaderSvc.loadDeltaRemove(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new IdType("CodeSystem/101")));
|
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)) {
|
||||||
|
when(myTermLoaderSvc.loadDeltaRemove(eq("http://foo"), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.r4.model.IdType("CodeSystem/101")));
|
||||||
|
} else {
|
||||||
|
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||||
|
}
|
||||||
|
|
||||||
App.main(new String[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "REMOVE",
|
"-m", "REMOVE",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -257,21 +312,22 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
assertEquals(1, listOfDescriptors.size());
|
assertEquals(1, listOfDescriptors.size());
|
||||||
assertEquals("file:/files.zip", listOfDescriptors.get(0).getFilename());
|
assertEquals("file:/files.zip", listOfDescriptors.get(0).getFilename());
|
||||||
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testSnapshot() throws IOException {
|
@MethodSource("paramsProvider")
|
||||||
|
public void testSnapshot(String theFhirVersion) 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")));
|
||||||
writeConceptAndHierarchyFiles();
|
} else if (FHIR_VERSION_R4.equals(theFhirVersion)) {
|
||||||
|
when(myTermLoaderSvc.loadCustom(any(), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.r4.model.IdType("CodeSystem/101")));
|
||||||
when(myTermLoaderSvc.loadCustom(any(), anyList(), any())).thenReturn(new UploadStatistics(100, new IdType("CodeSystem/101")));
|
} else {
|
||||||
|
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||||
|
}
|
||||||
|
|
||||||
App.main(new String[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "SNAPSHOT",
|
"-m", "SNAPSHOT",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -287,17 +343,24 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
public void testPropertiesFile() throws IOException {
|
@MethodSource("paramsProvider")
|
||||||
|
public void testPropertiesFile(String theFhirVersion) throws IOException {
|
||||||
try (FileWriter w = new FileWriter(myPropertiesFileName, false)) {
|
try (FileWriter w = new FileWriter(myPropertiesFileName, false)) {
|
||||||
w.append("a=b\n");
|
w.append("a=b\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
when(myTermLoaderSvc.loadCustom(any(), anyList(), any())).thenReturn(new UploadStatistics(100, new IdType("CodeSystem/101")));
|
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)) {
|
||||||
|
when(myTermLoaderSvc.loadCustom(any(), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.r4.model.IdType("CodeSystem/101")));
|
||||||
|
} else {
|
||||||
|
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||||
|
}
|
||||||
|
|
||||||
App.main(new String[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "SNAPSHOT",
|
"-m", "SNAPSHOT",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -310,26 +373,24 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
assertEquals(1, listOfDescriptors.size());
|
assertEquals(1, listOfDescriptors.size());
|
||||||
assertThat(listOfDescriptors.get(0).getFilename(), matchesPattern(".*\\.zip$"));
|
assertThat(listOfDescriptors.get(0).getFilename(), matchesPattern(".*\\.zip$"));
|
||||||
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@ParameterizedTest
|
||||||
* When transferring large files, we use a local file to store the binary instead of
|
@MethodSource("paramsProvider")
|
||||||
* using HTTP to transfer a giant base 64 encoded attachment. Hopefully we can
|
public void testSnapshotLargeFile(String theFhirVersion) throws IOException {
|
||||||
* replace this with a bulk data import at some point when that gets implemented.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testSnapshotLargeFile() throws IOException {
|
|
||||||
UploadTerminologyCommand.setTransferSizeLimitForUnitTest(10);
|
UploadTerminologyCommand.setTransferSizeLimitForUnitTest(10);
|
||||||
|
|
||||||
writeConceptAndHierarchyFiles();
|
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")));
|
||||||
when(myTermLoaderSvc.loadCustom(any(), anyList(), any())).thenReturn(new UploadStatistics(100, new IdType("CodeSystem/101")));
|
} else if (FHIR_VERSION_R4.equals(theFhirVersion)) {
|
||||||
|
when(myTermLoaderSvc.loadCustom(any(), anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.r4.model.IdType("CodeSystem/101")));
|
||||||
|
} else {
|
||||||
|
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||||
|
}
|
||||||
|
|
||||||
App.main(new String[]{
|
App.main(new String[]{
|
||||||
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
"-v", "r4",
|
"-v", theFhirVersion,
|
||||||
"-m", "SNAPSHOT",
|
"-m", "SNAPSHOT",
|
||||||
"-t", "http://localhost:" + myPort,
|
"-t", "http://localhost:" + myPort,
|
||||||
"-u", "http://foo",
|
"-u", "http://foo",
|
||||||
|
@ -345,139 +406,51 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@ParameterizedTest
|
||||||
public class HeaderPassthroughOptionTests {
|
@MethodSource("paramsProvider")
|
||||||
|
public void testUploadICD10UsingCompressedFile(String theFhirVersion) throws IOException {
|
||||||
@RegisterExtension
|
if (FHIR_VERSION_DSTU3.equals(theFhirVersion)) {
|
||||||
public final RestfulServerExtension myRestfulServerExtension = new RestfulServerExtension(myCtx);
|
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)) {
|
||||||
private final String headerKey1 = "test-header-key-1";
|
when(myTermLoaderSvc.loadIcd10cm(anyList(), any())).thenReturn(new UploadStatistics(100, new org.hl7.fhir.r4.model.IdType("CodeSystem/101")));
|
||||||
private final String headerValue1 = "test header value-1";
|
} else {
|
||||||
|
fail("Unknown FHIR Version param provided: " + theFhirVersion);
|
||||||
private final CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor();
|
|
||||||
private final UploadTerminologyCommand testedCommand =
|
|
||||||
new RequestCapturingUploadTerminologyCommand(myCapturingInterceptor);
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void before() {
|
|
||||||
when(myTermLoaderSvc.loadCustom(eq("http://foo"), anyList(), any()))
|
|
||||||
.thenReturn(new UploadStatistics(100, new IdType("CodeSystem/101")));
|
|
||||||
|
|
||||||
TerminologyUploaderProvider provider = new TerminologyUploaderProvider(myCtx, myTermLoaderSvc);
|
|
||||||
myRestfulServerExtension.registerProvider(provider);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App.main(new String[]{
|
||||||
|
UploadTerminologyCommand.UPLOAD_TERMINOLOGY,
|
||||||
|
"-v", theFhirVersion,
|
||||||
|
"-t", "http://localhost:" + myPort,
|
||||||
|
"-u", myICD10URL,
|
||||||
|
"-d", myICD10FileName
|
||||||
|
});
|
||||||
|
|
||||||
@Test
|
verify(myTermLoaderSvc, times(1)).loadIcd10cm(myDescriptorListCaptor.capture(), any());
|
||||||
public void oneHeader() throws Exception {
|
|
||||||
String[] args = new String[] {
|
|
||||||
"-v", "r4",
|
|
||||||
"-m", "SNAPSHOT",
|
|
||||||
"-t", "http://localhost:" + myRestfulServerExtension.getPort(),
|
|
||||||
"-u", "http://foo",
|
|
||||||
"-d", myConceptsFileName,
|
|
||||||
"-d", myHierarchyFileName,
|
|
||||||
"-hp", "\"" + headerKey1 + ":" + headerValue1 + "\""
|
|
||||||
};
|
|
||||||
|
|
||||||
writeConceptAndHierarchyFiles();
|
List<ITermLoaderSvc.FileDescriptor> listOfDescriptors = myDescriptorListCaptor.getValue();
|
||||||
final CommandLine commandLine = new DefaultParser().parse(testedCommand.getOptions(), args, true);
|
assertEquals(1, listOfDescriptors.size());
|
||||||
testedCommand.run(commandLine);
|
assertThat(listOfDescriptors.get(0).getFilename(), matchesPattern("^file:.*files.*\\.zip$"));
|
||||||
|
assertThat(IOUtils.toByteArray(listOfDescriptors.get(0).getInputStream()).length, greaterThan(100));
|
||||||
|
}
|
||||||
|
|
||||||
assertNotNull(myCapturingInterceptor.getLastRequest());
|
private synchronized void writeConceptAndHierarchyFiles() throws IOException {
|
||||||
Map<String, List<String>> allHeaders = myCapturingInterceptor.getLastRequest().getAllHeaders();
|
if (!myConceptsFile.exists()) {
|
||||||
assertFalse(allHeaders.isEmpty());
|
try (FileWriter w = new FileWriter(myConceptsFile, false)) {
|
||||||
|
w.append("CODE,DISPLAY\n");
|
||||||
assertTrue(allHeaders.containsKey(headerKey1));
|
w.append("ANIMALS,Animals\n");
|
||||||
assertEquals(1, allHeaders.get(headerKey1).size());
|
w.append("CATS,Cats\n");
|
||||||
|
w.append("DOGS,Dogs\n");
|
||||||
assertThat(allHeaders.get(headerKey1), hasItems(headerValue1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void twoHeadersSameKey() throws Exception {
|
|
||||||
final String headerValue2 = "test header value-2";
|
|
||||||
|
|
||||||
String[] args = new String[] {
|
|
||||||
"-v", "r4",
|
|
||||||
"-m", "SNAPSHOT",
|
|
||||||
"-t", "http://localhost:" + myRestfulServerExtension.getPort(),
|
|
||||||
"-u", "http://foo",
|
|
||||||
"-d", myConceptsFileName,
|
|
||||||
"-d", myHierarchyFileName,
|
|
||||||
"-hp", "\"" + headerKey1 + ":" + headerValue1 + "\"",
|
|
||||||
"-hp", "\"" + headerKey1 + ":" + headerValue2 + "\""
|
|
||||||
};
|
|
||||||
|
|
||||||
writeConceptAndHierarchyFiles();
|
|
||||||
final CommandLine commandLine = new DefaultParser().parse(testedCommand.getOptions(), args, true);
|
|
||||||
testedCommand.run(commandLine);
|
|
||||||
|
|
||||||
assertNotNull(myCapturingInterceptor.getLastRequest());
|
|
||||||
Map<String, List<String>> allHeaders = myCapturingInterceptor.getLastRequest().getAllHeaders();
|
|
||||||
assertFalse(allHeaders.isEmpty());
|
|
||||||
assertEquals(2, allHeaders.get(headerKey1).size());
|
|
||||||
|
|
||||||
assertTrue(allHeaders.containsKey(headerKey1));
|
|
||||||
assertEquals(2, allHeaders.get(headerKey1).size());
|
|
||||||
|
|
||||||
assertEquals(headerValue1, allHeaders.get(headerKey1).get(0));
|
|
||||||
assertEquals(headerValue2, allHeaders.get(headerKey1).get(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void twoHeadersDifferentKeys() throws Exception {
|
|
||||||
final String headerKey2 = "test-header-key-2";
|
|
||||||
final String headerValue2 = "test header value-2";
|
|
||||||
|
|
||||||
String[] args = new String[] {
|
|
||||||
"-v", "r4",
|
|
||||||
"-m", "SNAPSHOT",
|
|
||||||
"-t", "http://localhost:" + myRestfulServerExtension.getPort(),
|
|
||||||
"-u", "http://foo",
|
|
||||||
"-d", myConceptsFileName,
|
|
||||||
"-d", myHierarchyFileName,
|
|
||||||
"-hp", "\"" + headerKey1 + ":" + headerValue1 + "\"",
|
|
||||||
"-hp", "\"" + headerKey2 + ":" + headerValue2 + "\""
|
|
||||||
};
|
|
||||||
|
|
||||||
writeConceptAndHierarchyFiles();
|
|
||||||
final CommandLine commandLine = new DefaultParser().parse(testedCommand.getOptions(), args, true);
|
|
||||||
testedCommand.run(commandLine);
|
|
||||||
|
|
||||||
assertNotNull(myCapturingInterceptor.getLastRequest());
|
|
||||||
Map<String, List<String>> allHeaders = myCapturingInterceptor.getLastRequest().getAllHeaders();
|
|
||||||
assertFalse(allHeaders.isEmpty());
|
|
||||||
|
|
||||||
assertTrue(allHeaders.containsKey(headerKey1));
|
|
||||||
assertEquals(1, allHeaders.get(headerKey1).size());
|
|
||||||
assertThat(allHeaders.get(headerKey1), hasItems(headerValue1));
|
|
||||||
|
|
||||||
assertTrue(allHeaders.containsKey(headerKey2));
|
|
||||||
assertEquals(1, allHeaders.get(headerKey2).size());
|
|
||||||
assertThat(allHeaders.get(headerKey2), hasItems(headerValue2));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class RequestCapturingUploadTerminologyCommand extends UploadTerminologyCommand {
|
|
||||||
private CapturingInterceptor myCapturingInterceptor;
|
|
||||||
|
|
||||||
public RequestCapturingUploadTerminologyCommand(CapturingInterceptor theCapturingInterceptor) {
|
|
||||||
myCapturingInterceptor = theCapturingInterceptor;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Override
|
if (!myHierarchyFile.exists()) {
|
||||||
protected IGenericClient newClient(CommandLine theCommandLine) throws ParseException {
|
try (FileWriter w = new FileWriter(myHierarchyFile, false)) {
|
||||||
IGenericClient client = super.newClient(theCommandLine);
|
w.append("PARENT,CHILD\n");
|
||||||
client.getInterceptorService().registerInterceptor(myCapturingInterceptor);
|
w.append("ANIMALS,CATS\n");
|
||||||
return client;
|
w.append("ANIMALS,DOGS\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void writeArchiveFile(File... theFiles) throws IOException {
|
private void writeArchiveFile(File... theFiles) throws IOException {
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||||
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream, Charsets.UTF_8);
|
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream, Charsets.UTF_8);
|
||||||
|
@ -485,11 +458,9 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
for (File next : theFiles) {
|
for (File next : theFiles) {
|
||||||
ZipEntry nextEntry = new ZipEntry(UploadTerminologyCommand.stripPath(next.getAbsolutePath()));
|
ZipEntry nextEntry = new ZipEntry(UploadTerminologyCommand.stripPath(next.getAbsolutePath()));
|
||||||
zipOutputStream.putNextEntry(nextEntry);
|
zipOutputStream.putNextEntry(nextEntry);
|
||||||
|
|
||||||
try (FileInputStream fileInputStream = new FileInputStream(next)) {
|
try (FileInputStream fileInputStream = new FileInputStream(next)) {
|
||||||
IOUtils.copy(fileInputStream, zipOutputStream);
|
IOUtils.copy(fileInputStream, zipOutputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zipOutputStream.flush();
|
zipOutputStream.flush();
|
||||||
|
@ -502,54 +473,4 @@ public class UploadTerminologyCommandTest extends BaseTest {
|
||||||
fos.write(byteArrayOutputStream.toByteArray());
|
fos.write(byteArrayOutputStream.toByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void writeConceptAndHierarchyFiles() throws IOException {
|
|
||||||
try (FileWriter w = new FileWriter(myConceptsFile, false)) {
|
|
||||||
w.append("CODE,DISPLAY\n");
|
|
||||||
w.append("ANIMALS,Animals\n");
|
|
||||||
w.append("CATS,Cats\n");
|
|
||||||
w.append("DOGS,Dogs\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
try (FileWriter w = new FileWriter(myHierarchyFile, false)) {
|
|
||||||
w.append("PARENT,CHILD\n");
|
|
||||||
w.append("ANIMALS,CATS\n");
|
|
||||||
w.append("ANIMALS,DOGS\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
public void after() throws Exception {
|
|
||||||
JettyUtil.closeServer(myServer);
|
|
||||||
|
|
||||||
FileUtils.deleteQuietly(myConceptsFile);
|
|
||||||
FileUtils.deleteQuietly(myHierarchyFile);
|
|
||||||
FileUtils.deleteQuietly(myArchiveFile);
|
|
||||||
FileUtils.deleteQuietly(myCodeSystemFile);
|
|
||||||
FileUtils.deleteQuietly(myTextFile);
|
|
||||||
FileUtils.deleteQuietly(myPropertiesFile);
|
|
||||||
|
|
||||||
UploadTerminologyCommand.setTransferSizeLimitForUnitTest(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void before() throws Exception {
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-cli</artifactId>
|
<artifactId>hapi-fhir-cli</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../../hapi-deployable-pom</relativePath>
|
<relativePath>../../hapi-deployable-pom</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 2829
|
||||||
|
title: "Add DSTU3 Support To UploadTerminologyCommand."
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
type: add
|
||||||
|
issue: 2852
|
||||||
|
title: "Replace existing email implementation code with SimpleJavaMail library."
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
type: fix
|
||||||
|
issue: 2876
|
||||||
|
jira: SMILE-1006
|
||||||
|
backport: 5.5.0
|
||||||
|
title: "Fixed a bug wherein an NPE could be thrown by the MDM module interceptor if an incoming resource had a tag with no system."
|
|
@ -69,6 +69,9 @@ public class ChangelogFilesTest {
|
||||||
// this one is optional
|
// this one is optional
|
||||||
fieldNames.remove("backport");
|
fieldNames.remove("backport");
|
||||||
|
|
||||||
|
// this one is optional
|
||||||
|
fieldNames.remove("jira");
|
||||||
|
|
||||||
assertThat("Invalid element in " + next + ": " + fieldNames, fieldNames, empty());
|
assertThat("Invalid element in " + next + ": " + fieldNames, fieldNames, empty());
|
||||||
|
|
||||||
if (haveIssue) {
|
if (haveIssue) {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -410,22 +410,6 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>javax.mail</groupId>
|
|
||||||
<artifactId>javax.mail-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.sun.mail</groupId>
|
|
||||||
<artifactId>javax.mail</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>javax.activation</groupId>
|
|
||||||
<artifactId>activation</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.el</groupId>
|
<groupId>javax.el</groupId>
|
||||||
<artifactId>javax.el-api</artifactId>
|
<artifactId>javax.el-api</artifactId>
|
||||||
|
@ -533,25 +517,19 @@
|
||||||
<artifactId>spring-boot-test</artifactId>
|
<artifactId>spring-boot-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.icegreen</groupId>
|
<groupId>com.icegreen</groupId>
|
||||||
<artifactId>greenmail</artifactId>
|
<artifactId>greenmail</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.sun.mail</groupId>
|
|
||||||
<artifactId>javax.mail</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.icegreen</groupId>
|
<groupId>com.icegreen</groupId>
|
||||||
<artifactId>greenmail-spring</artifactId>
|
<artifactId>greenmail-junit5</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -1056,7 +1056,13 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
for (String nextParamName : comboParamNames) {
|
for (String nextParamName : comboParamNames) {
|
||||||
List<List<IQueryParameterType>> nextValues = theParams.get(nextParamName);
|
List<List<IQueryParameterType>> nextValues = theParams.get(nextParamName);
|
||||||
|
|
||||||
nextParamName = UrlUtil.escapeUrlParam(nextParamName);
|
// TODO Hack to fix weird IOOB on the next stanza until James comes back and makes sense of this.
|
||||||
|
if (nextValues.isEmpty()) {
|
||||||
|
ourLog.error("query parameter {} is unexpectedly empty. Encountered while considering {} index for {}", nextParamName, comboParam.getName(), theRequest.getCompleteUrl());
|
||||||
|
sb = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (nextValues.get(0).size() != 1) {
|
if (nextValues.get(0).size() != 1) {
|
||||||
sb = null;
|
sb = null;
|
||||||
break;
|
break;
|
||||||
|
@ -1083,14 +1089,15 @@ public class SearchBuilder implements ISearchBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nextOrValue = UrlUtil.escapeUrlParam(nextOrValue);
|
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
sb.append('&');
|
sb.append('&');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextParamName = UrlUtil.escapeUrlParam(nextParamName);
|
||||||
|
nextOrValue = UrlUtil.escapeUrlParam(nextOrValue);
|
||||||
|
|
||||||
sb.append(nextParamName).append('=').append(nextOrValue);
|
sb.append(nextParamName).append('=').append(nextOrValue);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,30 +473,23 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
// defaults to true
|
// defaults to true
|
||||||
boolean isMakeVersionCurrent = theRequestDetails == null ||
|
boolean isMakeVersionCurrent = theRequestDetails == null ||
|
||||||
(boolean) theRequestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE);
|
(boolean) theRequestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE);
|
||||||
|
|
||||||
if (isMakeVersionCurrent) {
|
if (isMakeVersionCurrent) {
|
||||||
makeCodeSystemCurrentVersion(codeSystem, codeSystemToStore, conceptsToSave, totalCodeCount);
|
codeSystem.setCurrentVersion(codeSystemToStore);
|
||||||
|
if (codeSystem.getPid() == null) {
|
||||||
|
codeSystem = myCodeSystemDao.saveAndFlush(codeSystem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
ourLog.debug("Setting CodeSystemVersion[{}] on {} concepts...", codeSystem.getPid(), totalCodeCount);
|
||||||
|
for (TermConcept next : conceptsToSave) {
|
||||||
|
populateVersion(next, codeSystemToStore);
|
||||||
private void makeCodeSystemCurrentVersion(TermCodeSystem theCodeSystem, TermCodeSystemVersion theCodeSystemToStore,
|
|
||||||
Collection<TermConcept> theConceptsToSave, int theTotalCodeCount) {
|
|
||||||
|
|
||||||
theCodeSystem.setCurrentVersion(theCodeSystemToStore);
|
|
||||||
if (theCodeSystem.getPid() == null) {
|
|
||||||
theCodeSystem = myCodeSystemDao.saveAndFlush(theCodeSystem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.debug("Setting CodeSystemVersion[{}] on {} concepts...", theCodeSystem.getPid(), theTotalCodeCount);
|
ourLog.debug("Saving {} concepts...", totalCodeCount);
|
||||||
for (TermConcept next : theConceptsToSave) {
|
|
||||||
populateVersion(next, theCodeSystemToStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
ourLog.debug("Saving {} concepts...", theTotalCodeCount);
|
|
||||||
IdentityHashMap<TermConcept, Object> conceptsStack2 = new IdentityHashMap<>();
|
IdentityHashMap<TermConcept, Object> conceptsStack2 = new IdentityHashMap<>();
|
||||||
for (TermConcept next : theConceptsToSave) {
|
for (TermConcept next : conceptsToSave) {
|
||||||
persistChildren(next, theCodeSystemToStore, conceptsStack2, theTotalCodeCount);
|
persistChildren(next, codeSystemToStore, conceptsStack2, totalCodeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.debug("Done saving concepts, flushing to database");
|
ourLog.debug("Done saving concepts, flushing to database");
|
||||||
|
|
|
@ -2,6 +2,7 @@ package ca.uhn.fhir.jpa.term.loinc;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.trimToEmpty;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -54,18 +55,36 @@ public class LoincLinguisticVariantHandler implements IZipContentsHandlerCsv {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addDesignation(theRecord, concept, "COMPONENT");
|
// The following should be created as designations for each term:
|
||||||
addDesignation(theRecord, concept, "PROPERTY");
|
// COMPONENT:PROPERTY:TIME_ASPCT:SYSTEM:SCALE_TYP:METHOD_TYP (as colon-separated concatenation - FormalName)
|
||||||
addDesignation(theRecord, concept, "TIME_ASPCT");
|
// SHORTNAME
|
||||||
addDesignation(theRecord, concept, "SYSTEM");
|
// LONG_COMMON_NAME
|
||||||
addDesignation(theRecord, concept, "SCALE_TYP");
|
// LinguisticVariantDisplayName
|
||||||
|
|
||||||
addDesignation(theRecord, concept, "METHOD_TYP");
|
//-- add formalName designation
|
||||||
addDesignation(theRecord, concept, "CLASS");
|
StringBuilder fullySpecifiedName = new StringBuilder();
|
||||||
|
fullySpecifiedName.append(trimToEmpty(theRecord.get("COMPONENT") + ":"));
|
||||||
|
fullySpecifiedName.append(trimToEmpty(theRecord.get("PROPERTY") + ":"));
|
||||||
|
fullySpecifiedName.append(trimToEmpty(theRecord.get("TIME_ASPCT") + ":"));
|
||||||
|
fullySpecifiedName.append(trimToEmpty(theRecord.get("SYSTEM") + ":"));
|
||||||
|
fullySpecifiedName.append(trimToEmpty(theRecord.get("SCALE_TYP") + ":"));
|
||||||
|
fullySpecifiedName.append(trimToEmpty(theRecord.get("METHOD_TYP")));
|
||||||
|
|
||||||
|
String fullySpecifiedNameStr = fullySpecifiedName.toString();
|
||||||
|
|
||||||
|
// skip if COMPONENT, PROPERTY, TIME_ASPCT, SYSTEM, SCALE_TYP and METHOD_TYP are all empty
|
||||||
|
if (!fullySpecifiedNameStr.equals(":::::")) {
|
||||||
|
concept.addDesignation()
|
||||||
|
.setLanguage(myLanguageCode)
|
||||||
|
.setUseSystem(ITermLoaderSvc.LOINC_URI)
|
||||||
|
.setUseCode("FullySpecifiedName")
|
||||||
|
.setUseDisplay("FullySpecifiedName")
|
||||||
|
.setValue(fullySpecifiedNameStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- other designations
|
||||||
addDesignation(theRecord, concept, "SHORTNAME");
|
addDesignation(theRecord, concept, "SHORTNAME");
|
||||||
addDesignation(theRecord, concept, "LONG_COMMON_NAME");
|
addDesignation(theRecord, concept, "LONG_COMMON_NAME");
|
||||||
addDesignation(theRecord, concept, "RELATEDNAMES2");
|
|
||||||
|
|
||||||
addDesignation(theRecord, concept, "LinguisticVariantDisplayName");
|
addDesignation(theRecord, concept, "LinguisticVariantDisplayName");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
package ca.uhn.fhir.jpa.config;
|
package ca.uhn.fhir.jpa.config;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.search.HapiLuceneAnalysisConfigurer;
|
import ca.uhn.fhir.jpa.search.HapiLuceneAnalysisConfigurer;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailSenderImpl;
|
||||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender;
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.IEmailSender;
|
||||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.JavaMailEmailSender;
|
|
||||||
import ca.uhn.fhir.jpa.util.CircularQueueCaptureQueriesListener;
|
import ca.uhn.fhir.jpa.util.CircularQueueCaptureQueriesListener;
|
||||||
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
|
import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
|
||||||
|
import ca.uhn.fhir.rest.server.mail.MailConfig;
|
||||||
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
import ca.uhn.fhir.validation.ResultSeverityEnum;
|
||||||
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
|
import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder;
|
||||||
import org.apache.commons.dbcp2.BasicDataSource;
|
import org.apache.commons.dbcp2.BasicDataSource;
|
||||||
|
@ -132,10 +133,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public IEmailSender emailSender() {
|
public IEmailSender emailSender() {
|
||||||
JavaMailEmailSender retVal = new JavaMailEmailSender();
|
return new EmailSenderImpl(new MailConfig().setSmtpHostname("localhost").setSmtpPort(3025));
|
||||||
retVal.setSmtpServerHostname("localhost");
|
|
||||||
retVal.setSmtpServerPort(3025);
|
|
||||||
return retVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -702,26 +702,6 @@ public abstract class BaseJpaTest extends BaseTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void waitForSize(int theTarget, Callable<Number> theCallable) throws Exception {
|
|
||||||
waitForSize(theTarget, 10000, theCallable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("BusyWait")
|
|
||||||
public static void waitForSize(int theTarget, int theTimeout, Callable<Number> theCallable) throws Exception {
|
|
||||||
StopWatch sw = new StopWatch();
|
|
||||||
while (theCallable.call().intValue() != theTarget && sw.getMillis() < theTimeout) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(50);
|
|
||||||
} catch (InterruptedException theE) {
|
|
||||||
throw new Error(theE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sw.getMillis() >= theTimeout) {
|
|
||||||
fail("Size " + theCallable.call() + " is != target " + theTarget);
|
|
||||||
}
|
|
||||||
Thread.sleep(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void waitForSize(int theTarget, Callable<Number> theCallable, Callable<String> theFailureMessage) throws Exception {
|
public static void waitForSize(int theTarget, Callable<Number> theCallable, Callable<String> theFailureMessage) throws Exception {
|
||||||
waitForSize(theTarget, 10000, theCallable, theFailureMessage);
|
waitForSize(theTarget, 10000, theCallable, theFailureMessage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,14 @@ package ca.uhn.fhir.jpa.subscription;
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.cache.IResourceChangeListenerCacheRefresher;
|
import ca.uhn.fhir.jpa.cache.IResourceChangeListenerCacheRefresher;
|
||||||
import ca.uhn.fhir.jpa.subscription.channel.impl.LinkedBlockingChannel;
|
import ca.uhn.fhir.jpa.subscription.channel.impl.LinkedBlockingChannel;
|
||||||
import ca.uhn.fhir.jpa.subscription.submit.interceptor.SubscriptionSubmitInterceptorLoader;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelRegistry;
|
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelRegistry;
|
||||||
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelWithHandlers;
|
import ca.uhn.fhir.jpa.subscription.channel.subscription.SubscriptionChannelWithHandlers;
|
||||||
import ca.uhn.fhir.jpa.subscription.submit.interceptor.SubscriptionMatcherInterceptor;
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailSenderImpl;
|
||||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.JavaMailEmailSender;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.SubscriptionDeliveringEmailSubscriber;
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.SubscriptionDeliveringEmailSubscriber;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.match.registry.SubscriptionRegistry;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.submit.interceptor.SubscriptionMatcherInterceptor;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.submit.interceptor.SubscriptionSubmitInterceptorLoader;
|
||||||
import org.hl7.fhir.dstu2.model.Subscription;
|
import org.hl7.fhir.dstu2.model.Subscription;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -18,8 +18,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
public class SubscriptionTestUtil {
|
public class SubscriptionTestUtil {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SubscriptionTestUtil.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SubscriptionTestUtil.class);
|
||||||
|
|
||||||
private JavaMailEmailSender myEmailSender;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DaoConfig myDaoConfig;
|
private DaoConfig myDaoConfig;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -77,21 +75,15 @@ public class SubscriptionTestUtil {
|
||||||
return getExecutorQueueSize();
|
return getExecutorQueueSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initEmailSender(int theListenerPort) {
|
public void setEmailSender(IIdType theIdElement, EmailSenderImpl theEmailSender) {
|
||||||
myEmailSender = new JavaMailEmailSender();
|
|
||||||
myEmailSender.setSmtpServerHostname("localhost");
|
|
||||||
myEmailSender.setSmtpServerPort(theListenerPort);
|
|
||||||
myEmailSender.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEmailSender(IIdType theIdElement) {
|
|
||||||
ActiveSubscription activeSubscription = mySubscriptionRegistry.get(theIdElement.getIdPart());
|
ActiveSubscription activeSubscription = mySubscriptionRegistry.get(theIdElement.getIdPart());
|
||||||
SubscriptionChannelWithHandlers subscriptionChannelWithHandlers = mySubscriptionChannelRegistry.getDeliveryReceiverChannel(activeSubscription.getChannelName());
|
SubscriptionChannelWithHandlers subscriptionChannelWithHandlers = mySubscriptionChannelRegistry.getDeliveryReceiverChannel(activeSubscription.getChannelName());
|
||||||
SubscriptionDeliveringEmailSubscriber subscriber = (SubscriptionDeliveringEmailSubscriber) subscriptionChannelWithHandlers.getDeliveryHandlerForUnitTest();
|
SubscriptionDeliveringEmailSubscriber subscriber = (SubscriptionDeliveringEmailSubscriber) subscriptionChannelWithHandlers.getDeliveryHandlerForUnitTest();
|
||||||
subscriber.setEmailSender(myEmailSender);
|
subscriber.setEmailSender(theEmailSender);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getActiveSubscriptionCount() {
|
public int getActiveSubscriptionCount() {
|
||||||
return mySubscriptionRegistry.size();
|
return mySubscriptionRegistry.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
package ca.uhn.fhir.jpa.subscription.email;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailDetails;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailSenderImpl;
|
||||||
|
import ca.uhn.fhir.rest.server.mail.MailConfig;
|
||||||
|
import com.icegreen.greenmail.junit5.GreenMailExtension;
|
||||||
|
import com.icegreen.greenmail.util.GreenMailUtil;
|
||||||
|
import com.icegreen.greenmail.util.ServerSetupTest;
|
||||||
|
import org.hl7.fhir.dstu3.model.IdType;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.mail.internet.InternetAddress;
|
||||||
|
import javax.mail.internet.MimeMessage;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class EmailSenderImplTest {
|
||||||
|
|
||||||
|
private static final Logger ourLog = LoggerFactory.getLogger(EmailSenderImplTest.class);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static GreenMailExtension ourGreenMail = new GreenMailExtension(ServerSetupTest.SMTP);
|
||||||
|
|
||||||
|
private EmailSenderImpl fixture;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
fixture = new EmailSenderImpl(withMailConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSend() throws Exception {
|
||||||
|
EmailDetails details = new EmailDetails();
|
||||||
|
details.setSubscription(new IdType("Subscription/123"));
|
||||||
|
details.setFrom("foo@example.com ");
|
||||||
|
details.setTo(Arrays.asList(" to1@example.com", "to2@example.com "));
|
||||||
|
details.setSubjectTemplate("test subject");
|
||||||
|
details.setBodyTemplate("foo");
|
||||||
|
fixture.send(details);
|
||||||
|
|
||||||
|
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 1));
|
||||||
|
|
||||||
|
MimeMessage[] messages = ourGreenMail.getReceivedMessages();
|
||||||
|
assertEquals(2, messages.length);
|
||||||
|
final MimeMessage message = messages[0];
|
||||||
|
ourLog.info("Received: " + GreenMailUtil.getWholeMessage(message));
|
||||||
|
assertEquals("test subject", message.getSubject());
|
||||||
|
assertEquals(1, message.getFrom().length);
|
||||||
|
assertEquals("foo@example.com", ((InternetAddress) message.getFrom()[0]).getAddress());
|
||||||
|
assertEquals(2, message.getAllRecipients().length);
|
||||||
|
assertEquals("to1@example.com", ((InternetAddress) message.getAllRecipients()[0]).getAddress());
|
||||||
|
assertEquals("to2@example.com", ((InternetAddress) message.getAllRecipients()[1]).getAddress());
|
||||||
|
assertEquals(1, message.getHeader("Content-Type").length);
|
||||||
|
assertEquals("text/plain; charset=UTF-8", message.getHeader("Content-Type")[0]);
|
||||||
|
String foundBody = GreenMailUtil.getBody(message);
|
||||||
|
assertEquals("foo", foundBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
private MailConfig withMailConfig() {
|
||||||
|
return new MailConfig()
|
||||||
|
.setSmtpHostname(ServerSetupTest.SMTP.getBindAddress())
|
||||||
|
.setSmtpPort(ServerSetupTest.SMTP.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.subscription.email;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.provider.BaseResourceProviderDstu2Test;
|
import ca.uhn.fhir.jpa.provider.BaseResourceProviderDstu2Test;
|
||||||
import ca.uhn.fhir.jpa.subscription.SubscriptionTestUtil;
|
import ca.uhn.fhir.jpa.subscription.SubscriptionTestUtil;
|
||||||
import ca.uhn.fhir.jpa.subscription.match.registry.ActiveSubscription;
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailSenderImpl;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||||
|
@ -11,15 +11,16 @@ import ca.uhn.fhir.model.dstu2.valueset.ObservationStatusEnum;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionChannelTypeEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionChannelTypeEnum;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.SubscriptionStatusEnum;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
import com.icegreen.greenmail.util.GreenMail;
|
import ca.uhn.fhir.rest.server.mail.MailConfig;
|
||||||
|
import com.icegreen.greenmail.junit5.GreenMailExtension;
|
||||||
import com.icegreen.greenmail.util.GreenMailUtil;
|
import com.icegreen.greenmail.util.GreenMailUtil;
|
||||||
import com.icegreen.greenmail.util.ServerSetup;
|
import com.icegreen.greenmail.util.ServerSetupTest;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import static org.awaitility.Awaitility.await;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -29,16 +30,19 @@ import javax.mail.internet.MimeMessage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import static ca.uhn.fhir.jpa.subscription.resthook.RestHookTestDstu3Test.logAllInterceptors;
|
import static ca.uhn.fhir.jpa.subscription.resthook.RestHookTestDstu3Test.logAllInterceptors;
|
||||||
|
import static org.awaitility.Awaitility.await;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
public class EmailSubscriptionDstu2Test extends BaseResourceProviderDstu2Test {
|
public class EmailSubscriptionDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
|
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(EmailSubscriptionDstu2Test.class);
|
private static final Logger ourLog = LoggerFactory.getLogger(EmailSubscriptionDstu2Test.class);
|
||||||
private static GreenMail ourTestSmtp;
|
|
||||||
private static int ourListenerPort;
|
@RegisterExtension
|
||||||
|
static GreenMailExtension ourGreenMail = new GreenMailExtension(ServerSetupTest.SMTP);
|
||||||
|
|
||||||
private List<IIdType> mySubscriptionIds = new ArrayList<>();
|
private List<IIdType> mySubscriptionIds = new ArrayList<>();
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -65,8 +69,6 @@ public class EmailSubscriptionDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
ourLog.info("Before re-registering interceptors");
|
ourLog.info("Before re-registering interceptors");
|
||||||
logAllInterceptors(myInterceptorRegistry);
|
logAllInterceptors(myInterceptorRegistry);
|
||||||
|
|
||||||
mySubscriptionTestUtil.initEmailSender(ourListenerPort);
|
|
||||||
|
|
||||||
mySubscriptionTestUtil.registerEmailInterceptor();
|
mySubscriptionTestUtil.registerEmailInterceptor();
|
||||||
|
|
||||||
ourLog.info("After re-registering interceptors");
|
ourLog.info("After re-registering interceptors");
|
||||||
|
@ -121,51 +123,32 @@ public class EmailSubscriptionDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
Subscription subscription1 = createSubscription(criteria1, payload, "to1@example.com,to2@example.com");
|
Subscription subscription1 = createSubscription(criteria1, payload, "to1@example.com,to2@example.com");
|
||||||
mySubscriptionTestUtil.waitForQueueToDrain();
|
mySubscriptionTestUtil.waitForQueueToDrain();
|
||||||
await().until(()->mySubscriptionRegistry.get(subscription1.getIdElement().getIdPart()), Matchers.not(Matchers.nullValue()));
|
await().until(()->mySubscriptionRegistry.get(subscription1.getIdElement().getIdPart()), Matchers.not(Matchers.nullValue()));
|
||||||
mySubscriptionTestUtil.setEmailSender(subscription1.getIdElement());
|
mySubscriptionTestUtil.setEmailSender(subscription1.getIdElement(), new EmailSenderImpl(withMailConfig()));
|
||||||
assertEquals(0, Arrays.asList(ourTestSmtp.getReceivedMessages()).size());
|
assertEquals(0, Arrays.asList(ourGreenMail.getReceivedMessages()).size());
|
||||||
|
|
||||||
Observation observation1 = sendObservation(code, "SNOMED-CT");
|
Observation observation1 = sendObservation(code, "SNOMED-CT");
|
||||||
|
|
||||||
waitForSize(2, 60000, new Callable<Number>() {
|
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 1));
|
||||||
@Override
|
|
||||||
public Number call() {
|
|
||||||
int length = ourTestSmtp.getReceivedMessages().length;
|
|
||||||
ourLog.trace("Have received {}", length);
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
MimeMessage[] messages = ourTestSmtp.getReceivedMessages();
|
MimeMessage[] messages = ourGreenMail.getReceivedMessages();
|
||||||
assertEquals(2, messages.length);
|
assertEquals(2, messages.length);
|
||||||
int msgIdx = 0;
|
ourLog.info("Received: " + GreenMailUtil.getWholeMessage(messages[0]));
|
||||||
ourLog.info("Received: " + GreenMailUtil.getWholeMessage(messages[msgIdx]));
|
assertEquals("HAPI FHIR Subscriptions", messages[0].getSubject());
|
||||||
assertEquals("HAPI FHIR Subscriptions", messages[msgIdx].getSubject());
|
assertEquals(1, messages[0].getFrom().length);
|
||||||
assertEquals(1, messages[msgIdx].getFrom().length);
|
assertEquals("noreply@unknown.com", ((InternetAddress) messages[0].getFrom()[0]).getAddress());
|
||||||
assertEquals("noreply@unknown.com", ((InternetAddress) messages[msgIdx].getFrom()[0]).getAddress());
|
assertEquals(2, messages[0].getAllRecipients().length);
|
||||||
assertEquals(2, messages[msgIdx].getAllRecipients().length);
|
assertEquals("to1@example.com", ((InternetAddress) messages[0].getAllRecipients()[0]).getAddress());
|
||||||
assertEquals("to1@example.com", ((InternetAddress) messages[msgIdx].getAllRecipients()[0]).getAddress());
|
assertEquals("to2@example.com", ((InternetAddress) messages[0].getAllRecipients()[1]).getAddress());
|
||||||
assertEquals("to2@example.com", ((InternetAddress) messages[msgIdx].getAllRecipients()[1]).getAddress());
|
assertEquals(1, messages[0].getHeader("Content-Type").length);
|
||||||
assertEquals(1, messages[msgIdx].getHeader("Content-Type").length);
|
assertEquals("text/plain; charset=UTF-8", messages[0].getHeader("Content-Type")[0]);
|
||||||
assertEquals("text/plain; charset=us-ascii", messages[msgIdx].getHeader("Content-Type")[0]);
|
String foundBody = GreenMailUtil.getBody(messages[0]);
|
||||||
String foundBody = GreenMailUtil.getBody(messages[msgIdx]);
|
|
||||||
assertEquals("", foundBody);
|
assertEquals("", foundBody);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private MailConfig withMailConfig() {
|
||||||
@AfterAll
|
return new MailConfig()
|
||||||
public static void afterClass() {
|
.setSmtpHostname(ServerSetupTest.SMTP.getBindAddress())
|
||||||
ourTestSmtp.stop();
|
.setSmtpPort(ServerSetupTest.SMTP.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void beforeClass() {
|
|
||||||
ServerSetup smtp = new ServerSetup(0, null, ServerSetup.PROTOCOL_SMTP);
|
|
||||||
smtp.setServerStartupTimeout(2000);
|
|
||||||
ourTestSmtp = new GreenMail(smtp);
|
|
||||||
ourTestSmtp.start();
|
|
||||||
ourListenerPort = ourTestSmtp.getSmtp().getPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@ package ca.uhn.fhir.jpa.subscription.email;
|
||||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||||
import ca.uhn.fhir.jpa.provider.dstu3.BaseResourceProviderDstu3Test;
|
import ca.uhn.fhir.jpa.provider.dstu3.BaseResourceProviderDstu3Test;
|
||||||
import ca.uhn.fhir.jpa.subscription.SubscriptionTestUtil;
|
import ca.uhn.fhir.jpa.subscription.SubscriptionTestUtil;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailSenderImpl;
|
||||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||||
|
import ca.uhn.fhir.rest.server.mail.MailConfig;
|
||||||
import ca.uhn.fhir.util.HapiExtensions;
|
import ca.uhn.fhir.util.HapiExtensions;
|
||||||
|
import com.icegreen.greenmail.junit5.GreenMailExtension;
|
||||||
import com.icegreen.greenmail.store.FolderException;
|
import com.icegreen.greenmail.store.FolderException;
|
||||||
import com.icegreen.greenmail.util.GreenMail;
|
import com.icegreen.greenmail.util.ServerSetupTest;
|
||||||
import com.icegreen.greenmail.util.ServerSetup;
|
|
||||||
import org.hl7.fhir.dstu3.model.Bundle;
|
import org.hl7.fhir.dstu3.model.Bundle;
|
||||||
import org.hl7.fhir.dstu3.model.CodeableConcept;
|
import org.hl7.fhir.dstu3.model.CodeableConcept;
|
||||||
import org.hl7.fhir.dstu3.model.Coding;
|
import org.hl7.fhir.dstu3.model.Coding;
|
||||||
|
@ -15,11 +17,10 @@ import org.hl7.fhir.dstu3.model.Observation;
|
||||||
import org.hl7.fhir.dstu3.model.StringType;
|
import org.hl7.fhir.dstu3.model.StringType;
|
||||||
import org.hl7.fhir.dstu3.model.Subscription;
|
import org.hl7.fhir.dstu3.model.Subscription;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import javax.mail.internet.InternetAddress;
|
import javax.mail.internet.InternetAddress;
|
||||||
|
@ -27,11 +28,11 @@ import javax.mail.internet.MimeMessage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import static ca.uhn.fhir.jpa.subscription.resthook.RestHookTestDstu3Test.logAllInterceptors;
|
import static ca.uhn.fhir.jpa.subscription.resthook.RestHookTestDstu3Test.logAllInterceptors;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the rest-hook subscriptions
|
* Test the rest-hook subscriptions
|
||||||
|
@ -40,11 +41,12 @@ public class EmailSubscriptionDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
|
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(EmailSubscriptionDstu3Test.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(EmailSubscriptionDstu3Test.class);
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static GreenMailExtension ourGreenMail = new GreenMailExtension(ServerSetupTest.SMTP);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SubscriptionTestUtil mySubscriptionTestUtil;
|
private SubscriptionTestUtil mySubscriptionTestUtil;
|
||||||
|
|
||||||
private static int ourListenerPort;
|
|
||||||
private static GreenMail ourTestSmtp;
|
|
||||||
private List<IIdType> mySubscriptionIds = new ArrayList<>();
|
private List<IIdType> mySubscriptionIds = new ArrayList<>();
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
|
@ -68,7 +70,7 @@ public class EmailSubscriptionDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void beforeRegisterEmailListener() throws FolderException {
|
public void beforeRegisterEmailListener() throws FolderException {
|
||||||
ourTestSmtp.purgeEmailFromAllMailboxes();
|
ourGreenMail.purgeEmailFromAllMailboxes();
|
||||||
|
|
||||||
ourLog.info("Before re-registering interceptors");
|
ourLog.info("Before re-registering interceptors");
|
||||||
logAllInterceptors(myInterceptorRegistry);
|
logAllInterceptors(myInterceptorRegistry);
|
||||||
|
@ -78,8 +80,6 @@ public class EmailSubscriptionDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
ourLog.info("After re-registering interceptors");
|
ourLog.info("After re-registering interceptors");
|
||||||
logAllInterceptors(myInterceptorRegistry);
|
logAllInterceptors(myInterceptorRegistry);
|
||||||
|
|
||||||
mySubscriptionTestUtil.initEmailSender(ourListenerPort);
|
|
||||||
|
|
||||||
myDaoConfig.setEmailFromAddress("123@hapifhir.io");
|
myDaoConfig.setEmailFromAddress("123@hapifhir.io");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,24 +133,19 @@ public class EmailSubscriptionDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
String criteria1 = "Observation?code=SNOMED-CT|" + code + "&_format=xml";
|
String criteria1 = "Observation?code=SNOMED-CT|" + code + "&_format=xml";
|
||||||
Subscription subscription = createSubscription(criteria1, payload);
|
Subscription subscription = createSubscription(criteria1, payload);
|
||||||
waitForQueueToDrain();
|
waitForQueueToDrain();
|
||||||
mySubscriptionTestUtil.setEmailSender(subscription.getIdElement());
|
mySubscriptionTestUtil.setEmailSender(subscription.getIdElement(), new EmailSenderImpl(withMailConfig()));
|
||||||
|
|
||||||
sendObservation(code, "SNOMED-CT");
|
sendObservation(code, "SNOMED-CT");
|
||||||
waitForQueueToDrain();
|
waitForQueueToDrain();
|
||||||
|
|
||||||
waitForSize(1, 60000, new Callable<Number>() {
|
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 1));
|
||||||
@Override
|
|
||||||
public Number call() {
|
|
||||||
return ourTestSmtp.getReceivedMessages().length;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<MimeMessage> received = Arrays.asList(ourTestSmtp.getReceivedMessages());
|
List<MimeMessage> received = Arrays.asList(ourGreenMail.getReceivedMessages());
|
||||||
assertEquals(1, received.get(0).getFrom().length);
|
assertEquals(1, received.get(0).getFrom().length);
|
||||||
assertEquals("123@hapifhir.io", ((InternetAddress) received.get(0).getFrom()[0]).getAddress());
|
assertEquals("123@hapifhir.io", ((InternetAddress) received.get(0).getFrom()[0]).getAddress());
|
||||||
assertEquals(1, received.get(0).getAllRecipients().length);
|
assertEquals(1, received.get(0).getAllRecipients().length);
|
||||||
assertEquals("foo@example.com", ((InternetAddress) received.get(0).getAllRecipients()[0]).getAddress());
|
assertEquals("foo@example.com", ((InternetAddress) received.get(0).getAllRecipients()[0]).getAddress());
|
||||||
assertEquals("text/plain; charset=us-ascii", received.get(0).getContentType());
|
assertEquals("text/plain; charset=UTF-8", received.get(0).getContentType());
|
||||||
assertEquals(mySubscriptionIds.get(0).toUnqualifiedVersionless().getValue(), received.get(0).getHeader("X-FHIR-Subscription")[0]);
|
assertEquals(mySubscriptionIds.get(0).toUnqualifiedVersionless().getValue(), received.get(0).getHeader("X-FHIR-Subscription")[0]);
|
||||||
|
|
||||||
// Expect the body of the email subscription to be an Observation formatted as XML
|
// Expect the body of the email subscription to be an Observation formatted as XML
|
||||||
|
@ -185,25 +180,20 @@ public class EmailSubscriptionDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
|
|
||||||
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
||||||
waitForQueueToDrain();
|
waitForQueueToDrain();
|
||||||
mySubscriptionTestUtil.setEmailSender(subscriptionTemp.getIdElement());
|
mySubscriptionTestUtil.setEmailSender(subscriptionTemp.getIdElement(), new EmailSenderImpl(withMailConfig()));
|
||||||
|
|
||||||
sendObservation(code, "SNOMED-CT");
|
sendObservation(code, "SNOMED-CT");
|
||||||
waitForQueueToDrain();
|
waitForQueueToDrain();
|
||||||
|
|
||||||
waitForSize(1, 60000, new Callable<Number>() {
|
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 1));
|
||||||
@Override
|
|
||||||
public Number call() throws Exception {
|
|
||||||
return ourTestSmtp.getReceivedMessages().length;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<MimeMessage> received = Arrays.asList(ourTestSmtp.getReceivedMessages());
|
List<MimeMessage> received = Arrays.asList(ourGreenMail.getReceivedMessages());
|
||||||
assertEquals(1, received.size());
|
assertEquals(1, received.size());
|
||||||
assertEquals(1, received.get(0).getFrom().length);
|
assertEquals(1, received.get(0).getFrom().length);
|
||||||
assertEquals("myfrom@from.com", ((InternetAddress) received.get(0).getFrom()[0]).getAddress());
|
assertEquals("myfrom@from.com", ((InternetAddress) received.get(0).getFrom()[0]).getAddress());
|
||||||
assertEquals(1, received.get(0).getAllRecipients().length);
|
assertEquals(1, received.get(0).getAllRecipients().length);
|
||||||
assertEquals("foo@example.com", ((InternetAddress) received.get(0).getAllRecipients()[0]).getAddress());
|
assertEquals("foo@example.com", ((InternetAddress) received.get(0).getAllRecipients()[0]).getAddress());
|
||||||
assertEquals("text/plain; charset=us-ascii", received.get(0).getContentType());
|
assertEquals("text/plain; charset=UTF-8", received.get(0).getContentType());
|
||||||
assertEquals("This is a subject", received.get(0).getSubject().toString().trim());
|
assertEquals("This is a subject", received.get(0).getSubject().toString().trim());
|
||||||
assertEquals(mySubscriptionIds.get(0).toUnqualifiedVersionless().getValue(), received.get(0).getHeader("X-FHIR-Subscription")[0]);
|
assertEquals(mySubscriptionIds.get(0).toUnqualifiedVersionless().getValue(), received.get(0).getHeader("X-FHIR-Subscription")[0]);
|
||||||
|
|
||||||
|
@ -239,25 +229,20 @@ public class EmailSubscriptionDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
ourLog.info("Subscription ID is: {}", id.getValue());
|
ourLog.info("Subscription ID is: {}", id.getValue());
|
||||||
|
|
||||||
waitForQueueToDrain();
|
waitForQueueToDrain();
|
||||||
mySubscriptionTestUtil.setEmailSender(subscriptionTemp.getIdElement());
|
mySubscriptionTestUtil.setEmailSender(subscriptionTemp.getIdElement(), new EmailSenderImpl(withMailConfig()));
|
||||||
|
|
||||||
sendObservation(code, "SNOMED-CT");
|
sendObservation(code, "SNOMED-CT");
|
||||||
waitForQueueToDrain();
|
waitForQueueToDrain();
|
||||||
|
|
||||||
waitForSize(1, 60000, new Callable<Number>() {
|
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 1));
|
||||||
@Override
|
|
||||||
public Number call() throws Exception {
|
|
||||||
return ourTestSmtp.getReceivedMessages().length;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<MimeMessage> received = Arrays.asList(ourTestSmtp.getReceivedMessages());
|
List<MimeMessage> received = Arrays.asList(ourGreenMail.getReceivedMessages());
|
||||||
assertEquals(1, received.size());
|
assertEquals(1, received.size());
|
||||||
assertEquals(1, received.get(0).getFrom().length);
|
assertEquals(1, received.get(0).getFrom().length);
|
||||||
assertEquals("myfrom@from.com", ((InternetAddress) received.get(0).getFrom()[0]).getAddress());
|
assertEquals("myfrom@from.com", ((InternetAddress) received.get(0).getFrom()[0]).getAddress());
|
||||||
assertEquals(1, received.get(0).getAllRecipients().length);
|
assertEquals(1, received.get(0).getAllRecipients().length);
|
||||||
assertEquals("foo@example.com", ((InternetAddress) received.get(0).getAllRecipients()[0]).getAddress());
|
assertEquals("foo@example.com", ((InternetAddress) received.get(0).getAllRecipients()[0]).getAddress());
|
||||||
assertEquals("text/plain; charset=us-ascii", received.get(0).getContentType());
|
assertEquals("text/plain; charset=UTF-8", received.get(0).getContentType());
|
||||||
assertEquals("This is a subject", received.get(0).getSubject().toString().trim());
|
assertEquals("This is a subject", received.get(0).getSubject().toString().trim());
|
||||||
assertEquals("", received.get(0).getContent().toString().trim());
|
assertEquals("", received.get(0).getContent().toString().trim());
|
||||||
assertEquals(mySubscriptionIds.get(0).toUnqualifiedVersionless().getValue(), received.get(0).getHeader("X-FHIR-Subscription")[0]);
|
assertEquals(mySubscriptionIds.get(0).toUnqualifiedVersionless().getValue(), received.get(0).getHeader("X-FHIR-Subscription")[0]);
|
||||||
|
@ -273,20 +258,11 @@ public class EmailSubscriptionDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
mySubscriptionTestUtil.waitForQueueToDrain();
|
mySubscriptionTestUtil.waitForQueueToDrain();
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterAll
|
private MailConfig withMailConfig() {
|
||||||
public static void afterClass() {
|
return new MailConfig()
|
||||||
ourTestSmtp.stop();
|
.setSmtpHostname(ServerSetupTest.SMTP.getBindAddress())
|
||||||
|
.setSmtpPort(ServerSetupTest.SMTP.getPort());
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void beforeClass() {
|
|
||||||
ServerSetup smtp = new ServerSetup(0, null, ServerSetup.PROTOCOL_SMTP);
|
|
||||||
smtp.setServerStartupTimeout(2000);
|
|
||||||
smtp.setReadTimeout(2000);
|
|
||||||
smtp.setConnectionTimeout(2000);
|
|
||||||
ourTestSmtp = new GreenMail(smtp);
|
|
||||||
ourTestSmtp.start();
|
|
||||||
ourListenerPort = ourTestSmtp.getSmtp().getPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
package ca.uhn.fhir.jpa.subscription.email;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.EmailDetails;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.match.deliver.email.JavaMailEmailSender;
|
|
||||||
import com.icegreen.greenmail.util.GreenMail;
|
|
||||||
import com.icegreen.greenmail.util.GreenMailUtil;
|
|
||||||
import com.icegreen.greenmail.util.ServerSetup;
|
|
||||||
import org.hl7.fhir.dstu3.model.IdType;
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.mail.internet.InternetAddress;
|
|
||||||
import javax.mail.internet.MimeMessage;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
public class JavaMailEmailSenderTest {
|
|
||||||
|
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(JavaMailEmailSenderTest.class);
|
|
||||||
private static GreenMail ourTestSmtp;
|
|
||||||
private static int ourPort;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSend() throws Exception {
|
|
||||||
JavaMailEmailSender sender = new JavaMailEmailSender();
|
|
||||||
sender.setSmtpServerHostname("localhost");
|
|
||||||
sender.setSmtpServerPort(ourPort);
|
|
||||||
sender.setSmtpServerUsername(null);
|
|
||||||
sender.setSmtpServerPassword(null);
|
|
||||||
sender.start();
|
|
||||||
|
|
||||||
String body = "foo";
|
|
||||||
|
|
||||||
EmailDetails details = new EmailDetails();
|
|
||||||
details.setSubscription(new IdType("Subscription/123"));
|
|
||||||
details.setFrom("foo@example.com ");
|
|
||||||
details.setTo(Arrays.asList(" to1@example.com", "to2@example.com "));
|
|
||||||
details.setSubjectTemplate("test subject");
|
|
||||||
details.setBodyTemplate(body);
|
|
||||||
sender.send(details);
|
|
||||||
|
|
||||||
MimeMessage[] messages = ourTestSmtp.getReceivedMessages();
|
|
||||||
assertEquals(2, messages.length);
|
|
||||||
ourLog.info("Received: " + GreenMailUtil.getWholeMessage(messages[0]));
|
|
||||||
assertEquals("test subject", messages[0].getSubject());
|
|
||||||
assertEquals(1, messages[0].getFrom().length);
|
|
||||||
assertEquals("foo@example.com", ((InternetAddress)messages[0].getFrom()[0]).getAddress());
|
|
||||||
assertEquals(2, messages[0].getAllRecipients().length);
|
|
||||||
assertEquals("to1@example.com", ((InternetAddress)messages[0].getAllRecipients()[0]).getAddress());
|
|
||||||
assertEquals("to2@example.com", ((InternetAddress)messages[0].getAllRecipients()[1]).getAddress());
|
|
||||||
assertEquals(1, messages[0].getHeader("Content-Type").length);
|
|
||||||
assertEquals("text/plain; charset=us-ascii", messages[0].getHeader("Content-Type")[0]);
|
|
||||||
String foundBody = GreenMailUtil.getBody(messages[0]);
|
|
||||||
assertEquals("foo", foundBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterAll
|
|
||||||
public static void afterClass() {
|
|
||||||
ourTestSmtp.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeAll
|
|
||||||
public static void beforeClass() {
|
|
||||||
ServerSetup smtp = new ServerSetup(0, null, ServerSetup.PROTOCOL_SMTP);
|
|
||||||
smtp.setServerStartupTimeout(2000);
|
|
||||||
ourTestSmtp = new GreenMail(smtp);
|
|
||||||
ourTestSmtp.start();
|
|
||||||
ourPort = ourTestSmtp.getSmtp().getPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -111,6 +111,77 @@ public class TerminologyLoaderSvcLoincJpaTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadLoincVersionNotCurrent() throws IOException {
|
||||||
|
|
||||||
|
// Load LOINC marked as version 2.67
|
||||||
|
TerminologyLoaderSvcLoincTest.addLoincMandatoryFilesWithPropertiesFileToZip(myFiles, "v267_loincupload.properties");
|
||||||
|
|
||||||
|
mySvc.loadLoinc(myFiles.getFiles(), mySrd);
|
||||||
|
|
||||||
|
myTerminologyDeferredStorageSvc.saveAllDeferred();
|
||||||
|
|
||||||
|
// array just to make it final and populate it into following lambda
|
||||||
|
final TermCodeSystemVersion[] currentCodeSystemVersion_before_loading_v2_68 = new TermCodeSystemVersion[1];
|
||||||
|
|
||||||
|
runInTransaction(() -> {
|
||||||
|
assertEquals(1, myTermCodeSystemDao.count());
|
||||||
|
assertEquals(2, myTermCodeSystemVersionDao.count());
|
||||||
|
assertEquals(24, myTermValueSetDao.count());
|
||||||
|
assertEquals(162, myTermConceptDao.count());
|
||||||
|
assertEquals(12, myTermConceptMapDao.count());
|
||||||
|
assertEquals(38, myResourceTableDao.count());
|
||||||
|
TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri("http://loinc.org");
|
||||||
|
|
||||||
|
TermCodeSystemVersion myTermCodeSystemVersion_versioned =
|
||||||
|
myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2.67");
|
||||||
|
assertNotEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion_versioned.getPid());
|
||||||
|
assertNotEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion_versioned.getResource().getId());
|
||||||
|
|
||||||
|
TermCodeSystemVersion myTermCodeSystemVersion_nonversioned =
|
||||||
|
myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(myTermCodeSystem.getPid());
|
||||||
|
assertEquals(myTermCodeSystem.getCurrentVersion().getPid(), myTermCodeSystemVersion_nonversioned.getPid());
|
||||||
|
assertEquals(myTermCodeSystem.getResource().getId(), myTermCodeSystemVersion_nonversioned.getResource().getId());
|
||||||
|
|
||||||
|
// current should be null loaded after 2.67
|
||||||
|
currentCodeSystemVersion_before_loading_v2_68[0] =
|
||||||
|
myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(myTermCodeSystem.getPid());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load LOINC marked as version 2.68 and not making it current (so 2.67 should remain current)
|
||||||
|
myFiles = new ZipCollectionBuilder();
|
||||||
|
TerminologyLoaderSvcLoincTest.addLoincMandatoryFilesWithPropertiesFileToZip(
|
||||||
|
myFiles, "v268_curr_false_loincupload.properties");
|
||||||
|
mySvc.loadLoinc(myFiles.getFiles(), mySrd);
|
||||||
|
myTerminologyDeferredStorageSvc.saveAllDeferred();
|
||||||
|
|
||||||
|
runInTransaction(() -> {
|
||||||
|
assertEquals(1, myTermCodeSystemDao.count());
|
||||||
|
assertEquals(3, myTermCodeSystemVersionDao.count());
|
||||||
|
assertEquals(36, myTermValueSetDao.count());
|
||||||
|
assertEquals(243, myTermConceptDao.count());
|
||||||
|
assertEquals(18, myTermConceptMapDao.count());
|
||||||
|
assertEquals(57, myResourceTableDao.count());
|
||||||
|
TermCodeSystem myTermCodeSystem = myTermCodeSystemDao.findByCodeSystemUri("http://loinc.org");
|
||||||
|
|
||||||
|
TermCodeSystemVersion currentCodeSystemVersion_after_loading_v2_68 =
|
||||||
|
myTermCodeSystemVersionDao.findByCodeSystemPidVersionIsNull(myTermCodeSystem.getPid());
|
||||||
|
|
||||||
|
// current should be same as before loading 2.68
|
||||||
|
assertEquals(currentCodeSystemVersion_before_loading_v2_68[0].getPid(), currentCodeSystemVersion_after_loading_v2_68.getPid());
|
||||||
|
|
||||||
|
TermCodeSystemVersion termCodeSystemVersion_267 =
|
||||||
|
myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2.67");
|
||||||
|
assertNotEquals(myTermCodeSystem.getCurrentVersion().getPid(), termCodeSystemVersion_267.getPid());
|
||||||
|
|
||||||
|
TermCodeSystemVersion termCodeSystemVersion_268 =
|
||||||
|
myTermCodeSystemVersionDao.findByCodeSystemPidAndVersion(myTermCodeSystem.getPid(), "2.68");
|
||||||
|
assertNotEquals(myTermCodeSystem.getCurrentVersion().getPid(), termCodeSystemVersion_268.getPid());
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loinc distro includes loinc.xml as of 2.70
|
* Loinc distro includes loinc.xml as of 2.70
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -478,13 +478,13 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
||||||
// Consumer Name
|
// Consumer Name
|
||||||
if (theIncludeConsumerNameAndLinguisticVariants) {
|
if (theIncludeConsumerNameAndLinguisticVariants) {
|
||||||
code = concepts.get("61438-8");
|
code = concepts.get("61438-8");
|
||||||
assertEquals(28, code.getDesignations().size());
|
assertEquals(8, code.getDesignations().size());
|
||||||
verifyConsumerName(code.getDesignations(), "Consumer Name 61438-8");
|
verifyConsumerName(code.getDesignations(), "Consumer Name 61438-8");
|
||||||
verifyLinguisticVariant(code.getDesignations(), "de-AT", "Entlassungsbrief Ärztlich","Ergebnis","Zeitpunkt","{Setting}","Dokument","Dermatologie","DOC.ONTOLOGY","de shortname","de long common name","de related names 2","de linguistic variant display name");
|
verifyLinguisticVariant(code.getDesignations(), "de-AT", "Entlassungsbrief Ärztlich","Ergebnis","Zeitpunkt","{Setting}","Dokument","Dermatologie","DOC.ONTOLOGY","de shortname","de long common name","de related names 2","de linguistic variant display name");
|
||||||
verifyLinguisticVariant(code.getDesignations(), "fr-CA", "Cellules de Purkinje cytoplasmique type 2 , IgG","Titre","Temps ponctuel","Sérum","Quantitatif","Immunofluorescence","Sérologie","","","","");
|
verifyLinguisticVariant(code.getDesignations(), "fr-CA", "Cellules de Purkinje cytoplasmique type 2 , IgG","Titre","Temps ponctuel","Sérum","Quantitatif","Immunofluorescence","Sérologie","","","","");
|
||||||
verifyLinguisticVariant(code.getDesignations(), "zh-CN", "血流速度.收缩期.最大值","速度","时间点","大脑中动脉","定量型","超声.多普勒","产科学检查与测量指标.超声","","", "Cereb 动态 可用数量表示的;定量性;数值型;数量型;连续数值型标尺 大脑(Cerebral) 时刻;随机;随意;瞬间 术语\"cerebral\"指的是主要由中枢半球(大脑皮质和基底神经节)组成的那部分脑结构 流 流量;流速;流体 血;全血 血流量;血液流量 速度(距离/时间);速率;速率(距离/时间)","");
|
verifyLinguisticVariant(code.getDesignations(), "zh-CN", "血流速度.收缩期.最大值","速度","时间点","大脑中动脉","定量型","超声.多普勒","产科学检查与测量指标.超声","","", "Cereb 动态 可用数量表示的;定量性;数值型;数量型;连续数值型标尺 大脑(Cerebral) 时刻;随机;随意;瞬间 术语\"cerebral\"指的是主要由中枢半球(大脑皮质和基底神经节)组成的那部分脑结构 流 流量;流速;流体 血;全血 血流量;血液流量 速度(距离/时间);速率;速率(距离/时间)","");
|
||||||
code = concepts.get("17787-3");
|
code = concepts.get("17787-3");
|
||||||
assertEquals(19, code.getDesignations().size());
|
assertEquals(5, code.getDesignations().size());
|
||||||
verifyConsumerName(code.getDesignations(), "Consumer Name 17787-3");
|
verifyConsumerName(code.getDesignations(), "Consumer Name 17787-3");
|
||||||
verifyLinguisticVariant(code.getDesignations(), "de-AT", "","","","","","","","","","CoV OC43 RNA ql/SM P","Coronavirus OC43 RNA ql. /Sondermaterial PCR");
|
verifyLinguisticVariant(code.getDesignations(), "de-AT", "","","","","","","","","","CoV OC43 RNA ql/SM P","Coronavirus OC43 RNA ql. /Sondermaterial PCR");
|
||||||
verifyLinguisticVariant(code.getDesignations(), "fr-CA", "Virus respiratoire syncytial bovin","Présence-Seuil","Temps ponctuel","XXX","Ordinal","Culture spécifique à un microorganisme","Microbiologie","","","","");
|
verifyLinguisticVariant(code.getDesignations(), "fr-CA", "Virus respiratoire syncytial bovin","Présence-Seuil","Temps ponctuel","XXX","Ordinal","Culture spécifique à un microorganisme","Microbiologie","","","","");
|
||||||
|
@ -958,67 +958,35 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
||||||
String methodType, String theClass, String theShortName, String theLongCommonName, String theRelatedName2,
|
String methodType, String theClass, String theShortName, String theLongCommonName, String theRelatedName2,
|
||||||
String theLinguisticVariantDisplayName) {
|
String theLinguisticVariantDisplayName) {
|
||||||
|
|
||||||
TermConceptDesignation componentDes = null;
|
TermConceptDesignation formalNameDes = null;
|
||||||
TermConceptDesignation propertyDes = null;
|
|
||||||
TermConceptDesignation timeAspctDes = null;
|
|
||||||
TermConceptDesignation systemDes = null;
|
|
||||||
TermConceptDesignation scaleTypDes = null;
|
|
||||||
|
|
||||||
TermConceptDesignation methodTypDes = null;
|
|
||||||
TermConceptDesignation classDes = null;
|
|
||||||
TermConceptDesignation shortNameDes = null;
|
TermConceptDesignation shortNameDes = null;
|
||||||
TermConceptDesignation longCommonNameDes = null;
|
TermConceptDesignation longCommonNameDes = null;
|
||||||
TermConceptDesignation relatedNames2Des = null;
|
|
||||||
|
|
||||||
TermConceptDesignation linguisticVariantDisplayNameDes = null;
|
TermConceptDesignation linguisticVariantDisplayNameDes = null;
|
||||||
|
|
||||||
for (TermConceptDesignation designation : designationList) {
|
for (TermConceptDesignation designation : designationList) {
|
||||||
if (theLanguage.equals(designation.getLanguage())) {
|
if (theLanguage.equals(designation.getLanguage())) {
|
||||||
|
|
||||||
if ("COMPONENT".equals(designation.getUseDisplay()))
|
if ("FullySpecifiedName".equals(designation.getUseDisplay()))
|
||||||
componentDes = designation;
|
formalNameDes = designation;
|
||||||
if ("PROPERTY".equals(designation.getUseDisplay()))
|
|
||||||
propertyDes = designation;
|
|
||||||
if ("TIME_ASPCT".equals(designation.getUseDisplay()))
|
|
||||||
timeAspctDes = designation;
|
|
||||||
if ("SYSTEM".equals(designation.getUseDisplay()))
|
|
||||||
systemDes = designation;
|
|
||||||
if ("SCALE_TYP".equals(designation.getUseDisplay()))
|
|
||||||
scaleTypDes = designation;
|
|
||||||
|
|
||||||
if ("METHOD_TYP".equals(designation.getUseDisplay()))
|
|
||||||
methodTypDes = designation;
|
|
||||||
if ("CLASS".equals(designation.getUseDisplay()))
|
|
||||||
classDes = designation;
|
|
||||||
if ("SHORTNAME".equals(designation.getUseDisplay()))
|
if ("SHORTNAME".equals(designation.getUseDisplay()))
|
||||||
shortNameDes = designation;
|
shortNameDes = designation;
|
||||||
if ("LONG_COMMON_NAME".equals(designation.getUseDisplay()))
|
if ("LONG_COMMON_NAME".equals(designation.getUseDisplay()))
|
||||||
longCommonNameDes = designation;
|
longCommonNameDes = designation;
|
||||||
if ("RELATEDNAMES2".equals(designation.getUseDisplay()))
|
|
||||||
relatedNames2Des = designation;
|
|
||||||
|
|
||||||
if ("LinguisticVariantDisplayName".equals(designation.getUseDisplay()))
|
if ("LinguisticVariantDisplayName".equals(designation.getUseDisplay()))
|
||||||
linguisticVariantDisplayNameDes = designation;
|
linguisticVariantDisplayNameDes = designation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
verifyDesignation(componentDes, ITermLoaderSvc.LOINC_URI, "COMPONENT", theComponent);
|
|
||||||
verifyDesignation(propertyDes, ITermLoaderSvc.LOINC_URI, "PROPERTY", theProperty);
|
|
||||||
verifyDesignation(timeAspctDes, ITermLoaderSvc.LOINC_URI, "TIME_ASPCT", theTimeAspct);
|
|
||||||
verifyDesignation(systemDes, ITermLoaderSvc.LOINC_URI, "SYSTEM", theSystem);
|
|
||||||
verifyDesignation(scaleTypDes, ITermLoaderSvc.LOINC_URI, "SCALE_TYP", theScaleTyp);
|
|
||||||
|
|
||||||
verifyDesignation(methodTypDes, ITermLoaderSvc.LOINC_URI, "METHOD_TYP", methodType);
|
verifyDesignation(formalNameDes, ITermLoaderSvc.LOINC_URI, "FullySpecifiedName", theComponent+":"+theProperty+":"+theTimeAspct+":"+theSystem+":"+theScaleTyp+":"+methodType);
|
||||||
verifyDesignation(classDes, ITermLoaderSvc.LOINC_URI, "CLASS", theClass);
|
|
||||||
verifyDesignation(shortNameDes, ITermLoaderSvc.LOINC_URI, "SHORTNAME", theShortName);
|
verifyDesignation(shortNameDes, ITermLoaderSvc.LOINC_URI, "SHORTNAME", theShortName);
|
||||||
verifyDesignation(longCommonNameDes, ITermLoaderSvc.LOINC_URI, "LONG_COMMON_NAME", theLongCommonName);
|
verifyDesignation(longCommonNameDes, ITermLoaderSvc.LOINC_URI, "LONG_COMMON_NAME", theLongCommonName);
|
||||||
verifyDesignation(relatedNames2Des, ITermLoaderSvc.LOINC_URI, "RELATEDNAMES2", theRelatedName2);
|
|
||||||
|
|
||||||
verifyDesignation(linguisticVariantDisplayNameDes, ITermLoaderSvc.LOINC_URI, "LinguisticVariantDisplayName", theLinguisticVariantDisplayName);
|
verifyDesignation(linguisticVariantDisplayNameDes, ITermLoaderSvc.LOINC_URI, "LinguisticVariantDisplayName", theLinguisticVariantDisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void verifyDesignation(TermConceptDesignation theDesignation, String theUseSystem, String theUseCode, String theValue) {
|
private static void verifyDesignation(TermConceptDesignation theDesignation, String theUseSystem, String theUseCode, String theValue) {
|
||||||
if (theDesignation == null)
|
if (theDesignation == null)
|
||||||
return;
|
return;
|
||||||
assertEquals(theUseSystem, theDesignation.getUseSystem());
|
assertEquals(theUseSystem, theDesignation.getUseSystem());
|
||||||
assertEquals(theUseCode, theDesignation.getUseCode());
|
assertEquals(theUseCode, theDesignation.getUseCode());
|
||||||
assertEquals(theValue, theDesignation.getValue());
|
assertEquals(theValue, theDesignation.getValue());
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
#################
|
||||||
|
### MANDATORY ###
|
||||||
|
#################
|
||||||
|
|
||||||
|
# Answer lists (ValueSets of potential answers/values for LOINC "questions")
|
||||||
|
## File must be present
|
||||||
|
loinc.answerlist.file=AccessoryFiles/AnswerFile/AnswerList.csv
|
||||||
|
# Answer list links (connects LOINC observation codes to answer list codes)
|
||||||
|
## File must be present
|
||||||
|
loinc.answerlist.link.file=AccessoryFiles/AnswerFile/LoincAnswerListLink.csv
|
||||||
|
|
||||||
|
# Document ontology
|
||||||
|
## File must be present
|
||||||
|
loinc.document.ontology.file=AccessoryFiles/DocumentOntology/DocumentOntology.csv
|
||||||
|
|
||||||
|
# LOINC codes
|
||||||
|
## File must be present
|
||||||
|
loinc.file=LoincTable/Loinc.csv
|
||||||
|
|
||||||
|
# LOINC hierarchy
|
||||||
|
## File must be present
|
||||||
|
loinc.hierarchy.file=AccessoryFiles/MultiAxialHierarchy/MultiAxialHierarchy.csv
|
||||||
|
|
||||||
|
# IEEE medical device codes
|
||||||
|
## File must be present
|
||||||
|
loinc.ieee.medical.device.code.mapping.table.file=AccessoryFiles/LoincIeeeMedicalDeviceCodeMappingTable/LoincIeeeMedicalDeviceCodeMappingTable.csv
|
||||||
|
|
||||||
|
# Imaging document codes
|
||||||
|
## File must be present
|
||||||
|
loinc.imaging.document.codes.file=AccessoryFiles/ImagingDocuments/ImagingDocumentCodes.csv
|
||||||
|
|
||||||
|
# Part
|
||||||
|
## File must be present
|
||||||
|
loinc.part.file=AccessoryFiles/PartFile/Part.csv
|
||||||
|
|
||||||
|
# Part link
|
||||||
|
## File must be present
|
||||||
|
loinc.part.link.primary.file=AccessoryFiles/PartFile/LoincPartLink_Primary.csv
|
||||||
|
loinc.part.link.supplementary.file=AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv
|
||||||
|
|
||||||
|
# Part related code mapping
|
||||||
|
## File must be present
|
||||||
|
loinc.part.related.code.mapping.file=AccessoryFiles/PartFile/PartRelatedCodeMapping.csv
|
||||||
|
|
||||||
|
# RSNA playbook
|
||||||
|
## File must be present
|
||||||
|
loinc.rsna.playbook.file=AccessoryFiles/LoincRsnaRadiologyPlaybook/LoincRsnaRadiologyPlaybook.csv
|
||||||
|
|
||||||
|
# Top 2000 codes - SI
|
||||||
|
## File must be present
|
||||||
|
loinc.top2000.common.lab.results.si.file=AccessoryFiles/Top2000Results/SI/Top2000CommonLabResultsSi.csv
|
||||||
|
# Top 2000 codes - US
|
||||||
|
## File must be present
|
||||||
|
loinc.top2000.common.lab.results.us.file=AccessoryFiles/Top2000Results/US/Top2000CommonLabResultsUs.csv
|
||||||
|
|
||||||
|
# Universal lab order ValueSet
|
||||||
|
## File must be present
|
||||||
|
loinc.universal.lab.order.valueset.file=AccessoryFiles/LoincUniversalLabOrdersValueSet/LoincUniversalLabOrdersValueSet.csv
|
||||||
|
|
||||||
|
################
|
||||||
|
### OPTIONAL ###
|
||||||
|
################
|
||||||
|
|
||||||
|
# This is the version identifier for the LOINC code system
|
||||||
|
## Key may be omitted if only a single version of LOINC is being kept.
|
||||||
|
loinc.codesystem.version=2.68
|
||||||
|
|
||||||
|
loinc.codesystem.make.current=false
|
||||||
|
|
||||||
|
# This is the version identifier for the answer list file
|
||||||
|
## Key may be omitted
|
||||||
|
loinc.answerlist.version=Beta.1
|
||||||
|
|
||||||
|
# This is the version identifier for uploaded ConceptMap resources
|
||||||
|
## Key may be omitted
|
||||||
|
loinc.conceptmap.version=Beta.1
|
||||||
|
|
||||||
|
# Group
|
||||||
|
## Default value if key not provided: AccessoryFiles/GroupFile/Group.csv
|
||||||
|
## File may be omitted
|
||||||
|
loinc.group.file=AccessoryFiles/GroupFile/Group.csv
|
||||||
|
# Group terms
|
||||||
|
## Default value if key not provided: AccessoryFiles/GroupFile/GroupLoincTerms.csv
|
||||||
|
## File may be omitted
|
||||||
|
loinc.group.terms.file=AccessoryFiles/GroupFile/GroupLoincTerms.csv
|
||||||
|
# Parent group
|
||||||
|
## Default value if key not provided: AccessoryFiles/GroupFile/ParentGroup.csv
|
||||||
|
## File may be omitted
|
||||||
|
loinc.parent.group.file=AccessoryFiles/GroupFile/ParentGroup.csv
|
||||||
|
|
||||||
|
# Consumer Names
|
||||||
|
## Default value if key not provided: AccessoryFiles/ConsumerName/ConsumerName.csv
|
||||||
|
## File may be omitted
|
||||||
|
loinc.consumer.name.file=AccessoryFiles/ConsumerName/ConsumerName.csv
|
||||||
|
|
||||||
|
# Linguistic Variants
|
||||||
|
## Default value if key not provided: AccessoryFiles/LinguisticVariants/LinguisticVariants.csv
|
||||||
|
## File may be omitted
|
||||||
|
loinc.linguistic.variants.file=AccessoryFiles/LinguisticVariants/LinguisticVariants.csv
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -65,18 +65,12 @@
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-context-support</artifactId>
|
<artifactId>spring-context-support</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>javax.mail</groupId>
|
|
||||||
<artifactId>javax.mail-api</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- test dependencies -->
|
<!-- test dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
|
|
|
@ -20,19 +20,38 @@ package ca.uhn.fhir.jpa.subscription.match.deliver.email;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.simplejavamail.api.email.Email;
|
||||||
|
import org.simplejavamail.email.EmailBuilder;
|
||||||
|
import org.thymeleaf.context.Context;
|
||||||
|
import org.thymeleaf.spring5.SpringTemplateEngine;
|
||||||
|
import org.thymeleaf.spring5.dialect.SpringStandardDialect;
|
||||||
|
import org.thymeleaf.templatemode.TemplateMode;
|
||||||
|
import org.thymeleaf.templateresolver.StringTemplateResolver;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class EmailDetails {
|
public class EmailDetails {
|
||||||
|
private final SpringTemplateEngine myTemplateEngine;
|
||||||
|
private final Context myContext;
|
||||||
|
|
||||||
private String mySubjectTemplate;
|
private String mySubjectTemplate;
|
||||||
private String myBodyTemplate;
|
private String myBodyTemplate;
|
||||||
private List<String> myTo;
|
private List<String> myTo;
|
||||||
private String myFrom;
|
private String myFrom;
|
||||||
private IIdType mySubscription;
|
private IIdType mySubscription;
|
||||||
|
|
||||||
public String getBodyTemplate() {
|
public EmailDetails() {
|
||||||
return myBodyTemplate;
|
myTemplateEngine = makeTemplateEngine();
|
||||||
|
myContext = new Context();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBody() {
|
||||||
|
return myTemplateEngine.process(myBodyTemplate, myContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBodyTemplate(String theBodyTemplate) {
|
public void setBodyTemplate(String theBodyTemplate) {
|
||||||
|
@ -40,35 +59,65 @@ public class EmailDetails {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFrom() {
|
public String getFrom() {
|
||||||
return myFrom;
|
return StringUtils.trim(myFrom);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFrom(String theFrom) {
|
public void setFrom(String theFrom) {
|
||||||
myFrom = theFrom;
|
myFrom = theFrom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSubjectTemplate() {
|
public String getSubject() {
|
||||||
return mySubjectTemplate;
|
return myTemplateEngine.process(mySubjectTemplate, myContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSubjectTemplate(String theSubjectTemplate) {
|
public void setSubjectTemplate(String theSubjectTemplate) {
|
||||||
mySubjectTemplate = theSubjectTemplate;
|
mySubjectTemplate = theSubjectTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IIdType getSubscription() {
|
public String getSubscriptionId() {
|
||||||
return mySubscription;
|
return mySubscription.toUnqualifiedVersionless().getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSubscription(IIdType theSubscription) {
|
public void setSubscription(IIdType theSubscription) {
|
||||||
mySubscription = theSubscription;
|
mySubscription = theSubscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getTo() {
|
public String getTo() {
|
||||||
return myTo;
|
return myTo.stream().filter(StringUtils::isNotBlank).collect(Collectors.joining(","));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTo(List<String> theTo) {
|
public void setTo(List<String> theTo) {
|
||||||
myTo = theTo;
|
myTo = theTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Email toEmail() {
|
||||||
|
try {
|
||||||
|
return EmailBuilder.startingBlank()
|
||||||
|
.from(getFrom())
|
||||||
|
.to(getTo())
|
||||||
|
.withSubject(getSubject())
|
||||||
|
.withPlainText(getBody())
|
||||||
|
.withHeader("X-FHIR-Subscription", getSubscriptionId())
|
||||||
|
.buildEmail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new InternalErrorException("Failed to create email message", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private SpringTemplateEngine makeTemplateEngine() {
|
||||||
|
StringTemplateResolver stringTemplateResolver = new StringTemplateResolver();
|
||||||
|
stringTemplateResolver.setTemplateMode(TemplateMode.TEXT);
|
||||||
|
|
||||||
|
SpringStandardDialect springStandardDialect = new SpringStandardDialect();
|
||||||
|
springStandardDialect.setEnableSpringELCompiler(true);
|
||||||
|
|
||||||
|
SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
|
||||||
|
springTemplateEngine.setDialect(springStandardDialect);
|
||||||
|
springTemplateEngine.setEnableSpringELCompiler(true);
|
||||||
|
springTemplateEngine.setTemplateResolver(stringTemplateResolver);
|
||||||
|
|
||||||
|
return springTemplateEngine;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package ca.uhn.fhir.jpa.subscription.match.deliver.email;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR Subscription Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2021 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.server.mail.MailConfig;
|
||||||
|
import ca.uhn.fhir.rest.server.mail.MailSvc;
|
||||||
|
import ca.uhn.fhir.util.StopWatch;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.simplejavamail.api.email.Email;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class EmailSenderImpl implements IEmailSender {
|
||||||
|
|
||||||
|
private static final Logger ourLog = LoggerFactory.getLogger(EmailSenderImpl.class);
|
||||||
|
private MailSvc myMailSvc = new MailSvc();
|
||||||
|
private MailConfig myMailConfig;
|
||||||
|
|
||||||
|
public EmailSenderImpl(@Nonnull MailConfig theMailConfig) {
|
||||||
|
Validate.notNull(theMailConfig);
|
||||||
|
myMailConfig = theMailConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(EmailDetails theDetails) {
|
||||||
|
Validate.notNull(myMailConfig, "Mail configuration is not set!");
|
||||||
|
|
||||||
|
StopWatch stopWatch = new StopWatch();
|
||||||
|
|
||||||
|
ourLog.info("Sending email for subscription {} from [{}] to recipients: [{}]", theDetails.getSubscriptionId(), theDetails.getFrom(), theDetails.getTo());
|
||||||
|
|
||||||
|
Email email = theDetails.toEmail();
|
||||||
|
|
||||||
|
myMailSvc.sendMail(myMailConfig, email,
|
||||||
|
() -> ourLog.info("Done sending email for subscription {} from [{}] to recipients: [{}] (took {}ms)",
|
||||||
|
theDetails.getSubscriptionId(), theDetails.getFrom(), theDetails.getTo(), stopWatch.getMillis()),
|
||||||
|
(e) -> {
|
||||||
|
ourLog.error("Error sending email for subscription {} from [{}] to recipients: [{}] (took {}ms)",
|
||||||
|
theDetails.getSubscriptionId(), theDetails.getFrom(), theDetails.getTo(), stopWatch.getMillis());
|
||||||
|
ourLog.error("Error sending email", e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,194 +0,0 @@
|
||||||
package ca.uhn.fhir.jpa.subscription.match.deliver.email;
|
|
||||||
|
|
||||||
/*-
|
|
||||||
* #%L
|
|
||||||
* HAPI FHIR Subscription Server
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2014 - 2021 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.api.Constants;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|
||||||
import ca.uhn.fhir.util.StopWatch;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
|
||||||
import org.thymeleaf.context.Context;
|
|
||||||
import org.thymeleaf.spring5.SpringTemplateEngine;
|
|
||||||
import org.thymeleaf.spring5.dialect.SpringStandardDialect;
|
|
||||||
import org.thymeleaf.templatemode.TemplateMode;
|
|
||||||
import org.thymeleaf.templateresolver.StringTemplateResolver;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import javax.mail.Message;
|
|
||||||
import javax.mail.MessagingException;
|
|
||||||
import javax.mail.internet.MimeMessage;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.trim;
|
|
||||||
|
|
||||||
public class JavaMailEmailSender implements IEmailSender {
|
|
||||||
|
|
||||||
private static final Logger ourLog = LoggerFactory.getLogger(JavaMailEmailSender.class);
|
|
||||||
private String mySmtpServerHostname;
|
|
||||||
private int mySmtpServerPort = 25;
|
|
||||||
private JavaMailSenderImpl mySender;
|
|
||||||
private String mySmtpServerUsername;
|
|
||||||
private String mySmtpServerPassword;
|
|
||||||
private final Properties myJavaMailProperties = new Properties();
|
|
||||||
|
|
||||||
public String getSmtpServerHostname() {
|
|
||||||
return mySmtpServerHostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the SMTP server host to use for outbound mail
|
|
||||||
*/
|
|
||||||
public void setSmtpServerHostname(String theSmtpServerHostname) {
|
|
||||||
mySmtpServerHostname = theSmtpServerHostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSmtpServerPassword() {
|
|
||||||
return mySmtpServerPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSmtpServerPassword(String theSmtpServerPassword) {
|
|
||||||
mySmtpServerPassword = theSmtpServerPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSmtpServerPort() {
|
|
||||||
return mySmtpServerPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the SMTP server port to use for outbound mail
|
|
||||||
*/
|
|
||||||
public void setSmtpServerPort(int theSmtpServerPort) {
|
|
||||||
mySmtpServerPort = theSmtpServerPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSmtpServerUsername() {
|
|
||||||
return mySmtpServerUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSmtpServerUsername(String theSmtpServerUsername) {
|
|
||||||
mySmtpServerUsername = theSmtpServerUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the "mail.smtp.auth" Java Mail Property
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void setAuth(Boolean theAuth) {
|
|
||||||
myJavaMailProperties.setProperty("mail.smtp.auth", theAuth.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the "mail.smtp.starttls.enable" Java Mail Property
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void setStartTlsEnable(Boolean theStartTlsEnable) {
|
|
||||||
myJavaMailProperties.setProperty("mail.smtp.starttls.enable", theStartTlsEnable.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the "mail.smtp.starttls.required" Java Mail Property
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void setStartTlsRequired(Boolean theStartTlsRequired) {
|
|
||||||
myJavaMailProperties.setProperty("mail.smtp.starttls.required", theStartTlsRequired.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the "mail.smtp.quitwait" Java Mail Property
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void setQuitWait(Boolean theQuitWait) {
|
|
||||||
myJavaMailProperties.setProperty("mail.smtp.quitwait", theQuitWait.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(EmailDetails theDetails) {
|
|
||||||
String subscriptionId = theDetails.getSubscription().toUnqualifiedVersionless().getValue();
|
|
||||||
StopWatch sw = new StopWatch();
|
|
||||||
|
|
||||||
StringTemplateResolver templateResolver = new StringTemplateResolver();
|
|
||||||
templateResolver.setTemplateMode(TemplateMode.TEXT);
|
|
||||||
|
|
||||||
SpringStandardDialect dialect = new SpringStandardDialect();
|
|
||||||
dialect.setEnableSpringELCompiler(true);
|
|
||||||
|
|
||||||
SpringTemplateEngine engine = new SpringTemplateEngine();
|
|
||||||
engine.setDialect(dialect);
|
|
||||||
engine.setEnableSpringELCompiler(true);
|
|
||||||
engine.setTemplateResolver(templateResolver);
|
|
||||||
|
|
||||||
Context context = new Context();
|
|
||||||
|
|
||||||
String body = engine.process(theDetails.getBodyTemplate(), context);
|
|
||||||
String subject = engine.process(theDetails.getSubjectTemplate(), context);
|
|
||||||
|
|
||||||
MimeMessage email = mySender.createMimeMessage();
|
|
||||||
|
|
||||||
String from = trim(theDetails.getFrom());
|
|
||||||
ourLog.info("Sending email for subscription {} from [{}] to recipients: [{}]", subscriptionId, from, theDetails.getTo());
|
|
||||||
|
|
||||||
try {
|
|
||||||
email.setFrom(from);
|
|
||||||
email.setRecipients(Message.RecipientType.TO, toTrimmedCommaSeparatedString(theDetails.getTo()));
|
|
||||||
email.setSubject(subject);
|
|
||||||
email.setText(body);
|
|
||||||
email.setSentDate(new Date());
|
|
||||||
email.addHeader("X-FHIR-Subscription", subscriptionId);
|
|
||||||
} catch (MessagingException e) {
|
|
||||||
throw new InternalErrorException("Failed to create email message", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
mySender.send(email);
|
|
||||||
|
|
||||||
ourLog.info("Done sending email (took {}ms)", sw.getMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
public void start() {
|
|
||||||
Validate.notBlank(mySmtpServerHostname, "No SMTP host defined");
|
|
||||||
|
|
||||||
mySender = new JavaMailSenderImpl();
|
|
||||||
mySender.setHost(getSmtpServerHostname());
|
|
||||||
mySender.setPort(getSmtpServerPort());
|
|
||||||
mySender.setUsername(getSmtpServerUsername());
|
|
||||||
mySender.setPassword(getSmtpServerPassword());
|
|
||||||
mySender.setDefaultEncoding(Constants.CHARSET_UTF8.name());
|
|
||||||
mySender.setJavaMailProperties(myJavaMailProperties);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String toTrimmedCommaSeparatedString(List<String> theTo) {
|
|
||||||
List<String> to = new ArrayList<>();
|
|
||||||
for (String next : theTo) {
|
|
||||||
if (isNotBlank(next)) {
|
|
||||||
to.add(next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return StringUtils.join(to, ",");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,20 +22,21 @@ package ca.uhn.fhir.jpa.subscription.match.deliver.email;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||||
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
|
||||||
import ca.uhn.fhir.jpa.subscription.match.deliver.BaseSubscriptionDeliverySubscriber;
|
import ca.uhn.fhir.jpa.subscription.match.deliver.BaseSubscriptionDeliverySubscriber;
|
||||||
|
import ca.uhn.fhir.jpa.subscription.model.CanonicalSubscription;
|
||||||
import ca.uhn.fhir.jpa.subscription.model.ResourceDeliveryMessage;
|
import ca.uhn.fhir.jpa.subscription.model.ResourceDeliveryMessage;
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Scope;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.*;
|
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.trim;
|
||||||
|
|
||||||
public class SubscriptionDeliveringEmailSubscriber extends BaseSubscriptionDeliverySubscriber {
|
public class SubscriptionDeliveringEmailSubscriber extends BaseSubscriptionDeliverySubscriber {
|
||||||
private Logger ourLog = LoggerFactory.getLogger(SubscriptionDeliveringEmailSubscriber.class);
|
private Logger ourLog = LoggerFactory.getLogger(SubscriptionDeliveringEmailSubscriber.class);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -76,19 +76,19 @@ public final class MdmResourceUtil {
|
||||||
return theBaseResource.getMeta().getTag(theSystem, theCode) != null;
|
return theBaseResource.getMeta().getTag(theSystem, theCode) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean resourceHasTagWithSystem(IBaseResource theBaseResource, String theSystem) {
|
private static boolean resourceHasTagWithSystem(IBaseResource theBaseResource, @Nonnull String theSystem) {
|
||||||
if (theBaseResource == null) {
|
if (theBaseResource == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return theBaseResource.getMeta().getTag().stream().anyMatch(tag -> tag.getSystem().equalsIgnoreCase(theSystem));
|
return theBaseResource.getMeta().getTag().stream().anyMatch(tag -> theSystem.equalsIgnoreCase(tag.getSystem()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<? extends IBaseCoding> getTagWithSystem(IBaseResource theResource, String theSystem) {
|
private static Optional<? extends IBaseCoding> getTagWithSystem(IBaseResource theResource, @Nonnull String theSystem) {
|
||||||
return theResource.getMeta().getTag().stream().filter(tag -> tag.getSystem().equalsIgnoreCase(theSystem)).findFirst();
|
return theResource.getMeta().getTag().stream().filter(tag -> theSystem.equalsIgnoreCase(tag.getSystem())).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeTagWithSystem(IBaseResource theResource, String theSystem) {
|
public static void removeTagWithSystem(IBaseResource theResource, @Nonnull String theSystem) {
|
||||||
theResource.getMeta().getTag().removeIf(tag -> tag.getSystem().equalsIgnoreCase(theSystem));
|
theResource.getMeta().getTag().removeIf(tag -> theSystem.equalsIgnoreCase(tag.getSystem()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package ca.uhn.fhir.mdm.util;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r4.model.Organization;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
|
||||||
|
class MdmResourceUtilTest {
|
||||||
|
|
||||||
|
//See https://github.com/hapifhir/hapi-fhir/issues/2876
|
||||||
|
@Test
|
||||||
|
public void testNoNpeOnTagWithNoSystem() {
|
||||||
|
//Given
|
||||||
|
Organization organization = new Organization();
|
||||||
|
organization.getMeta().addTag(null, "Some Code", "Some Display");
|
||||||
|
|
||||||
|
boolean hasGoldenRecordTag = MdmResourceUtil.hasGoldenRecordSystemTag(organization);
|
||||||
|
|
||||||
|
assertThat(hasGoldenRecordTag, is(equalTo(false)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -509,7 +509,7 @@ public class OpenApiInterceptor {
|
||||||
Operation operation = getPathItem(paths, "/" + resourceType, PathItem.HttpMethod.GET);
|
Operation operation = getPathItem(paths, "/" + resourceType, PathItem.HttpMethod.GET);
|
||||||
operation.addTagsItem(resourceType);
|
operation.addTagsItem(resourceType);
|
||||||
operation.setDescription("This is a search type");
|
operation.setDescription("This is a search type");
|
||||||
operation.setSummary("search-type: Update an existing " + resourceType + " instance, or create using a client-assigned ID");
|
operation.setSummary("search-type: Search for " + resourceType + " instances");
|
||||||
addFhirResourceResponse(ctx, openApi, operation, null);
|
addFhirResourceResponse(ctx, openApi, operation, null);
|
||||||
|
|
||||||
for (CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent nextSearchParam : nextResource.getSearchParam()) {
|
for (CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent nextSearchParam : nextResource.getSearchParam()) {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -87,6 +87,29 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- mail start -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.simplejavamail</groupId>
|
||||||
|
<artifactId>simple-java-mail</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>jakarta.annotation</groupId>
|
||||||
|
<artifactId>jakarta.annotation-api</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.icegreen</groupId>
|
||||||
|
<artifactId>greenmail</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.icegreen</groupId>
|
||||||
|
<artifactId>greenmail-junit5</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- mail end -->
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
package ca.uhn.fhir.rest.server.mail;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
|
||||||
|
public class MailConfig {
|
||||||
|
private String mySmtpHostname;
|
||||||
|
private Integer mySmtpPort;
|
||||||
|
private String mySmtpUsername;
|
||||||
|
private String mySmtpPassword;
|
||||||
|
private boolean mySmtpUseStartTLS;
|
||||||
|
|
||||||
|
public MailConfig() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmtpHostname() {
|
||||||
|
return mySmtpHostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MailConfig setSmtpHostname(String theSmtpHostname) {
|
||||||
|
mySmtpHostname = theSmtpHostname;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getSmtpPort() {
|
||||||
|
return mySmtpPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MailConfig setSmtpPort(Integer theSmtpPort) {
|
||||||
|
mySmtpPort = theSmtpPort;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmtpUsername() {
|
||||||
|
return mySmtpUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MailConfig setSmtpUsername(String theSmtpUsername) {
|
||||||
|
// SimpleJavaMail treats empty smtp username as valid username and requires auth
|
||||||
|
mySmtpUsername = StringUtils.isBlank(theSmtpUsername) ? null : theSmtpUsername;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSmtpPassword() {
|
||||||
|
return mySmtpPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MailConfig setSmtpPassword(String theSmtpPassword) {
|
||||||
|
// SimpleJavaMail treats empty smtp password as valid password and requires auth
|
||||||
|
mySmtpPassword = StringUtils.isBlank(theSmtpPassword) ? null : theSmtpPassword;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSmtpUseStartTLS() {
|
||||||
|
return mySmtpUseStartTLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MailConfig setSmtpUseStartTLS(boolean theSmtpUseStartTLS) {
|
||||||
|
mySmtpUseStartTLS = theSmtpUseStartTLS;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (this == object) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (object == null || getClass() != object.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return EqualsBuilder.reflectionEquals(this, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return HashCodeBuilder.reflectionHashCode(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ToStringBuilder.reflectionToString(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
package ca.uhn.fhir.rest.server.mail;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.simplejavamail.MailException;
|
||||||
|
import org.simplejavamail.api.email.Email;
|
||||||
|
import org.simplejavamail.api.email.Recipient;
|
||||||
|
import org.simplejavamail.api.mailer.AsyncResponse;
|
||||||
|
import org.simplejavamail.api.mailer.AsyncResponse.ExceptionConsumer;
|
||||||
|
import org.simplejavamail.api.mailer.Mailer;
|
||||||
|
import org.simplejavamail.api.mailer.config.TransportStrategy;
|
||||||
|
import org.simplejavamail.mailer.MailerBuilder;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class MailSvc {
|
||||||
|
private static final Logger ourLog = LoggerFactory.getLogger(MailSvc.class);
|
||||||
|
|
||||||
|
public void sendMail(@Nonnull MailConfig theMailConfig, @Nonnull List<Email> theEmails) {
|
||||||
|
Validate.notNull(theMailConfig);
|
||||||
|
Validate.notNull(theEmails);
|
||||||
|
final Mailer mailer = makeMailer(theMailConfig);
|
||||||
|
theEmails.forEach(theEmail -> sendMail(mailer, theEmail, new OnSuccess(theEmail), new ErrorHandler(theEmail)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMail(@Nonnull MailConfig theMailConfig, @Nonnull Email theEmail) {
|
||||||
|
Validate.notNull(theMailConfig);
|
||||||
|
final Mailer mailer = makeMailer(theMailConfig);
|
||||||
|
sendMail(mailer, theEmail, new OnSuccess(theEmail), new ErrorHandler(theEmail));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMail(@Nonnull MailConfig theMailConfig,
|
||||||
|
@Nonnull Email theEmail,
|
||||||
|
@Nonnull Runnable theOnSuccess,
|
||||||
|
@Nonnull ExceptionConsumer theErrorHandler) {
|
||||||
|
Validate.notNull(theMailConfig);
|
||||||
|
final Mailer mailer = makeMailer(theMailConfig);
|
||||||
|
sendMail(mailer, theEmail, theOnSuccess, theErrorHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMail(@Nonnull Mailer theMailer,
|
||||||
|
@Nonnull Email theEmail,
|
||||||
|
@Nonnull Runnable theOnSuccess,
|
||||||
|
@Nonnull ExceptionConsumer theErrorHandler) {
|
||||||
|
Validate.notNull(theMailer);
|
||||||
|
Validate.notNull(theEmail);
|
||||||
|
Validate.notNull(theOnSuccess);
|
||||||
|
Validate.notNull(theErrorHandler);
|
||||||
|
try {
|
||||||
|
final AsyncResponse asyncResponse = theMailer.sendMail(theEmail, true);
|
||||||
|
if (asyncResponse != null) {
|
||||||
|
asyncResponse.onSuccess(theOnSuccess);
|
||||||
|
asyncResponse.onException(theErrorHandler);
|
||||||
|
}
|
||||||
|
} catch (MailException e) {
|
||||||
|
theErrorHandler.accept(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private Mailer makeMailer(@Nonnull MailConfig theMailConfig) {
|
||||||
|
ourLog.info("SMTP Mailer config Hostname:[{}] | Port:[{}] | Username:[{}] | TLS:[{}]",
|
||||||
|
theMailConfig.getSmtpHostname(), theMailConfig.getSmtpPort(),
|
||||||
|
theMailConfig.getSmtpUsername(), theMailConfig.isSmtpUseStartTLS());
|
||||||
|
return MailerBuilder
|
||||||
|
.withSMTPServer(
|
||||||
|
theMailConfig.getSmtpHostname(),
|
||||||
|
theMailConfig.getSmtpPort(),
|
||||||
|
theMailConfig.getSmtpUsername(),
|
||||||
|
theMailConfig.getSmtpPassword())
|
||||||
|
.withTransportStrategy(theMailConfig.isSmtpUseStartTLS() ? TransportStrategy.SMTP_TLS : TransportStrategy.SMTP)
|
||||||
|
.buildMailer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
private String makeMessage(@Nonnull Email theEmail) {
|
||||||
|
return " with subject [" + theEmail.getSubject() + "] and recipients ["
|
||||||
|
+ theEmail.getRecipients().stream().map(Recipient::getAddress).collect(Collectors.joining(",")) + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
private class OnSuccess implements Runnable {
|
||||||
|
private final Email myEmail;
|
||||||
|
|
||||||
|
private OnSuccess(@Nonnull Email theEmail) {
|
||||||
|
myEmail = theEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ourLog.info("Email sent" + makeMessage(myEmail));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ErrorHandler implements ExceptionConsumer {
|
||||||
|
private final Email myEmail;
|
||||||
|
|
||||||
|
private ErrorHandler(@Nonnull Email theEmail) {
|
||||||
|
myEmail = theEmail;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(Exception t) {
|
||||||
|
ourLog.error("Email not sent" + makeMessage(myEmail), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package ca.uhn.fhir.rest.server.mail;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class MailConfigTest {
|
||||||
|
|
||||||
|
private static final String SMTP_HOST_NAME = "SMTP_HOST_NAME";
|
||||||
|
private static final Integer SMTP_PORT = 1025;
|
||||||
|
private static final String SMTP_USERNAME = "SMTP_USERNAME";
|
||||||
|
private static final String SMTP_PASSWORD = "SMTP_PASSWORD";
|
||||||
|
|
||||||
|
private MailConfig fixture;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
fixture = withMainConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private MailConfig withMainConfig() {
|
||||||
|
return new MailConfig()
|
||||||
|
.setSmtpHostname(SMTP_HOST_NAME)
|
||||||
|
.setSmtpPort(SMTP_PORT)
|
||||||
|
.setSmtpUsername(SMTP_USERNAME)
|
||||||
|
.setSmtpPassword(SMTP_PASSWORD)
|
||||||
|
.setSmtpUseStartTLS(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSmtpHostname() {
|
||||||
|
// execute
|
||||||
|
final String actual = fixture.getSmtpHostname();
|
||||||
|
// validate
|
||||||
|
assertEquals(SMTP_HOST_NAME, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSmtpPort() {
|
||||||
|
// execute
|
||||||
|
final int actual = fixture.getSmtpPort();
|
||||||
|
// validate
|
||||||
|
assertEquals(SMTP_PORT, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSmtpUsername() {
|
||||||
|
// execute
|
||||||
|
final String actual = fixture.getSmtpUsername();
|
||||||
|
// validate
|
||||||
|
assertEquals(SMTP_USERNAME, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetSmtpPassword() {
|
||||||
|
// execute
|
||||||
|
final String actual = fixture.getSmtpPassword();
|
||||||
|
// validate
|
||||||
|
assertEquals(SMTP_PASSWORD, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsSmtpUseStartTLS() {
|
||||||
|
// execute
|
||||||
|
final boolean actual = fixture.isSmtpUseStartTLS();
|
||||||
|
// validate
|
||||||
|
assertTrue(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEquality() {
|
||||||
|
// setup
|
||||||
|
final MailConfig other = withMainConfig();
|
||||||
|
// execute & validate
|
||||||
|
assertEquals(fixture, fixture);
|
||||||
|
assertSame(fixture, fixture);
|
||||||
|
assertEquals(fixture, other);
|
||||||
|
assertNotSame(fixture, other);
|
||||||
|
assertEquals(fixture.hashCode(), other.hashCode());
|
||||||
|
assertNotEquals(fixture.toString(), other.toString());
|
||||||
|
assertNotEquals(fixture, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetSmtpUsername() {
|
||||||
|
// execute & validate
|
||||||
|
assertEquals("xyz", fixture.setSmtpUsername("xyz").getSmtpUsername());
|
||||||
|
assertNull(fixture.setSmtpUsername(null).getSmtpUsername());
|
||||||
|
assertNull(fixture.setSmtpUsername("").getSmtpUsername());
|
||||||
|
assertNull(fixture.setSmtpUsername(" ").getSmtpUsername());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetSmtpPassword() {
|
||||||
|
// execute & validate
|
||||||
|
assertEquals("xyz", fixture.setSmtpPassword("xyz").getSmtpPassword());
|
||||||
|
assertNull(fixture.setSmtpPassword(null).getSmtpPassword());
|
||||||
|
assertNull(fixture.setSmtpPassword("").getSmtpPassword());
|
||||||
|
assertNull(fixture.setSmtpPassword(" ").getSmtpPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,120 @@
|
||||||
|
package ca.uhn.fhir.rest.server.mail;
|
||||||
|
|
||||||
|
import com.icegreen.greenmail.junit5.GreenMailExtension;
|
||||||
|
import com.icegreen.greenmail.util.GreenMailUtil;
|
||||||
|
import com.icegreen.greenmail.util.ServerSetupTest;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||||
|
import org.simplejavamail.MailException;
|
||||||
|
import org.simplejavamail.api.email.Email;
|
||||||
|
import org.simplejavamail.email.EmailBuilder;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.mail.internet.MimeMessage;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
public class MailSvcIT {
|
||||||
|
private static final String FROM_ADDRESS = "from_address@email.com";
|
||||||
|
private static final String TO_ADDRESS = "to_address@email.com";
|
||||||
|
private static final String SUBJECT = "Email Subject";
|
||||||
|
private static final String BODY = "Email Body !!!";
|
||||||
|
|
||||||
|
@RegisterExtension
|
||||||
|
static GreenMailExtension ourGreenMail = new GreenMailExtension(ServerSetupTest.SMTP);
|
||||||
|
|
||||||
|
private MailSvc fixture;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() {
|
||||||
|
fixture = new MailSvc();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSendSingleMail() throws Exception {
|
||||||
|
// setup
|
||||||
|
final MailConfig mailConfig = withMailConfig();
|
||||||
|
final Email email = withEmail();
|
||||||
|
// execute
|
||||||
|
fixture.sendMail(mailConfig, email);
|
||||||
|
// validate
|
||||||
|
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 1));
|
||||||
|
final MimeMessage[] receivedMessages = ourGreenMail.getReceivedMessages();
|
||||||
|
assertEquals(1, receivedMessages.length);
|
||||||
|
assertEquals(SUBJECT, receivedMessages[0].getSubject());
|
||||||
|
assertEquals(BODY, GreenMailUtil.getBody(receivedMessages[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSendMultipleMail() throws Exception {
|
||||||
|
// setup
|
||||||
|
final MailConfig mailConfig = withMailConfig();
|
||||||
|
final List<Email> emails = Arrays.asList(withEmail(), withEmail(), withEmail());
|
||||||
|
// execute
|
||||||
|
fixture.sendMail(mailConfig, emails);
|
||||||
|
// validate
|
||||||
|
assertTrue(ourGreenMail.waitForIncomingEmail(1000, emails.size()));
|
||||||
|
final MimeMessage[] receivedMessages = ourGreenMail.getReceivedMessages();
|
||||||
|
assertEquals(emails.size(), receivedMessages.length);
|
||||||
|
assertEquals(SUBJECT, receivedMessages[0].getSubject());
|
||||||
|
assertEquals(BODY, GreenMailUtil.getBody(receivedMessages[0]));
|
||||||
|
assertEquals(SUBJECT, receivedMessages[1].getSubject());
|
||||||
|
assertEquals(BODY, GreenMailUtil.getBody(receivedMessages[1]));
|
||||||
|
assertEquals(SUBJECT, receivedMessages[2].getSubject());
|
||||||
|
assertEquals(BODY, GreenMailUtil.getBody(receivedMessages[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSendMailWithInvalidToAddress() {
|
||||||
|
// setup
|
||||||
|
final MailConfig mailConfig = withMailConfig();
|
||||||
|
final Email email = withEmail("xyz");
|
||||||
|
// execute
|
||||||
|
fixture.sendMail(mailConfig, email);
|
||||||
|
// validate
|
||||||
|
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 0));
|
||||||
|
final MimeMessage[] receivedMessages = ourGreenMail.getReceivedMessages();
|
||||||
|
assertEquals(0, receivedMessages.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSendMailWithInvalidToAddressExpectErrorHandler() {
|
||||||
|
// setup
|
||||||
|
final MailConfig mailConfig = withMailConfig();
|
||||||
|
final Email email = withEmail("xyz");
|
||||||
|
// execute
|
||||||
|
fixture.sendMail(mailConfig, email,
|
||||||
|
() -> fail("Should not execute on Success"),
|
||||||
|
(e) -> {
|
||||||
|
assertTrue(e instanceof MailException);
|
||||||
|
assertEquals("Invalid TO address: " + email, e.getMessage());
|
||||||
|
});
|
||||||
|
// validate
|
||||||
|
assertTrue(ourGreenMail.waitForIncomingEmail(1000, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private MailConfig withMailConfig() {
|
||||||
|
return new MailConfig()
|
||||||
|
.setSmtpHostname(ServerSetupTest.SMTP.getBindAddress())
|
||||||
|
.setSmtpPort(ServerSetupTest.SMTP.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Email withEmail() {
|
||||||
|
return withEmail(TO_ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Email withEmail(@Nonnull String toAddress) {
|
||||||
|
return EmailBuilder.startingBlank()
|
||||||
|
.from(FROM_ADDRESS)
|
||||||
|
.to(toAddress)
|
||||||
|
.withSubject(SUBJECT)
|
||||||
|
.withPlainText(BODY)
|
||||||
|
.buildEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-client-apache</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-client-okhttp</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>
|
<artifactId>hapi-fhir-spring-boot-sample-server-jersey</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-spring-boot</artifactId>
|
<artifactId>hapi-fhir-spring-boot</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
<artifactId>hapi-fhir-spring-boot-samples</artifactId>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-deployable-pom</artifactId>
|
<artifactId>hapi-deployable-pom</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
<relativePath>../hapi-deployable-pom/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
@ -58,37 +58,37 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
<artifactId>hapi-fhir-structures-dstu3</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
<artifactId>hapi-fhir-structures-hl7org-dstu2</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-r4</artifactId>
|
<artifactId>hapi-fhir-structures-r4</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-structures-r5</artifactId>
|
<artifactId>hapi-fhir-structures-r5</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
<artifactId>hapi-fhir-validation-resources-dstu2</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
<artifactId>hapi-fhir-validation-resources-dstu3</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
|
<artifactId>hapi-fhir-validation-resources-r4</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.velocity</groupId>
|
<groupId>org.apache.velocity</groupId>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
40
pom.xml
40
pom.xml
|
@ -6,11 +6,12 @@
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<name>HAPI-FHIR</name>
|
<name>HAPI-FHIR</name>
|
||||||
<description>An open-source implementation of the FHIR specification in Java.</description>
|
<description>An open-source implementation of the FHIR specification in Java.</description>
|
||||||
<url>https://hapifhir.io</url>
|
<url>https://hapifhir.io</url>
|
||||||
|
|
||||||
|
|
||||||
<organization>
|
<organization>
|
||||||
<name>Smile CDR, Inc.</name>
|
<name>Smile CDR, Inc.</name>
|
||||||
<url>https://smilecdr.com</url>
|
<url>https://smilecdr.com</url>
|
||||||
|
@ -893,16 +894,25 @@
|
||||||
<artifactId>caffeine</artifactId>
|
<artifactId>caffeine</artifactId>
|
||||||
<version>${caffeine_version}</version>
|
<version>${caffeine_version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- mail start -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.simplejavamail</groupId>
|
||||||
|
<artifactId>simple-java-mail</artifactId>
|
||||||
|
<version>6.6.1</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.icegreen</groupId>
|
<groupId>com.icegreen</groupId>
|
||||||
<artifactId>greenmail</artifactId>
|
<artifactId>greenmail</artifactId>
|
||||||
<version>1.6.3</version>
|
<version>1.6.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.icegreen</groupId>
|
<groupId>com.icegreen</groupId>
|
||||||
<artifactId>greenmail-spring</artifactId>
|
<artifactId>greenmail-junit5</artifactId>
|
||||||
<version>1.5.10</version>
|
<version>1.6.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- mail end -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.dnault</groupId>
|
<groupId>com.github.dnault</groupId>
|
||||||
<artifactId>xml-patch</artifactId>
|
<artifactId>xml-patch</artifactId>
|
||||||
|
@ -963,11 +973,6 @@
|
||||||
<artifactId>jakarta.activation</artifactId>
|
<artifactId>jakarta.activation</artifactId>
|
||||||
<version>2.0.0</version>
|
<version>2.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.sun.mail</groupId>
|
|
||||||
<artifactId>javax.mail</artifactId>
|
|
||||||
<version>1.6.1</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.vladsch.flexmark</groupId>
|
<groupId>com.vladsch.flexmark</groupId>
|
||||||
<artifactId>flexmark</artifactId>
|
<artifactId>flexmark</artifactId>
|
||||||
|
@ -1115,11 +1120,6 @@
|
||||||
<artifactId>mssql-jdbc</artifactId>
|
<artifactId>mssql-jdbc</artifactId>
|
||||||
<version>9.2.1.jre8</version>
|
<version>9.2.1.jre8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>javax.mail</groupId>
|
|
||||||
<artifactId>javax.mail-api</artifactId>
|
|
||||||
<version>1.6.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.servlet</groupId>
|
<groupId>javax.servlet</groupId>
|
||||||
<artifactId>javax.servlet-api</artifactId>
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
@ -1784,17 +1784,7 @@
|
||||||
<artifactId>spring-websocket</artifactId>
|
<artifactId>spring-websocket</artifactId>
|
||||||
<version>${spring_version}</version>
|
<version>${spring_version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.batch</groupId>
|
|
||||||
<artifactId>spring-batch-core</artifactId>
|
|
||||||
<version>${spring_batch_version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.batch</groupId>
|
|
||||||
<artifactId>spring-batch-infrastructure</artifactId>
|
|
||||||
<version>${spring_batch_version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.retry</groupId>
|
<groupId>org.springframework.retry</groupId>
|
||||||
<artifactId>spring-retry</artifactId>
|
<artifactId>spring-retry</artifactId>
|
||||||
<version>${spring_retry_version}</version>
|
<version>${spring_retry_version}</version>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||||
<artifactId>hapi-fhir</artifactId>
|
<artifactId>hapi-fhir</artifactId>
|
||||||
<version>5.5.0-PRE8-SNAPSHOT</version>
|
<version>5.6.0-PRE1-SNAPSHOT</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue