mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-03-28 02:48:47 +00:00
Initial implementation of lastn operation.
This commit is contained in:
parent
f891634341
commit
f819c91530
hapi-fhir-cli
hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli
hapi-fhir-cli-jpaserver
pom.xml
src/main/java/ca/uhn/fhir/jpa/demo
hapi-fhir-jpaserver-base/src
main/java/ca/uhn/fhir/jpa
config
dao
IFhirResourceDaoObservation.javaSearchBuilder.java
data
dstu3
lastn
ObservationLastNIndexPersistDstu3Svc.javaObservationLastNIndexPersistR4Svc.javaObservationLastNIndexPersistR5Svc.javaObservationLastNIndexPersistSvc.java
entity
r4
r5
provider
search/lastn
test/java/ca/uhn/fhir/jpa
dao/lastn
IntegratedObservationIndexedSearchParamLastNTest.javaPersistObservationIndexedSearchParamLastNTest.java
config
search/lastn
hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util
hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam
hapi-tinder-plugin/src/main/resources/vm
@ -173,6 +173,7 @@ public abstract class BaseApp {
|
||||
commands.add(new ExportConceptMapToCsvCommand());
|
||||
commands.add(new ImportCsvToConceptMapCommand());
|
||||
commands.add(new HapiFlywayMigrateDatabaseCommand());
|
||||
commands.add(new RunJpaServerWithElasticsearchCommand());
|
||||
return commands;
|
||||
}
|
||||
|
||||
|
250
hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/RunJpaServerWithElasticsearchCommand.java
Normal file
250
hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/RunJpaServerWithElasticsearchCommand.java
Normal file
@ -0,0 +1,250 @@
|
||||
package ca.uhn.fhir.cli;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR - Command Line Client - API
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.demo.*;
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.springframework.web.context.ContextLoader;
|
||||
import org.springframework.web.context.ContextLoaderListener;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import java.io.*;
|
||||
import java.net.SocketException;
|
||||
|
||||
public class RunJpaServerWithElasticsearchCommand extends BaseCommand {
|
||||
|
||||
private static final String OPTION_DISABLE_REFERENTIAL_INTEGRITY = "disable-referential-integrity";
|
||||
private static final String OPTION_LOWMEM = "lowmem";
|
||||
private static final String OPTION_ALLOW_EXTERNAL_REFS = "allow-external-refs";
|
||||
private static final String OPTION_REUSE_SEARCH_RESULTS_MILLIS = "reuse-search-results-milliseconds";
|
||||
private static final String OPTION_EXTERNAL_ELASTICSEARCH = "external-elasticsearch";
|
||||
private static final int DEFAULT_PORT = 8080;
|
||||
private static final String OPTION_P = "p";
|
||||
|
||||
// TODO: Don't use qualified names for loggers in HAPI CLI.
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RunJpaServerWithElasticsearchCommand.class);
|
||||
public static final String RUN_SERVER_COMMAND_ELASTICSEARCH = "run-server-elasticsearch";
|
||||
private int myPort;
|
||||
|
||||
private Server myServer;
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return RUN_SERVER_COMMAND_ELASTICSEARCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Options getOptions() {
|
||||
Options options = new Options();
|
||||
addFhirVersionOption(options);
|
||||
options.addOption(OPTION_P, "port", true, "The port to listen on (default is " + DEFAULT_PORT + ")");
|
||||
options.addOption(null, OPTION_LOWMEM, false, "If this flag is set, the server will operate in low memory mode (some features disabled)");
|
||||
options.addOption(null, OPTION_ALLOW_EXTERNAL_REFS, false, "If this flag is set, the server will allow resources to be persisted contaning external resource references");
|
||||
options.addOption(null, OPTION_DISABLE_REFERENTIAL_INTEGRITY, false, "If this flag is set, the server will not enforce referential integrity");
|
||||
options.addOption(null, OPTION_EXTERNAL_ELASTICSEARCH, false, "If this flag is set, the server will attempt to use an external elasticsearch instance listening on port 9301");
|
||||
|
||||
addOptionalOption(options, "u", "url", "Url", "If this option is set, specifies the JDBC URL to use for the database connection");
|
||||
|
||||
Long defaultReuseSearchResults = DaoConfig.DEFAULT_REUSE_CACHED_SEARCH_RESULTS_FOR_MILLIS;
|
||||
String defaultReuseSearchResultsStr = defaultReuseSearchResults == null ? "off" : String.valueOf(defaultReuseSearchResults);
|
||||
options.addOption(null, OPTION_REUSE_SEARCH_RESULTS_MILLIS, true, "The time in milliseconds within which the same results will be returned for multiple identical searches, or \"off\" (default is " + defaultReuseSearchResultsStr + ")");
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private int parseOptionInteger(CommandLine theCommandLine, String opt, int defaultPort) throws ParseException {
|
||||
try {
|
||||
return Integer.parseInt(theCommandLine.getOptionValue(opt, Integer.toString(defaultPort)));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ParseException("Invalid value '" + theCommandLine.getOptionValue(opt) + "' (must be numeric)");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandLine theCommandLine) throws ParseException {
|
||||
parseFhirContext(theCommandLine);
|
||||
|
||||
myPort = parseOptionInteger(theCommandLine, OPTION_P, DEFAULT_PORT);
|
||||
|
||||
if (theCommandLine.hasOption(OPTION_LOWMEM)) {
|
||||
ourLog.info("Running in low memory mode, some features disabled");
|
||||
System.setProperty(OPTION_LOWMEM, OPTION_LOWMEM);
|
||||
}
|
||||
|
||||
if (theCommandLine.hasOption(OPTION_ALLOW_EXTERNAL_REFS)) {
|
||||
ourLog.info("Server is configured to allow external references");
|
||||
ContextPostgreSQLHolder.setAllowExternalRefs(true);
|
||||
}
|
||||
|
||||
if (theCommandLine.hasOption(OPTION_DISABLE_REFERENTIAL_INTEGRITY)) {
|
||||
ourLog.info("Server is configured to not enforce referential integrity");
|
||||
ContextPostgreSQLHolder.setDisableReferentialIntegrity(true);
|
||||
}
|
||||
|
||||
if (theCommandLine.hasOption(OPTION_EXTERNAL_ELASTICSEARCH)) {
|
||||
ourLog.info("Server is configured to use external elasticsearch");
|
||||
ContextPostgreSQLHolder.setExternalElasticsearch(true);
|
||||
}
|
||||
|
||||
ContextPostgreSQLHolder.setDatabaseUrl(theCommandLine.getOptionValue("u"));
|
||||
|
||||
String reuseSearchResults = theCommandLine.getOptionValue(OPTION_REUSE_SEARCH_RESULTS_MILLIS);
|
||||
if (reuseSearchResults != null) {
|
||||
if (reuseSearchResults.equals("off")) {
|
||||
ourLog.info("Server is configured to not reuse search results");
|
||||
ContextPostgreSQLHolder.setReuseCachedSearchResultsForMillis(null);
|
||||
} else {
|
||||
try {
|
||||
long reuseSearchResultsMillis = Long.parseLong(reuseSearchResults);
|
||||
if (reuseSearchResultsMillis < 0) {
|
||||
throw new NumberFormatException("expected a positive integer");
|
||||
}
|
||||
ourLog.info("Server is configured to reuse search results for " + String.valueOf(reuseSearchResultsMillis) + " milliseconds");
|
||||
ContextPostgreSQLHolder.setReuseCachedSearchResultsForMillis(reuseSearchResultsMillis);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ParseException("Invalid value '" + reuseSearchResults + "' (must be a positive integer)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContextPostgreSQLHolder.setCtx(getFhirContext());
|
||||
|
||||
|
||||
|
||||
ourLog.info("Preparing HAPI FHIR JPA server on port {}", myPort);
|
||||
File tempWarFile;
|
||||
try {
|
||||
tempWarFile = File.createTempFile("hapi-fhir", ".war");
|
||||
tempWarFile.deleteOnExit();
|
||||
|
||||
InputStream inStream = RunJpaServerWithElasticsearchCommand.class.getResourceAsStream("/hapi-fhir-cli-jpaserver.war");
|
||||
OutputStream outStream = new BufferedOutputStream(new FileOutputStream(tempWarFile, false));
|
||||
IOUtils.copy(inStream, outStream);
|
||||
} catch (IOException e) {
|
||||
ourLog.error("Failed to create temporary file", e);
|
||||
return;
|
||||
}
|
||||
|
||||
final ContextLoaderListener cll = new ContextLoaderListener();
|
||||
|
||||
ourLog.info("Starting HAPI FHIR JPA server in {} mode", ContextPostgreSQLHolder.getCtx().getVersion().getVersion());
|
||||
WebAppContext root = new WebAppContext();
|
||||
root.setAllowDuplicateFragmentNames(true);
|
||||
root.setWar(tempWarFile.getAbsolutePath());
|
||||
root.setParentLoaderPriority(true);
|
||||
root.setContextPath("/");
|
||||
root.addEventListener(new ServletContextListener() {
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent theSce) {
|
||||
theSce.getServletContext().setInitParameter(ContextLoader.CONTEXT_CLASS_PARAM, AnnotationConfigWebApplicationContext.class.getName());
|
||||
switch (ContextPostgreSQLHolder.getCtx().getVersion().getVersion()) {
|
||||
case DSTU2:
|
||||
theSce.getServletContext().setInitParameter(ContextLoader.CONFIG_LOCATION_PARAM, FhirServerConfig.class.getName());
|
||||
break;
|
||||
case DSTU3:
|
||||
theSce.getServletContext().setInitParameter(ContextLoader.CONFIG_LOCATION_PARAM, FhirServerConfigDstu3.class.getName());
|
||||
break;
|
||||
case R4:
|
||||
theSce.getServletContext().setInitParameter(ContextLoader.CONFIG_LOCATION_PARAM, FhirServerElasticsearchConfigR4.class.getName());
|
||||
break;
|
||||
case DSTU2_1:
|
||||
case DSTU2_HL7ORG:
|
||||
break;
|
||||
}
|
||||
cll.contextInitialized(theSce);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent theSce) {
|
||||
cll.contextDestroyed(theSce);
|
||||
}
|
||||
});
|
||||
|
||||
String path = ContextPostgreSQLHolder.getPath();
|
||||
root.addServlet("ca.uhn.fhir.jpa.demo.JpaServerDemo", path + "*");
|
||||
|
||||
myServer = new Server(myPort);
|
||||
myServer.setHandler(root);
|
||||
try {
|
||||
myServer.start();
|
||||
} catch (SocketException e) {
|
||||
throw new CommandFailureException("Server failed to start on port " + myPort + " because of the following error \"" + e.toString() + "\". Note that you can use the '-p' option to specify an alternate port.");
|
||||
} catch (Exception e) {
|
||||
ourLog.error("Server failed to start", e);
|
||||
throw new CommandFailureException("Server failed to start", e);
|
||||
}
|
||||
|
||||
ourLog.info("Server started on port {}", myPort);
|
||||
ourLog.info("Web Testing UI : http://localhost:{}/", myPort);
|
||||
ourLog.info("Server Base URL: http://localhost:{}{}", myPort, path);
|
||||
|
||||
// Never quit.. We'll let the user ctrl-C their way out.
|
||||
loopForever();
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("InfiniteLoopStatement")
|
||||
private void loopForever() {
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(DateUtils.MILLIS_PER_MINUTE);
|
||||
} catch (InterruptedException theE) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] theArgs) {
|
||||
|
||||
|
||||
Server server = new Server(22);
|
||||
String path = "../hapi-fhir-cli-jpaserver";
|
||||
WebAppContext webAppContext = new WebAppContext();
|
||||
webAppContext.setContextPath("/");
|
||||
webAppContext.setDescriptor(path + "/src/main/webapp/WEB-INF/web.xml");
|
||||
webAppContext.setResourceBase(path + "/target/hapi-fhir-jpaserver-example");
|
||||
webAppContext.setParentLoaderPriority(true);
|
||||
|
||||
server.setHandler(webAppContext);
|
||||
try {
|
||||
server.start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
ourLog.info("Started");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandDescription() {
|
||||
return "Start a FHIR server which can be used for testing";
|
||||
}
|
||||
|
||||
}
|
@ -136,6 +136,10 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -35,7 +35,8 @@ import java.util.Properties;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Configuration
|
||||
// TODO: Merge this with new CommonPostgreSQLConfig or find way to avoid conflicts with it.
|
||||
//@Configuration
|
||||
public class CommonConfig {
|
||||
|
||||
/**
|
||||
|
180
hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/CommonPostgreSQLConfig.java
Normal file
180
hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/CommonPostgreSQLConfig.java
Normal file
@ -0,0 +1,180 @@
|
||||
package ca.uhn.fhir.jpa.demo;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR - Command Line Client - Server WAR
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
||||
import ca.uhn.fhir.jpa.model.entity.ModelConfig;
|
||||
import ca.uhn.fhir.jpa.search.LuceneSearchMappingFactory;
|
||||
import ca.uhn.fhir.jpa.search.elastic.ElasticsearchHibernatePropertiesBuilder;
|
||||
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl;
|
||||
import org.apache.commons.dbcp2.BasicDataSource;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.hibernate.search.elasticsearch.cfg.ElasticsearchIndexStatus;
|
||||
import org.hibernate.search.elasticsearch.cfg.IndexSchemaManagementStrategy;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import pl.allegro.tech.embeddedelasticsearch.EmbeddedElastic;
|
||||
import pl.allegro.tech.embeddedelasticsearch.PopularProperties;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
@SuppressWarnings("Duplicates")
|
||||
@Configuration
|
||||
public class CommonPostgreSQLConfig {
|
||||
|
||||
static String elasticsearchHost = "localhost";
|
||||
static String elasticsearchUserId = "";
|
||||
static String elasticsearchPassword = "";
|
||||
static Integer elasticsearchPort;
|
||||
|
||||
/**
|
||||
* Configure FHIR properties around the the JPA server via this bean
|
||||
*/
|
||||
@Bean
|
||||
public DaoConfig daoConfig() {
|
||||
DaoConfig retVal = new DaoConfig();
|
||||
retVal.setSubscriptionEnabled(true);
|
||||
retVal.setSubscriptionPollDelay(5000);
|
||||
retVal.setSubscriptionPurgeInactiveAfterMillis(DateUtils.MILLIS_PER_HOUR);
|
||||
retVal.setAllowMultipleDelete(true);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ModelConfig modelConfig() {
|
||||
return daoConfig().getModelConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* The following bean configures the database connection. The 'url' property value of "jdbc:postgresql://localhost:5432/hapi" indicates that the server should save resources in a
|
||||
* PostgreSQL database named "hapi".
|
||||
*
|
||||
* A URL to a remote database could also be placed here, along with login credentials and other properties supported by BasicDataSource.
|
||||
*/
|
||||
@Bean(destroyMethod = "close")
|
||||
public DataSource dataSource() {
|
||||
String dbUrl = "jdbc:postgresql://localhost:5432/hapi";
|
||||
String dbUsername = "hapi";
|
||||
String dbPassword = "HapiFHIR";
|
||||
if (isNotBlank(ContextPostgreSQLHolder.getDatabaseUrl())) {
|
||||
dbUrl = ContextPostgreSQLHolder.getDatabaseUrl();
|
||||
}
|
||||
|
||||
BasicDataSource retVal = new BasicDataSource();
|
||||
retVal.setDriverClassName("org.postgresql.Driver");
|
||||
retVal.setUrl(dbUrl);
|
||||
retVal.setUsername(dbUsername);
|
||||
retVal.setPassword(dbPassword);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Properties jpaProperties() {
|
||||
|
||||
if(ContextPostgreSQLHolder.isExternalElasticsearch()) {
|
||||
elasticsearchUserId = "elastic";
|
||||
elasticsearchPassword = "changeme";
|
||||
elasticsearchPort = 9301;
|
||||
} else {
|
||||
elasticsearchPort = embeddedElasticSearch().getHttpPort();
|
||||
}
|
||||
|
||||
Properties extraProperties = new Properties();
|
||||
extraProperties.put("hibernate.dialect", org.hibernate.dialect.PostgreSQL94Dialect.class.getName());
|
||||
extraProperties.put("hibernate.format_sql", "false");
|
||||
extraProperties.put("hibernate.show_sql", "false");
|
||||
extraProperties.put("hibernate.hbm2ddl.auto", "update");
|
||||
extraProperties.put("hibernate.jdbc.batch_size", "20");
|
||||
extraProperties.put("hibernate.cache.use_query_cache", "false");
|
||||
extraProperties.put("hibernate.cache.use_second_level_cache", "false");
|
||||
extraProperties.put("hibernate.cache.use_structured_entries", "false");
|
||||
extraProperties.put("hibernate.cache.use_minimal_puts", "false");
|
||||
extraProperties.put("hibernate.search.model_mapping", LuceneSearchMappingFactory.class.getName());
|
||||
extraProperties.put("hibernate.search.default.directory_provider", "local-heap");
|
||||
extraProperties.put("hibernate.search.lucene_version", "LUCENE_CURRENT");
|
||||
extraProperties.put("hibernate.search.default.worker.execution", "sync");
|
||||
|
||||
if (System.getProperty("lowmem") != null) {
|
||||
extraProperties.put("hibernate.search.autoregister_listeners", "false");
|
||||
}
|
||||
|
||||
new ElasticsearchHibernatePropertiesBuilder()
|
||||
.setDebugRefreshAfterWrite(true)
|
||||
.setDebugPrettyPrintJsonLog(true)
|
||||
.setIndexSchemaManagementStrategy(IndexSchemaManagementStrategy.CREATE)
|
||||
.setIndexManagementWaitTimeoutMillis(10000)
|
||||
.setRequiredIndexStatus(ElasticsearchIndexStatus.YELLOW)
|
||||
.setRestUrl("http://" + elasticsearchHost + ":" + elasticsearchPort)
|
||||
.setUsername(elasticsearchUserId)
|
||||
.setPassword(elasticsearchPassword)
|
||||
.apply(extraProperties);
|
||||
|
||||
// extraProperties.setProperty("hibernate.search.default.elasticsearch.refresh_after_write", "true");
|
||||
return extraProperties;
|
||||
}
|
||||
|
||||
@Bean()
|
||||
public ElasticsearchSvcImpl myElasticsearchSvc() throws IOException {
|
||||
if(ContextPostgreSQLHolder.isExternalElasticsearch()) {
|
||||
elasticsearchUserId = "elastic";
|
||||
elasticsearchPassword = "changeme";
|
||||
elasticsearchPort = 9301;
|
||||
} else {
|
||||
elasticsearchPort = embeddedElasticSearch().getHttpPort();
|
||||
}
|
||||
return new ElasticsearchSvcImpl(elasticsearchHost, elasticsearchPort, elasticsearchUserId, elasticsearchPassword);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EmbeddedElastic embeddedElasticSearch() {
|
||||
String ELASTIC_VERSION = "6.5.4";
|
||||
|
||||
EmbeddedElastic embeddedElastic;
|
||||
try {
|
||||
embeddedElastic = EmbeddedElastic.builder()
|
||||
.withElasticVersion(ELASTIC_VERSION)
|
||||
.withSetting(PopularProperties.TRANSPORT_TCP_PORT, 0)
|
||||
.withSetting(PopularProperties.HTTP_PORT, 0)
|
||||
.withSetting(PopularProperties.CLUSTER_NAME, UUID.randomUUID())
|
||||
.withStartTimeout(60, TimeUnit.SECONDS)
|
||||
.build()
|
||||
.start();
|
||||
} catch (IOException | InterruptedException e) {
|
||||
throw new ConfigurationException(e);
|
||||
}
|
||||
|
||||
return embeddedElastic;
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void stop() {
|
||||
embeddedElasticSearch().stop();
|
||||
}
|
||||
|
||||
}
|
89
hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextPostgreSQLHolder.java
Normal file
89
hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/ContextPostgreSQLHolder.java
Normal file
@ -0,0 +1,89 @@
|
||||
package ca.uhn.fhir.jpa.demo;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR - Command Line Client - Server WAR
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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%
|
||||
*/
|
||||
|
||||
public class ContextPostgreSQLHolder extends ContextHolder {
|
||||
|
||||
// private static String myDbUsername;
|
||||
// private static String myDbPassword;
|
||||
private static boolean myExternalElasticsearch = false;
|
||||
// private static String myElasticsearchHost;
|
||||
// private static Integer myElasticsearchPort;
|
||||
// private static String myElasticsearchUsername;
|
||||
// private static String myElasticsearchPassword;
|
||||
|
||||
/* public static void setDbUsername(String theDbUsername) {
|
||||
myDbUsername = theDbUsername;
|
||||
}
|
||||
|
||||
public static String getDbUsername() {
|
||||
return myDbUsername;
|
||||
}
|
||||
|
||||
public static void setDbPassword(String theDbPassword) {
|
||||
myDbPassword = theDbPassword;
|
||||
}
|
||||
|
||||
public static String getDbPassword() {
|
||||
return myDbPassword;
|
||||
}
|
||||
*/
|
||||
public static void setExternalElasticsearch(Boolean theExternalElasticsearch) {
|
||||
myExternalElasticsearch = theExternalElasticsearch;
|
||||
}
|
||||
|
||||
public static Boolean isExternalElasticsearch() {
|
||||
return myExternalElasticsearch;
|
||||
}
|
||||
/*
|
||||
public static void setElasticsearchHost(String theElasticsearchHost) {
|
||||
myElasticsearchHost = theElasticsearchHost;
|
||||
}
|
||||
|
||||
public static String getElasticsearchHost() {
|
||||
return myElasticsearchHost;
|
||||
}
|
||||
|
||||
public static void setElasticsearchPort(Integer theElasticsearchPort) {
|
||||
myElasticsearchPort = theElasticsearchPort;
|
||||
}
|
||||
|
||||
public static Integer getElasticsearchPort() {
|
||||
return myElasticsearchPort;
|
||||
}
|
||||
|
||||
public static void setElasticsearchUsername(String theElasticsearchUsername) {
|
||||
myElasticsearchUsername = theElasticsearchUsername;
|
||||
}
|
||||
|
||||
public static String getElasticsearchUsername() {
|
||||
return myElasticsearchUsername;
|
||||
}
|
||||
|
||||
public static void setElasticsearchPassword(String theElasticsearchPassword) {
|
||||
myElasticsearchPassword = theElasticsearchPassword;
|
||||
}
|
||||
|
||||
public static String getElasticsearchPassword() {
|
||||
return myElasticsearchPassword;
|
||||
}
|
||||
*/
|
||||
}
|
107
hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/FhirServerElasticsearchConfigR4.java
Normal file
107
hapi-fhir-cli/hapi-fhir-cli-jpaserver/src/main/java/ca/uhn/fhir/jpa/demo/FhirServerElasticsearchConfigR4.java
Normal file
@ -0,0 +1,107 @@
|
||||
package ca.uhn.fhir.jpa.demo;
|
||||
|
||||
/*-
|
||||
* #%L
|
||||
* HAPI FHIR - Command Line Client - Server WAR
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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.jpa.config.BaseJavaConfigR4;
|
||||
import ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptorR4;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
|
||||
import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
|
||||
import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* This class isn't used by default by the example, but
|
||||
* you can use it as a config if you want to support DSTU3
|
||||
* instead of DSTU2 in your server.
|
||||
* <p>
|
||||
* See https://github.com/jamesagnew/hapi-fhir/issues/278
|
||||
*/
|
||||
@Configuration
|
||||
@EnableTransactionManagement()
|
||||
@Import(CommonPostgreSQLConfig.class)
|
||||
public class FhirServerElasticsearchConfigR4 extends BaseJavaConfigR4 {
|
||||
|
||||
@Autowired
|
||||
private DataSource myDataSource;
|
||||
@Autowired()
|
||||
@Qualifier("jpaProperties")
|
||||
private Properties myJpaProperties;
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
|
||||
LocalContainerEntityManagerFactoryBean retVal = super.entityManagerFactory();
|
||||
retVal.setPersistenceUnitName("HAPI_PU");
|
||||
retVal.setDataSource(myDataSource);
|
||||
retVal.setJpaProperties(myJpaProperties);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do some fancy logging to create a nice access log that has details about each incoming request.
|
||||
* @return
|
||||
*/
|
||||
public LoggingInterceptor loggingInterceptor() {
|
||||
LoggingInterceptor retVal = new LoggingInterceptor();
|
||||
retVal.setLoggerName("fhirtest.access");
|
||||
retVal.setMessageFormat(
|
||||
"Path[${servletPath}] Source[${requestHeader.x-forwarded-for}] Operation[${operationType} ${operationName} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}] ResponseEncoding[${responseEncodingNoDefault}]");
|
||||
retVal.setLogExceptions(true);
|
||||
retVal.setErrorMessageFormat("ERROR - ${requestVerb} ${requestUrl}");
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* This interceptor adds some pretty syntax highlighting in responses when a browser is detected
|
||||
* @return
|
||||
*/
|
||||
@Bean(autowire = Autowire.BY_TYPE)
|
||||
public ResponseHighlighterInterceptor responseHighlighterInterceptor() {
|
||||
ResponseHighlighterInterceptor retVal = new ResponseHighlighterInterceptor();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Bean(autowire = Autowire.BY_TYPE)
|
||||
public IServerInterceptor subscriptionSecurityInterceptor() {
|
||||
SubscriptionsRequireManualActivationInterceptorR4 retVal = new SubscriptionsRequireManualActivationInterceptorR4();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
|
||||
JpaTransactionManager retVal = new JpaTransactionManager();
|
||||
retVal.setEntityManagerFactory(entityManagerFactory);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
@ -285,6 +285,7 @@ public abstract class BaseConfig {
|
||||
|
||||
public static void configureEntityManagerFactory(LocalContainerEntityManagerFactoryBean theFactory, FhirContext theCtx) {
|
||||
theFactory.setJpaDialect(hibernateJpaDialect(theCtx.getLocalizer()));
|
||||
//TODO: Consider moving the jpa.dao.lastn.entity.* classes into jpa.entity at some point.
|
||||
theFactory.setPackagesToScan("ca.uhn.fhir.jpa.model.entity", "ca.uhn.fhir.jpa.entity", "ca.uhn.fhir.jpa.dao.lastn.entity");
|
||||
theFactory.setPersistenceProvider(new HibernatePersistenceProvider());
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||
import ca.uhn.fhir.jpa.dao.TransactionProcessor;
|
||||
import ca.uhn.fhir.jpa.dao.dstu3.TransactionProcessorVersionAdapterDstu3;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistDstu3Svc;
|
||||
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorDstu3;
|
||||
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
|
||||
@ -17,10 +18,7 @@ import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||
import ca.uhn.fhir.jpa.util.ResourceCountCache;
|
||||
import ca.uhn.fhir.validation.IInstanceValidatorModule;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
|
||||
import org.hl7.fhir.r5.utils.IResourceValidator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
@ -131,4 +129,9 @@ public class BaseDstu3Config extends BaseConfigDstu3Plus {
|
||||
return new TermReadSvcDstu3();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ObservationLastNIndexPersistDstu3Svc observationLastNIndexpersistSvc() {
|
||||
return new ObservationLastNIndexPersistDstu3Svc();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||
import ca.uhn.fhir.jpa.dao.TransactionProcessor;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistSvc;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistR4Svc;
|
||||
import ca.uhn.fhir.jpa.dao.r4.TransactionProcessorVersionAdapterR4;
|
||||
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR4;
|
||||
@ -18,10 +18,7 @@ import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||
import ca.uhn.fhir.jpa.util.ResourceCountCache;
|
||||
import ca.uhn.fhir.validation.IInstanceValidatorModule;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
|
||||
import org.hl7.fhir.r5.utils.IResourceValidator;
|
||||
import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -136,10 +133,8 @@ public class BaseR4Config extends BaseConfigDstu3Plus {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ObservationLastNIndexPersistSvc observationLastNIndexpersistSvc() {
|
||||
return new ObservationLastNIndexPersistSvc();
|
||||
public ObservationLastNIndexPersistR4Svc observationLastNIndexpersistSvc() {
|
||||
return new ObservationLastNIndexPersistR4Svc();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import ca.uhn.fhir.jpa.dao.FulltextSearchSvcImpl;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
||||
import ca.uhn.fhir.jpa.dao.TransactionProcessor;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistR5Svc;
|
||||
import ca.uhn.fhir.jpa.dao.r5.TransactionProcessorVersionAdapterR5;
|
||||
import ca.uhn.fhir.jpa.provider.GraphQLProvider;
|
||||
import ca.uhn.fhir.jpa.searchparam.extractor.SearchParamExtractorR5;
|
||||
@ -17,11 +18,8 @@ import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR5;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||
import ca.uhn.fhir.jpa.util.ResourceCountCache;
|
||||
import ca.uhn.fhir.validation.IInstanceValidatorModule;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
|
||||
import org.hl7.fhir.r5.model.Bundle;
|
||||
import org.hl7.fhir.r5.utils.IResourceValidator;
|
||||
import org.springframework.beans.factory.annotation.Autowire;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -135,4 +133,9 @@ public class BaseR5Config extends BaseConfigDstu3Plus {
|
||||
return new TermReadSvcR5();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ObservationLastNIndexPersistR5Svc observationLastNIndexpersistSvc() {
|
||||
return new ObservationLastNIndexPersistR5Svc();
|
||||
}
|
||||
|
||||
}
|
||||
|
34
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFhirResourceDaoObservation.java
Normal file
34
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/IFhirResourceDaoObservation.java
Normal file
@ -0,0 +1,34 @@
|
||||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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%
|
||||
*/
|
||||
|
||||
public interface IFhirResourceDaoObservation<T extends IBaseResource> extends IFhirResourceDao<T> {
|
||||
|
||||
IBundleProvider observationsLastN(SearchParameterMap paramMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse);
|
||||
|
||||
}
|
@ -45,6 +45,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTag;
|
||||
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
|
||||
import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
|
||||
import ca.uhn.fhir.jpa.search.lastn.IElasticsearchSvc;
|
||||
import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
|
||||
@ -110,6 +111,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
@ -152,6 +154,8 @@ public class SearchBuilder implements ISearchBuilder {
|
||||
private IdHelperService myIdHelperService;
|
||||
@Autowired(required = false)
|
||||
private IFulltextSearchSvc myFulltextSearchSvc;
|
||||
@Autowired(required = false)
|
||||
private IElasticsearchSvc myIElasticsearchSvc;
|
||||
@Autowired
|
||||
private ISearchParamRegistry mySearchParamRegistry;
|
||||
@Autowired
|
||||
@ -314,22 +318,51 @@ public class SearchBuilder implements ISearchBuilder {
|
||||
}
|
||||
|
||||
/*
|
||||
* Fulltext search
|
||||
* Fulltext search and lastn
|
||||
*/
|
||||
if (myParams.containsKey(Constants.PARAM_CONTENT) || myParams.containsKey(Constants.PARAM_TEXT)) {
|
||||
if (myFulltextSearchSvc == null) {
|
||||
if (myParams.containsKey(Constants.PARAM_TEXT)) {
|
||||
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
|
||||
} else if (myParams.containsKey(Constants.PARAM_CONTENT)) {
|
||||
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_CONTENT);
|
||||
if (myParams.containsKey(Constants.PARAM_CONTENT) || myParams.containsKey(Constants.PARAM_TEXT) || myParams.isLastN()) {
|
||||
List<ResourcePersistentId> lastnPids = new ArrayList<>();
|
||||
List<ResourcePersistentId> fullTextSearchPids = new ArrayList<>();
|
||||
|
||||
if (myParams.containsKey(Constants.PARAM_CONTENT) || myParams.containsKey(Constants.PARAM_TEXT)) {
|
||||
if (myFulltextSearchSvc == null) {
|
||||
if (myParams.containsKey(Constants.PARAM_TEXT)) {
|
||||
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_TEXT);
|
||||
} else if (myParams.containsKey(Constants.PARAM_CONTENT)) {
|
||||
throw new InvalidRequestException("Fulltext search is not enabled on this service, can not process parameter: " + Constants.PARAM_CONTENT);
|
||||
}
|
||||
}
|
||||
|
||||
if (myParams.getEverythingMode() != null) {
|
||||
fullTextSearchPids = myFulltextSearchSvc.everything(myResourceName, myParams, theRequest);
|
||||
} else {
|
||||
fullTextSearchPids = myFulltextSearchSvc.search(myResourceName, myParams);
|
||||
}
|
||||
} else {
|
||||
if (myIElasticsearchSvc == null) {
|
||||
if (myParams.isLastN()) {
|
||||
throw new InvalidRequestException("LastN operation is not enabled on this service, can not process this request");
|
||||
}
|
||||
}
|
||||
|
||||
if (myParams.isLastN()) {
|
||||
lastnPids = myIElasticsearchSvc.executeLastN(myParams, theRequest, myIdHelperService);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
List<ResourcePersistentId> pids;
|
||||
if (myParams.getEverythingMode() != null) {
|
||||
pids = myFulltextSearchSvc.everything(myResourceName, myParams, theRequest);
|
||||
if (fullTextSearchPids.isEmpty()) {
|
||||
pids = lastnPids;
|
||||
} else if (lastnPids.isEmpty()) {
|
||||
pids = fullTextSearchPids;
|
||||
} else {
|
||||
pids = myFulltextSearchSvc.search(myResourceName, myParams);
|
||||
// Intersection of the fullTextSearchPids and lastnPids
|
||||
Set<ResourcePersistentId> pidIntersection = fullTextSearchPids.stream()
|
||||
.distinct()
|
||||
.filter(lastnPids::contains)
|
||||
.collect(Collectors.toSet());
|
||||
pids = new ArrayList<>(pidIntersection);
|
||||
}
|
||||
if (pids.isEmpty()) {
|
||||
// Will never match
|
||||
|
@ -2,8 +2,16 @@ package ca.uhn.fhir.jpa.dao.data;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.lastn.entity.ObservationIndexedCodeCodeableConceptEntity;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface IObservationIndexedCodeCodeableConceptSearchParamDao extends JpaRepository<ObservationIndexedCodeCodeableConceptEntity, Long> {
|
||||
@Query("" +
|
||||
"SELECT t FROM ObservationIndexedCodeCodeableConceptEntity t " +
|
||||
"WHERE t.myCodeableConceptId = :codeableConceptId" +
|
||||
"")
|
||||
ObservationIndexedCodeCodeableConceptEntity findByCodeableConceptId(@Param("codeableConceptId") String theCodeableConceptId);
|
||||
|
||||
}
|
||||
|
113
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoObservationDstu3.java
Normal file
113
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoObservationDstu3.java
Normal file
@ -0,0 +1,113 @@
|
||||
package ca.uhn.fhir.jpa.dao.dstu3;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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.jpa.dao.BaseHapiFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoObservation;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistDstu3Svc;
|
||||
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.rest.api.CacheControlDirective;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
public class FhirResourceDaoObservationDstu3 extends BaseHapiFhirResourceDao<Observation> implements IFhirResourceDaoObservation<Observation> {
|
||||
|
||||
@Autowired
|
||||
ObservationLastNIndexPersistDstu3Svc myObservationLastNIndexPersistDstu3Svc;
|
||||
|
||||
private IBundleProvider doLastNOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theContent != null) {
|
||||
paramMap.add(Constants.PARAM_CONTENT, theContent);
|
||||
}
|
||||
if (theNarrative != null) {
|
||||
paramMap.add(Constants.PARAM_TEXT, theNarrative);
|
||||
}
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setEverythingMode(theId != null ? EverythingModeEnum.PATIENT_INSTANCE : EverythingModeEnum.PATIENT_TYPE);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
if (theId != null) {
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
}
|
||||
|
||||
if (!isPagingProviderDatabaseBacked(theRequest)) {
|
||||
paramMap.setLoadSynchronous(true);
|
||||
}
|
||||
|
||||
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider observationsLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
|
||||
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
|
||||
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
|
||||
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
|
||||
|
||||
if(thePerformIndexing) {
|
||||
// Update indexes here for LastN operation.
|
||||
Observation observation = (Observation)theResource;
|
||||
Collection<ResourceLink> myResourceLinks = retVal.getResourceLinks();
|
||||
Long subjectID = null;
|
||||
for (ResourceLink resourceLink : myResourceLinks) {
|
||||
if(resourceLink.getSourcePath().equals("Observation.subject")) {
|
||||
subjectID = resourceLink.getTargetResourcePid();
|
||||
}
|
||||
}
|
||||
if (subjectID != null) {
|
||||
myObservationLastNIndexPersistDstu3Svc.indexObservation(observation, subjectID.toString());
|
||||
} else {
|
||||
myObservationLastNIndexPersistDstu3Svc.indexObservation(observation);
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
87
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistDstu3Svc.java
Normal file
87
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistDstu3Svc.java
Normal file
@ -0,0 +1,87 @@
|
||||
package ca.uhn.fhir.jpa.dao.lastn;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodeableConceptSearchParamDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodingSearchParamDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.entity.*;
|
||||
import org.hl7.fhir.dstu3.model.CodeableConcept;
|
||||
import org.hl7.fhir.dstu3.model.Coding;
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ObservationLastNIndexPersistDstu3Svc {
|
||||
|
||||
@Autowired
|
||||
IObservationIndexedSearchParamLastNDao myResourceIndexedObservationLastNDao;
|
||||
|
||||
@Autowired
|
||||
IObservationIndexedCodeCodeableConceptSearchParamDao myObservationIndexedCodeableConceptSearchParamDao;
|
||||
|
||||
@Autowired
|
||||
IObservationIndexedCodeCodingSearchParamDao myObservationIndexedCodeCodingSearchParamDao;
|
||||
|
||||
// TODO: Change theSubjectId to be a Long
|
||||
public void indexObservation(Observation theObservation, String theSubjectId) {
|
||||
ObservationIndexedSearchParamLastNEntity indexedObservation = new ObservationIndexedSearchParamLastNEntity();
|
||||
String resourcePID = theObservation.getIdElement().getIdPart();
|
||||
indexedObservation.setIdentifier(resourcePID);
|
||||
indexedObservation.setSubject(theSubjectId);
|
||||
Date effectiveDtm = theObservation.getEffectiveDateTimeType().getValue();
|
||||
indexedObservation.setEffectiveDtm(effectiveDtm);
|
||||
|
||||
// Build CodeableConcept entities for Observation.Category
|
||||
Set<ObservationIndexedCategoryCodeableConceptEntity> categoryConcepts = new HashSet<>();
|
||||
for(CodeableConcept categoryCodeableConcept : theObservation.getCategory()) {
|
||||
// Build Coding entities for each category CodeableConcept
|
||||
Set<ObservationIndexedCategoryCodingEntity> categoryCodingEntities = new HashSet<>();
|
||||
ObservationIndexedCategoryCodeableConceptEntity categoryCodeableConceptEntity = new ObservationIndexedCategoryCodeableConceptEntity(categoryCodeableConcept.getText());
|
||||
for(Coding categoryCoding : categoryCodeableConcept.getCoding()){
|
||||
categoryCodingEntities.add(new ObservationIndexedCategoryCodingEntity(categoryCoding.getSystem(), categoryCoding.getCode(), categoryCoding.getDisplay()));
|
||||
}
|
||||
categoryCodeableConceptEntity.setObservationIndexedCategoryCodingEntitySet(categoryCodingEntities);
|
||||
categoryConcepts.add(categoryCodeableConceptEntity);
|
||||
}
|
||||
indexedObservation.setCategoryCodeableConcepts(categoryConcepts);
|
||||
|
||||
// Build CodeableConcept entity for Observation.Code.
|
||||
CodeableConcept codeCodeableConcept = theObservation.getCode();
|
||||
String observationCodeNormalizedId = null;
|
||||
|
||||
// Determine if a Normalized ID was created previously for Observation Code
|
||||
for (Coding codeCoding : codeCodeableConcept.getCoding()) {
|
||||
if (codeCoding.hasCode() && codeCoding.hasSystem()) {
|
||||
observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForCodeAndSystem(codeCoding.getCode(), codeCoding.getSystem());
|
||||
} else {
|
||||
observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForDisplay(codeCoding.getDisplay());
|
||||
}
|
||||
}
|
||||
// Generate a new a normalized ID if necessary
|
||||
if (observationCodeNormalizedId == null) {
|
||||
observationCodeNormalizedId = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
// Create/update normalized Observation Code index record
|
||||
ObservationIndexedCodeCodeableConceptEntity codeableConceptField = new ObservationIndexedCodeCodeableConceptEntity(codeCodeableConcept.getText(), observationCodeNormalizedId);
|
||||
for (Coding codeCoding : codeCodeableConcept.getCoding()) {
|
||||
codeableConceptField.addCoding(new ObservationIndexedCodeCodingEntity(codeCoding.getSystem(), codeCoding.getCode(), codeCoding.getDisplay(), observationCodeNormalizedId));
|
||||
}
|
||||
myObservationIndexedCodeableConceptSearchParamDao.save(codeableConceptField);
|
||||
|
||||
indexedObservation.setObservationCode(codeableConceptField);
|
||||
indexedObservation.setCodeNormalizedId(observationCodeNormalizedId);
|
||||
myResourceIndexedObservationLastNDao.save(indexedObservation);
|
||||
|
||||
}
|
||||
|
||||
// TODO: Remove this once Unit tests are updated.
|
||||
public void indexObservation(Observation theObservation) {
|
||||
String subjectId = "Patient/" + theObservation.getSubject().getReference();
|
||||
|
||||
indexObservation(theObservation, subjectId);
|
||||
}
|
||||
}
|
88
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR4Svc.java
Normal file
88
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR4Svc.java
Normal file
@ -0,0 +1,88 @@
|
||||
package ca.uhn.fhir.jpa.dao.lastn;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodeableConceptSearchParamDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodingSearchParamDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.entity.*;
|
||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||
import org.hl7.fhir.r4.model.Coding;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ObservationLastNIndexPersistR4Svc {
|
||||
|
||||
@Autowired
|
||||
IObservationIndexedSearchParamLastNDao myResourceIndexedObservationLastNDao;
|
||||
|
||||
@Autowired
|
||||
IObservationIndexedCodeCodeableConceptSearchParamDao myObservationIndexedCodeableConceptSearchParamDao;
|
||||
|
||||
@Autowired
|
||||
IObservationIndexedCodeCodingSearchParamDao myObservationIndexedCodeCodingSearchParamDao;
|
||||
|
||||
// TODO: Change theSubjectId to be a Long
|
||||
public void indexObservation(Observation theObservation, String theSubjectId) {
|
||||
ObservationIndexedSearchParamLastNEntity indexedObservation = new ObservationIndexedSearchParamLastNEntity();
|
||||
String resourcePID = theObservation.getIdElement().getIdPart();
|
||||
indexedObservation.setIdentifier(resourcePID);
|
||||
indexedObservation.setSubject(theSubjectId);
|
||||
Date effectiveDtm = theObservation.getEffectiveDateTimeType().getValue();
|
||||
indexedObservation.setEffectiveDtm(effectiveDtm);
|
||||
|
||||
// Build CodeableConcept entities for Observation.Category
|
||||
Set<ObservationIndexedCategoryCodeableConceptEntity> categoryConcepts = new HashSet<>();
|
||||
for(CodeableConcept categoryCodeableConcept : theObservation.getCategory()) {
|
||||
// Build Coding entities for each category CodeableConcept
|
||||
Set<ObservationIndexedCategoryCodingEntity> categoryCodingEntities = new HashSet<>();
|
||||
ObservationIndexedCategoryCodeableConceptEntity categoryCodeableConceptEntity = new ObservationIndexedCategoryCodeableConceptEntity(categoryCodeableConcept.getText());
|
||||
for(Coding categoryCoding : categoryCodeableConcept.getCoding()){
|
||||
categoryCodingEntities.add(new ObservationIndexedCategoryCodingEntity(categoryCoding.getSystem(), categoryCoding.getCode(), categoryCoding.getDisplay()));
|
||||
}
|
||||
categoryCodeableConceptEntity.setObservationIndexedCategoryCodingEntitySet(categoryCodingEntities);
|
||||
categoryConcepts.add(categoryCodeableConceptEntity);
|
||||
}
|
||||
indexedObservation.setCategoryCodeableConcepts(categoryConcepts);
|
||||
|
||||
// Build CodeableConcept entity for Observation.Code.
|
||||
CodeableConcept codeCodeableConcept = theObservation.getCode();
|
||||
String observationCodeNormalizedId = null;
|
||||
|
||||
// Determine if a Normalized ID was created previously for Observation Code
|
||||
for (Coding codeCoding : codeCodeableConcept.getCoding()) {
|
||||
if (codeCoding.hasCode() && codeCoding.hasSystem()) {
|
||||
observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForCodeAndSystem(codeCoding.getCode(), codeCoding.getSystem());
|
||||
} else {
|
||||
observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForDisplay(codeCoding.getDisplay());
|
||||
}
|
||||
}
|
||||
// Generate a new a normalized ID if necessary
|
||||
if (observationCodeNormalizedId == null) {
|
||||
observationCodeNormalizedId = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
// Create/update normalized Observation Code index record
|
||||
ObservationIndexedCodeCodeableConceptEntity codeableConceptField = new ObservationIndexedCodeCodeableConceptEntity(codeCodeableConcept.getText(), observationCodeNormalizedId);
|
||||
for (Coding codeCoding : codeCodeableConcept.getCoding()) {
|
||||
codeableConceptField.addCoding(new ObservationIndexedCodeCodingEntity(codeCoding.getSystem(), codeCoding.getCode(), codeCoding.getDisplay(), observationCodeNormalizedId));
|
||||
}
|
||||
myObservationIndexedCodeableConceptSearchParamDao.save(codeableConceptField);
|
||||
codeableConceptField = myObservationIndexedCodeableConceptSearchParamDao.findByCodeableConceptId(observationCodeNormalizedId);
|
||||
|
||||
indexedObservation.setObservationCode(codeableConceptField);
|
||||
indexedObservation.setCodeNormalizedId(observationCodeNormalizedId);
|
||||
myResourceIndexedObservationLastNDao.save(indexedObservation);
|
||||
|
||||
}
|
||||
|
||||
// TODO: Remove this once Unit tests are updated.
|
||||
public void indexObservation(Observation theObservation) {
|
||||
String subjectId = "Patient/" + theObservation.getSubject().getReference();
|
||||
|
||||
indexObservation(theObservation, subjectId);
|
||||
}
|
||||
}
|
87
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR5Svc.java
Normal file
87
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/lastn/ObservationLastNIndexPersistR5Svc.java
Normal file
@ -0,0 +1,87 @@
|
||||
package ca.uhn.fhir.jpa.dao.lastn;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodeableConceptSearchParamDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodingSearchParamDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.entity.*;
|
||||
import org.hl7.fhir.r5.model.CodeableConcept;
|
||||
import org.hl7.fhir.r5.model.Coding;
|
||||
import org.hl7.fhir.r5.model.Observation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ObservationLastNIndexPersistR5Svc {
|
||||
|
||||
@Autowired
|
||||
IObservationIndexedSearchParamLastNDao myResourceIndexedObservationLastNDao;
|
||||
|
||||
@Autowired
|
||||
IObservationIndexedCodeCodeableConceptSearchParamDao myObservationIndexedCodeableConceptSearchParamDao;
|
||||
|
||||
@Autowired
|
||||
IObservationIndexedCodeCodingSearchParamDao myObservationIndexedCodeCodingSearchParamDao;
|
||||
|
||||
// TODO: Change theSubjectId to be a Long
|
||||
public void indexObservation(Observation theObservation, String theSubjectId) {
|
||||
ObservationIndexedSearchParamLastNEntity indexedObservation = new ObservationIndexedSearchParamLastNEntity();
|
||||
String resourcePID = theObservation.getIdElement().getIdPart();
|
||||
indexedObservation.setIdentifier(resourcePID);
|
||||
indexedObservation.setSubject(theSubjectId);
|
||||
Date effectiveDtm = theObservation.getEffectiveDateTimeType().getValue();
|
||||
indexedObservation.setEffectiveDtm(effectiveDtm);
|
||||
|
||||
// Build CodeableConcept entities for Observation.Category
|
||||
Set<ObservationIndexedCategoryCodeableConceptEntity> categoryConcepts = new HashSet<>();
|
||||
for(CodeableConcept categoryCodeableConcept : theObservation.getCategory()) {
|
||||
// Build Coding entities for each category CodeableConcept
|
||||
Set<ObservationIndexedCategoryCodingEntity> categoryCodingEntities = new HashSet<>();
|
||||
ObservationIndexedCategoryCodeableConceptEntity categoryCodeableConceptEntity = new ObservationIndexedCategoryCodeableConceptEntity(categoryCodeableConcept.getText());
|
||||
for(Coding categoryCoding : categoryCodeableConcept.getCoding()){
|
||||
categoryCodingEntities.add(new ObservationIndexedCategoryCodingEntity(categoryCoding.getSystem(), categoryCoding.getCode(), categoryCoding.getDisplay()));
|
||||
}
|
||||
categoryCodeableConceptEntity.setObservationIndexedCategoryCodingEntitySet(categoryCodingEntities);
|
||||
categoryConcepts.add(categoryCodeableConceptEntity);
|
||||
}
|
||||
indexedObservation.setCategoryCodeableConcepts(categoryConcepts);
|
||||
|
||||
// Build CodeableConcept entity for Observation.Code.
|
||||
CodeableConcept codeCodeableConcept = theObservation.getCode();
|
||||
String observationCodeNormalizedId = null;
|
||||
|
||||
// Determine if a Normalized ID was created previously for Observation Code
|
||||
for (Coding codeCoding : codeCodeableConcept.getCoding()) {
|
||||
if (codeCoding.hasCode() && codeCoding.hasSystem()) {
|
||||
observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForCodeAndSystem(codeCoding.getCode(), codeCoding.getSystem());
|
||||
} else {
|
||||
observationCodeNormalizedId = myObservationIndexedCodeCodingSearchParamDao.findForDisplay(codeCoding.getDisplay());
|
||||
}
|
||||
}
|
||||
// Generate a new a normalized ID if necessary
|
||||
if (observationCodeNormalizedId == null) {
|
||||
observationCodeNormalizedId = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
// Create/update normalized Observation Code index record
|
||||
ObservationIndexedCodeCodeableConceptEntity codeableConceptField = new ObservationIndexedCodeCodeableConceptEntity(codeCodeableConcept.getText(), observationCodeNormalizedId);
|
||||
for (Coding codeCoding : codeCodeableConcept.getCoding()) {
|
||||
codeableConceptField.addCoding(new ObservationIndexedCodeCodingEntity(codeCoding.getSystem(), codeCoding.getCode(), codeCoding.getDisplay(), observationCodeNormalizedId));
|
||||
}
|
||||
myObservationIndexedCodeableConceptSearchParamDao.save(codeableConceptField);
|
||||
|
||||
indexedObservation.setObservationCode(codeableConceptField);
|
||||
indexedObservation.setCodeNormalizedId(observationCodeNormalizedId);
|
||||
myResourceIndexedObservationLastNDao.save(indexedObservation);
|
||||
|
||||
}
|
||||
|
||||
// TODO: Remove this once Unit tests are updated.
|
||||
public void indexObservation(Observation theObservation) {
|
||||
String subjectId = "Patient/" + theObservation.getSubject().getReference();
|
||||
|
||||
indexObservation(theObservation, subjectId);
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
//@Component
|
||||
public class ObservationLastNIndexPersistSvc {
|
||||
|
||||
@Autowired
|
||||
|
@ -25,8 +25,11 @@ public class ObservationIndexedCodeCodeableConceptEntity {
|
||||
private String myCodeableConceptText;
|
||||
|
||||
@IndexedEmbedded(depth=2, prefix = "coding")
|
||||
@OneToMany(mappedBy = "myCodeableConceptId", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||
private Set<ObservationIndexedCodeCodingEntity> myObservationIndexedCodeCodingEntitySet;
|
||||
// @OneToMany(mappedBy = "myCodeableConceptId", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||
@JoinColumn(name = "CODEABLE_CONCEPT_ID", nullable = false, updatable = false, foreignKey = @ForeignKey(name = "FK_CONCEPT_CODE"))
|
||||
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
|
||||
// private Set<ObservationIndexedCodeCodingEntity> myObservationIndexedCodeCodingEntitySet;
|
||||
private ObservationIndexedCodeCodingEntity myObservationIndexedCodeCodingEntity;
|
||||
|
||||
public ObservationIndexedCodeCodeableConceptEntity() {
|
||||
|
||||
@ -38,10 +41,11 @@ public class ObservationIndexedCodeCodeableConceptEntity {
|
||||
}
|
||||
|
||||
public void addCoding(ObservationIndexedCodeCodingEntity theObservationIndexedCodeCodingEntity) {
|
||||
if (myObservationIndexedCodeCodingEntitySet == null) {
|
||||
myObservationIndexedCodeCodingEntitySet = new HashSet<>();
|
||||
}
|
||||
myObservationIndexedCodeCodingEntitySet.add(theObservationIndexedCodeCodingEntity);
|
||||
// if (myObservationIndexedCodeCodingEntitySet == null) {
|
||||
// myObservationIndexedCodeCodingEntitySet = new HashSet<>();
|
||||
// }
|
||||
// myObservationIndexedCodeCodingEntitySet.add(theObservationIndexedCodeCodingEntity);
|
||||
myObservationIndexedCodeCodingEntity = theObservationIndexedCodeCodingEntity;
|
||||
}
|
||||
|
||||
public String getCodeableConceptId() {
|
||||
|
@ -11,11 +11,13 @@ import javax.persistence.*;
|
||||
@Table(name = "HFJ_SPIDX_LASTN_CODING")
|
||||
public class ObservationIndexedCodeCodingEntity {
|
||||
|
||||
@Id
|
||||
@SequenceGenerator(name = "SEQ_CODING_FIELD", sequenceName = "SEQ_CODING_FIELD")
|
||||
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CODING_FIELD")
|
||||
private Long myId;
|
||||
// TODO: Fix this to allow multiple codings for observation code
|
||||
// @Id
|
||||
// @SequenceGenerator(name = "SEQ_CODING_FIELD", sequenceName = "SEQ_CODING_FIELD")
|
||||
// @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CODING_FIELD")
|
||||
// private Long myId;
|
||||
|
||||
@Id
|
||||
@Column(name="CODEABLE_CONCEPT_ID")
|
||||
private String myCodeableConceptId;
|
||||
|
||||
|
@ -21,7 +21,11 @@ package ca.uhn.fhir.jpa.dao.r4;
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoObservation;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoPatient;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistR4Svc;
|
||||
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
|
||||
@ -38,42 +42,26 @@ import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
public class FhirResourceDaoObservationR4 extends BaseHapiFhirResourceDao<Observation> {
|
||||
public class FhirResourceDaoObservationR4 extends BaseHapiFhirResourceDao<Observation> implements IFhirResourceDaoObservation<Observation> {
|
||||
|
||||
private IBundleProvider doLastNOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theContent != null) {
|
||||
paramMap.add(Constants.PARAM_CONTENT, theContent);
|
||||
}
|
||||
if (theNarrative != null) {
|
||||
paramMap.add(Constants.PARAM_TEXT, theNarrative);
|
||||
}
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setEverythingMode(theId != null ? EverythingModeEnum.PATIENT_INSTANCE : EverythingModeEnum.PATIENT_TYPE);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
if (theId != null) {
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
}
|
||||
|
||||
if (!isPagingProviderDatabaseBacked(theRequest)) {
|
||||
paramMap.setLoadSynchronous(true);
|
||||
}
|
||||
|
||||
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequest);
|
||||
@Autowired
|
||||
ObservationLastNIndexPersistR4Svc myObservationLastNIndexPersistR4Svc;
|
||||
|
||||
@Override
|
||||
public IBundleProvider observationsLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
|
||||
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails);
|
||||
}
|
||||
|
||||
public IBundleProvider observationsLastN(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequestDetails) {
|
||||
return doLastNOperation(theId, theCount, theLastUpdated, theSort, theContent, theNarrative, theFilter, theRequestDetails);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
|
||||
@ -83,10 +71,21 @@ public class FhirResourceDaoObservationR4 extends BaseHapiFhirResourceDao<Observ
|
||||
if(thePerformIndexing) {
|
||||
// Update indexes here for LastN operation.
|
||||
Observation observation = (Observation)theResource;
|
||||
|
||||
Collection<ResourceLink> myResourceLinks = retVal.getResourceLinks();
|
||||
Long subjectID = null;
|
||||
for (ResourceLink resourceLink : myResourceLinks) {
|
||||
if(resourceLink.getSourcePath().equals("Observation.subject")) {
|
||||
subjectID = resourceLink.getTargetResourcePid();
|
||||
}
|
||||
}
|
||||
if (subjectID != null) {
|
||||
myObservationLastNIndexPersistR4Svc.indexObservation(observation, subjectID.toString());
|
||||
} else {
|
||||
myObservationLastNIndexPersistR4Svc.indexObservation(observation);
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
113
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoObservationR5.java
Normal file
113
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoObservationR5.java
Normal file
@ -0,0 +1,113 @@
|
||||
package ca.uhn.fhir.jpa.dao.r5;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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.jpa.dao.BaseHapiFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoObservation;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.ObservationLastNIndexPersistR5Svc;
|
||||
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
|
||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.rest.api.CacheControlDirective;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
import org.hl7.fhir.r5.model.Observation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
public class FhirResourceDaoObservationR5 extends BaseHapiFhirResourceDao<Observation> implements IFhirResourceDaoObservation<Observation> {
|
||||
|
||||
@Autowired
|
||||
ObservationLastNIndexPersistR5Svc myObservationLastNIndexPersistR5Svc;
|
||||
|
||||
private IBundleProvider doLastNOperation(IIdType theId, IPrimitiveType<Integer> theCount, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, RequestDetails theRequest) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
if (theCount != null) {
|
||||
paramMap.setCount(theCount.getValue());
|
||||
}
|
||||
if (theContent != null) {
|
||||
paramMap.add(Constants.PARAM_CONTENT, theContent);
|
||||
}
|
||||
if (theNarrative != null) {
|
||||
paramMap.add(Constants.PARAM_TEXT, theNarrative);
|
||||
}
|
||||
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
|
||||
paramMap.setEverythingMode(theId != null ? EverythingModeEnum.PATIENT_INSTANCE : EverythingModeEnum.PATIENT_TYPE);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
if (theId != null) {
|
||||
paramMap.add("_id", new StringParam(theId.getIdPart()));
|
||||
}
|
||||
|
||||
if (!isPagingProviderDatabaseBacked(theRequest)) {
|
||||
paramMap.setLoadSynchronous(true);
|
||||
}
|
||||
|
||||
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider observationsLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
|
||||
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
|
||||
boolean theUpdateVersion, Date theUpdateTime, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
|
||||
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theUpdateTime, theForceUpdate, theCreateNewHistoryEntry);
|
||||
|
||||
if(thePerformIndexing) {
|
||||
// Update indexes here for LastN operation.
|
||||
Observation observation = (Observation)theResource;
|
||||
Collection<ResourceLink> myResourceLinks = retVal.getResourceLinks();
|
||||
Long subjectID = null;
|
||||
for (ResourceLink resourceLink : myResourceLinks) {
|
||||
if(resourceLink.getSourcePath().equals("Observation.subject")) {
|
||||
subjectID = resourceLink.getTargetResourcePid();
|
||||
}
|
||||
}
|
||||
if (subjectID != null) {
|
||||
myObservationLastNIndexPersistR5Svc.indexObservation(observation, subjectID.toString());
|
||||
} else {
|
||||
myObservationLastNIndexPersistR5Svc.indexObservation(observation);
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
148
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaResourceProviderObservationDstu2.java
Normal file
148
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/BaseJpaResourceProviderObservationDstu2.java
Normal file
@ -0,0 +1,148 @@
|
||||
package ca.uhn.fhir.jpa.provider;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoObservation;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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%
|
||||
*/
|
||||
|
||||
public class BaseJpaResourceProviderObservationDstu2 extends JpaResourceProviderDstu2<Observation> {
|
||||
|
||||
/**
|
||||
* Observation/$lastn
|
||||
*/
|
||||
@Operation(name = JpaConstants.OPERATION_LASTN, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
|
||||
public IBundleProvider observationLastN(
|
||||
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
javax.servlet.http.HttpServletResponse theServletResponse,
|
||||
|
||||
ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a filter")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_FILTER)
|
||||
StringAndListParam theFtFilter,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a fulltext search")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT)
|
||||
StringAndListParam theFtContent,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's narrative using a fulltext search")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_TEXT)
|
||||
StringAndListParam theFtText,
|
||||
|
||||
@Description(shortDefinition="The classification of the type of observation")
|
||||
@OperationParam(name="category")
|
||||
TokenAndListParam theCategory,
|
||||
|
||||
@Description(shortDefinition="The code of the observation type")
|
||||
@OperationParam(name="code")
|
||||
TokenAndListParam theCode,
|
||||
|
||||
@Description(shortDefinition="Obtained date/time. If the obtained element is a period, a date that falls in the period")
|
||||
@OperationParam(name="date")
|
||||
DateRangeParam theDate,
|
||||
|
||||
@Description(shortDefinition="The maximum number of observations to return for each each observation code")
|
||||
@OperationParam(name="max", max=1, min=0)
|
||||
NumberParam theMax,
|
||||
|
||||
@Description(shortDefinition="The subject that the observation is about (if patient)")
|
||||
@OperationParam(name="patient")
|
||||
ReferenceAndListParam thePatient,
|
||||
|
||||
@Description(shortDefinition="The subject that the observation is about")
|
||||
@OperationParam(name="subject" )
|
||||
ReferenceAndListParam theSubject,
|
||||
|
||||
@IncludeParam(reverse=true)
|
||||
Set<Include> theRevIncludes,
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name="_lastUpdated")
|
||||
DateRangeParam theLastUpdated,
|
||||
|
||||
@IncludeParam(allow= {
|
||||
"Observation:based-on",
|
||||
"Observation:derived-from",
|
||||
"Observation:device",
|
||||
"Observation:encounter",
|
||||
"Observation:focus",
|
||||
"Observation:has-member",
|
||||
"Observation:part-of",
|
||||
"Observation:patient",
|
||||
"Observation:performer",
|
||||
"Observation:specimen",
|
||||
"Observation:subject",
|
||||
"*"
|
||||
})
|
||||
Set<Include> theIncludes,
|
||||
|
||||
@Sort
|
||||
SortSpec theSort,
|
||||
|
||||
@ca.uhn.fhir.rest.annotation.Count
|
||||
Integer theCount,
|
||||
|
||||
SummaryEnum theSummaryMode,
|
||||
|
||||
SearchTotalModeEnum theSearchTotalMode
|
||||
|
||||
) {
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_FILTER, theFtFilter);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT, theFtContent);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_TEXT, theFtText);
|
||||
paramMap.add("category", theCategory);
|
||||
paramMap.add("code", theCode);
|
||||
paramMap.add("date", theDate);
|
||||
paramMap.add("max", theMax);
|
||||
paramMap.add("patient", thePatient);
|
||||
paramMap.add("subject", theSubject);
|
||||
paramMap.setRevIncludes(theRevIncludes);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
paramMap.setIncludes(theIncludes);
|
||||
paramMap.setLastN(true);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setCount(theCount);
|
||||
paramMap.setSummaryMode(theSummaryMode);
|
||||
paramMap.setSearchTotalMode(theSearchTotalMode);
|
||||
|
||||
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
148
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderObservationDstu3.java
Normal file
148
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/dstu3/BaseJpaResourceProviderObservationDstu3.java
Normal file
@ -0,0 +1,148 @@
|
||||
package ca.uhn.fhir.jpa.provider.dstu3;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoObservation;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import org.hl7.fhir.dstu3.model.Observation;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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%
|
||||
*/
|
||||
|
||||
public class BaseJpaResourceProviderObservationDstu3 extends JpaResourceProviderDstu3<Observation> {
|
||||
|
||||
/**
|
||||
* Observation/$lastn
|
||||
*/
|
||||
@Operation(name = JpaConstants.OPERATION_LASTN, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
|
||||
public IBundleProvider observationLastN(
|
||||
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
javax.servlet.http.HttpServletResponse theServletResponse,
|
||||
|
||||
ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a filter")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_FILTER)
|
||||
StringAndListParam theFtFilter,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a fulltext search")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT)
|
||||
StringAndListParam theFtContent,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's narrative using a fulltext search")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_TEXT)
|
||||
StringAndListParam theFtText,
|
||||
|
||||
@Description(shortDefinition="The classification of the type of observation")
|
||||
@OperationParam(name="category")
|
||||
TokenAndListParam theCategory,
|
||||
|
||||
@Description(shortDefinition="The code of the observation type")
|
||||
@OperationParam(name="code")
|
||||
TokenAndListParam theCode,
|
||||
|
||||
@Description(shortDefinition="Obtained date/time. If the obtained element is a period, a date that falls in the period")
|
||||
@OperationParam(name="date")
|
||||
DateRangeParam theDate,
|
||||
|
||||
@Description(shortDefinition="The maximum number of observations to return for each each observation code")
|
||||
@OperationParam(name="max", max=1, min=0)
|
||||
NumberParam theMax,
|
||||
|
||||
@Description(shortDefinition="The subject that the observation is about (if patient)")
|
||||
@OperationParam(name="patient")
|
||||
ReferenceAndListParam thePatient,
|
||||
|
||||
@Description(shortDefinition="The subject that the observation is about")
|
||||
@OperationParam(name="subject" )
|
||||
ReferenceAndListParam theSubject,
|
||||
|
||||
@IncludeParam(reverse=true)
|
||||
Set<Include> theRevIncludes,
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name="_lastUpdated")
|
||||
DateRangeParam theLastUpdated,
|
||||
|
||||
@IncludeParam(allow= {
|
||||
"Observation:based-on",
|
||||
"Observation:derived-from",
|
||||
"Observation:device",
|
||||
"Observation:encounter",
|
||||
"Observation:focus",
|
||||
"Observation:has-member",
|
||||
"Observation:part-of",
|
||||
"Observation:patient",
|
||||
"Observation:performer",
|
||||
"Observation:specimen",
|
||||
"Observation:subject",
|
||||
"*"
|
||||
})
|
||||
Set<Include> theIncludes,
|
||||
|
||||
@Sort
|
||||
SortSpec theSort,
|
||||
|
||||
@ca.uhn.fhir.rest.annotation.Count
|
||||
Integer theCount,
|
||||
|
||||
SummaryEnum theSummaryMode,
|
||||
|
||||
SearchTotalModeEnum theSearchTotalMode
|
||||
|
||||
) {
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_FILTER, theFtFilter);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT, theFtContent);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_TEXT, theFtText);
|
||||
paramMap.add("category", theCategory);
|
||||
paramMap.add("code", theCode);
|
||||
paramMap.add("date", theDate);
|
||||
paramMap.add("max", theMax);
|
||||
paramMap.add("patient", thePatient);
|
||||
paramMap.add("subject", theSubject);
|
||||
paramMap.setRevIncludes(theRevIncludes);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
paramMap.setIncludes(theIncludes);
|
||||
paramMap.setLastN(true);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setCount(theCount);
|
||||
paramMap.setSummaryMode(theSummaryMode);
|
||||
paramMap.setSearchTotalMode(theSearchTotalMode);
|
||||
|
||||
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
149
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderObservationR4.java
Normal file
149
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r4/BaseJpaResourceProviderObservationR4.java
Normal file
@ -0,0 +1,149 @@
|
||||
package ca.uhn.fhir.jpa.provider.r4;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoObservation;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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%
|
||||
*/
|
||||
|
||||
public class BaseJpaResourceProviderObservationR4 extends JpaResourceProviderR4<Observation> {
|
||||
|
||||
/**
|
||||
* Observation/$lastn
|
||||
*/
|
||||
@Operation(name = JpaConstants.OPERATION_LASTN, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
|
||||
public IBundleProvider observationLastN(
|
||||
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
javax.servlet.http.HttpServletResponse theServletResponse,
|
||||
|
||||
ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a filter")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_FILTER)
|
||||
StringAndListParam theFtFilter,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a fulltext search")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT)
|
||||
StringAndListParam theFtContent,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's narrative using a fulltext search")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_TEXT)
|
||||
StringAndListParam theFtText,
|
||||
|
||||
@Description(shortDefinition="The classification of the type of observation")
|
||||
@OperationParam(name="category")
|
||||
TokenAndListParam theCategory,
|
||||
|
||||
@Description(shortDefinition="The code of the observation type")
|
||||
@OperationParam(name="code")
|
||||
TokenAndListParam theCode,
|
||||
|
||||
@Description(shortDefinition="Obtained date/time. If the obtained element is a period, a date that falls in the period")
|
||||
@OperationParam(name="date")
|
||||
DateRangeParam theDate,
|
||||
|
||||
// @Description(shortDefinition="The maximum number of observations to return for each each observation code")
|
||||
// @OperationParam(name="max", max=1, min=0)
|
||||
// NumberParam theMax,
|
||||
|
||||
@Description(shortDefinition="The subject that the observation is about (if patient)")
|
||||
@OperationParam(name="patient")
|
||||
ReferenceAndListParam thePatient,
|
||||
|
||||
@Description(shortDefinition="The subject that the observation is about")
|
||||
@OperationParam(name="subject" )
|
||||
ReferenceAndListParam theSubject,
|
||||
|
||||
@IncludeParam(reverse=true)
|
||||
Set<Include> theRevIncludes,
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name="_lastUpdated")
|
||||
DateRangeParam theLastUpdated,
|
||||
|
||||
@IncludeParam(allow= {
|
||||
"Observation:based-on",
|
||||
"Observation:derived-from",
|
||||
"Observation:device",
|
||||
"Observation:encounter",
|
||||
"Observation:focus",
|
||||
"Observation:has-member",
|
||||
"Observation:part-of",
|
||||
"Observation:patient",
|
||||
"Observation:performer",
|
||||
"Observation:specimen",
|
||||
"Observation:subject",
|
||||
"*"
|
||||
})
|
||||
Set<Include> theIncludes,
|
||||
|
||||
@Sort
|
||||
SortSpec theSort,
|
||||
|
||||
@ca.uhn.fhir.rest.annotation.Count
|
||||
Integer theCount,
|
||||
|
||||
SummaryEnum theSummaryMode,
|
||||
|
||||
SearchTotalModeEnum theSearchTotalMode
|
||||
|
||||
) {
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_FILTER, theFtFilter);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT, theFtContent);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_TEXT, theFtText);
|
||||
paramMap.add("category", theCategory);
|
||||
paramMap.add("code", theCode);
|
||||
paramMap.add("date", theDate);
|
||||
// paramMap.add("max", theMax);
|
||||
paramMap.add("patient", thePatient);
|
||||
paramMap.add("subject", theSubject);
|
||||
paramMap.setRevIncludes(theRevIncludes);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
paramMap.setIncludes(theIncludes);
|
||||
paramMap.setLastN(true);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setCount(theCount);
|
||||
paramMap.setSummaryMode(theSummaryMode);
|
||||
paramMap.setSearchTotalMode(theSearchTotalMode);
|
||||
|
||||
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
148
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/BaseJpaResourceProviderObservationR5.java
Normal file
148
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/provider/r5/BaseJpaResourceProviderObservationR5.java
Normal file
@ -0,0 +1,148 @@
|
||||
package ca.uhn.fhir.jpa.provider.r5;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoObservation;
|
||||
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import org.hl7.fhir.r5.model.Observation;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
* %%
|
||||
* Copyright (C) 2014 - 2020 University Health Network
|
||||
* %%
|
||||
* 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%
|
||||
*/
|
||||
|
||||
public class BaseJpaResourceProviderObservationR5 extends JpaResourceProviderR5<Observation> {
|
||||
|
||||
/**
|
||||
* Observation/$lastn
|
||||
*/
|
||||
@Operation(name = JpaConstants.OPERATION_LASTN, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
|
||||
public IBundleProvider observationLastN(
|
||||
|
||||
javax.servlet.http.HttpServletRequest theServletRequest,
|
||||
javax.servlet.http.HttpServletResponse theServletResponse,
|
||||
|
||||
ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a filter")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_FILTER)
|
||||
StringAndListParam theFtFilter,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's data using a fulltext search")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT)
|
||||
StringAndListParam theFtContent,
|
||||
|
||||
@Description(shortDefinition="Search the contents of the resource's narrative using a fulltext search")
|
||||
@OperationParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_TEXT)
|
||||
StringAndListParam theFtText,
|
||||
|
||||
@Description(shortDefinition="The classification of the type of observation")
|
||||
@OperationParam(name="category")
|
||||
TokenAndListParam theCategory,
|
||||
|
||||
@Description(shortDefinition="The code of the observation type")
|
||||
@OperationParam(name="code")
|
||||
TokenAndListParam theCode,
|
||||
|
||||
@Description(shortDefinition="Obtained date/time. If the obtained element is a period, a date that falls in the period")
|
||||
@OperationParam(name="date")
|
||||
DateRangeParam theDate,
|
||||
|
||||
@Description(shortDefinition="The maximum number of observations to return for each each observation code")
|
||||
@OperationParam(name="max", max=1, min=0)
|
||||
NumberParam theMax,
|
||||
|
||||
@Description(shortDefinition="The subject that the observation is about (if patient)")
|
||||
@OperationParam(name="patient")
|
||||
ReferenceAndListParam thePatient,
|
||||
|
||||
@Description(shortDefinition="The subject that the observation is about")
|
||||
@OperationParam(name="subject" )
|
||||
ReferenceAndListParam theSubject,
|
||||
|
||||
@IncludeParam(reverse=true)
|
||||
Set<Include> theRevIncludes,
|
||||
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
|
||||
@OperationParam(name="_lastUpdated")
|
||||
DateRangeParam theLastUpdated,
|
||||
|
||||
@IncludeParam(allow= {
|
||||
"Observation:based-on",
|
||||
"Observation:derived-from",
|
||||
"Observation:device",
|
||||
"Observation:encounter",
|
||||
"Observation:focus",
|
||||
"Observation:has-member",
|
||||
"Observation:part-of",
|
||||
"Observation:patient",
|
||||
"Observation:performer",
|
||||
"Observation:specimen",
|
||||
"Observation:subject",
|
||||
"*"
|
||||
})
|
||||
Set<Include> theIncludes,
|
||||
|
||||
@Sort
|
||||
SortSpec theSort,
|
||||
|
||||
@ca.uhn.fhir.rest.annotation.Count
|
||||
Integer theCount,
|
||||
|
||||
SummaryEnum theSummaryMode,
|
||||
|
||||
SearchTotalModeEnum theSearchTotalMode
|
||||
|
||||
) {
|
||||
startRequest(theServletRequest);
|
||||
try {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_FILTER, theFtFilter);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_CONTENT, theFtContent);
|
||||
paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_TEXT, theFtText);
|
||||
paramMap.add("category", theCategory);
|
||||
paramMap.add("code", theCode);
|
||||
paramMap.add("date", theDate);
|
||||
paramMap.add("max", theMax);
|
||||
paramMap.add("patient", thePatient);
|
||||
paramMap.add("subject", theSubject);
|
||||
paramMap.setRevIncludes(theRevIncludes);
|
||||
paramMap.setLastUpdated(theLastUpdated);
|
||||
paramMap.setIncludes(theIncludes);
|
||||
paramMap.setLastN(true);
|
||||
paramMap.setSort(theSort);
|
||||
paramMap.setCount(theCount);
|
||||
paramMap.setSummaryMode(theSummaryMode);
|
||||
paramMap.setSearchTotalMode(theSearchTotalMode);
|
||||
|
||||
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
|
||||
} finally {
|
||||
endRequest(theServletRequest);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +1,28 @@
|
||||
package ca.uhn.fhir.jpa.search.lastn;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.param.NumberParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.jpa.search.lastn.json.CodeJson;
|
||||
import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson;
|
||||
import ca.uhn.fhir.jpa.search.lastn.util.CodeSystemHash;
|
||||
import ca.uhn.fhir.rest.server.RestfulServerUtils;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
//import org.assertj.core.util.VisibleForTesting;
|
||||
import org.shadehapi.elasticsearch.action.admin.indices.create.CreateIndexRequest;
|
||||
import org.shadehapi.elasticsearch.action.admin.indices.create.CreateIndexResponse;
|
||||
import org.shadehapi.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
|
||||
import org.shadehapi.elasticsearch.action.admin.indices.get.GetIndexRequest;
|
||||
import org.shadehapi.elasticsearch.action.DocWriteResponse;
|
||||
import org.shadehapi.elasticsearch.action.index.IndexRequest;
|
||||
import org.shadehapi.elasticsearch.action.index.IndexResponse;
|
||||
import org.shadehapi.elasticsearch.action.search.SearchRequest;
|
||||
import org.shadehapi.elasticsearch.action.search.SearchResponse;
|
||||
import org.shadehapi.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.shadehapi.elasticsearch.client.RequestOptions;
|
||||
import org.shadehapi.elasticsearch.client.RestHighLevelClient;
|
||||
import org.shadehapi.elasticsearch.common.xcontent.XContentType;
|
||||
@ -39,7 +42,6 @@ import org.shadehapi.elasticsearch.search.aggregations.metrics.tophits.ParsedTop
|
||||
import org.shadehapi.elasticsearch.search.aggregations.support.ValueType;
|
||||
import org.shadehapi.elasticsearch.search.builder.SearchSourceBuilder;
|
||||
import org.shadehapi.elasticsearch.search.sort.SortOrder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@ -47,7 +49,6 @@ import java.util.List;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
//@Component
|
||||
public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
|
||||
RestHighLevelClient myRestHighLevelClient;
|
||||
@ -56,18 +57,17 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
|
||||
|
||||
public ElasticsearchSvcImpl(String theHostname, int thePort, String theUsername, String thePassword) {
|
||||
myRestHighLevelClient = ElasticsearchRestClientFactory.createElasticsearchHighLevelRestClient(theHostname, thePort, theUsername,thePassword);
|
||||
|
||||
myRestHighLevelClient = ElasticsearchRestClientFactory.createElasticsearchHighLevelRestClient(theHostname, thePort, theUsername,thePassword);
|
||||
try {
|
||||
createObservationIndexIfMissing();
|
||||
createCodeIndexIfMissing();
|
||||
} catch (IOException theE) {
|
||||
throw new RuntimeException("Failed to create document index", theE);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
createObservationIndexIfMissing();
|
||||
createCodeIndexIfMissing();
|
||||
} catch (IOException theE) {
|
||||
throw new RuntimeException("Failed to create document index", theE);
|
||||
}
|
||||
}
|
||||
|
||||
public void createObservationIndexIfMissing() throws IOException {
|
||||
private void createObservationIndexIfMissing() throws IOException {
|
||||
if(indexExists(IndexConstants.OBSERVATION_INDEX)) {
|
||||
return;
|
||||
}
|
||||
@ -129,7 +129,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
|
||||
}
|
||||
|
||||
public void createCodeIndexIfMissing() throws IOException {
|
||||
private void createCodeIndexIfMissing() throws IOException {
|
||||
if(indexExists(IndexConstants.CODE_INDEX)) {
|
||||
return;
|
||||
}
|
||||
@ -166,7 +166,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
|
||||
}
|
||||
|
||||
public boolean createIndex(String theIndexName, String theMapping) throws IOException {
|
||||
private boolean createIndex(String theIndexName, String theMapping) throws IOException {
|
||||
CreateIndexRequest request = new CreateIndexRequest(theIndexName);
|
||||
request.source(theMapping, XContentType.JSON);
|
||||
CreateIndexResponse createIndexResponse = myRestHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
|
||||
@ -174,12 +174,11 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
|
||||
}
|
||||
|
||||
public boolean performIndex(String theIndexName, String theDocumentId, String theIndexDocument, String theDocumentType) throws IOException {
|
||||
boolean performIndex(String theIndexName, String theDocumentId, String theIndexDocument, String theDocumentType) throws IOException {
|
||||
IndexResponse indexResponse = myRestHighLevelClient.index(createIndexRequest(theIndexName, theDocumentId,theIndexDocument,theDocumentType),
|
||||
RequestOptions.DEFAULT);
|
||||
|
||||
IndexResponse indexResponse = myRestHighLevelClient.index(createIndexRequest(theIndexName, theDocumentId,theIndexDocument,theDocumentType),
|
||||
RequestOptions.DEFAULT);
|
||||
|
||||
return (indexResponse.getResult() == DocWriteResponse.Result.CREATED) || (indexResponse.getResult() == DocWriteResponse.Result.UPDATED);
|
||||
return (indexResponse.getResult() == DocWriteResponse.Result.CREATED) || (indexResponse.getResult() == DocWriteResponse.Result.UPDATED);
|
||||
}
|
||||
|
||||
private IndexRequest createIndexRequest(String theIndexName, String theDocumentId, String theObservationDocument, String theDocumentType) {
|
||||
@ -191,12 +190,31 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
return request;
|
||||
}
|
||||
|
||||
public boolean indexExists(String theIndexName) throws IOException {
|
||||
private boolean indexExists(String theIndexName) throws IOException {
|
||||
GetIndexRequest request = new GetIndexRequest();
|
||||
request.indices(theIndexName);
|
||||
return myRestHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResourcePersistentId> executeLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, IdHelperService theIdHelperService) {
|
||||
Integer myMaxObservationsPerCode = 1;
|
||||
String[] maxCountParams = theRequestDetails.getParameters().get("map");
|
||||
if (maxCountParams != null && maxCountParams.length > 0) {
|
||||
myMaxObservationsPerCode = Integer.valueOf(maxCountParams[0]);
|
||||
}
|
||||
SearchRequest myLastNRequest = buildObservationCompositeSearchRequest(10000, theSearchParameterMap, myMaxObservationsPerCode);
|
||||
SearchResponse lastnResponse = null;
|
||||
try {
|
||||
lastnResponse = executeSearchRequest(myLastNRequest);
|
||||
List<ResourcePersistentId> observationIds = buildObservationIdList(lastnResponse, theIdHelperService);
|
||||
return observationIds;
|
||||
} catch (IOException theE) {
|
||||
throw new InvalidRequestException("Unable to execute LastN request", theE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SearchRequest buildObservationCodesSearchRequest(int theMaxResultSetSize) {
|
||||
SearchRequest searchRequest = new SearchRequest(IndexConstants.CODE_INDEX);
|
||||
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
|
||||
@ -236,15 +254,15 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
}
|
||||
|
||||
public SearchResponse executeSearchRequest(SearchRequest searchRequest) throws IOException {
|
||||
return myRestHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
|
||||
return myRestHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
|
||||
}
|
||||
|
||||
public List<ObservationJson> buildObservationCompositeResults(SearchResponse theSearchResponse) throws IOException {
|
||||
Aggregations responseAggregations = theSearchResponse.getAggregations();
|
||||
ParsedComposite aggregatedSubjects = responseAggregations.get("group_by_subject");
|
||||
List<ParsedComposite.ParsedBucket> subjectBuckets = aggregatedSubjects.getBuckets();
|
||||
List<ObservationJson> codes = new ArrayList<>();
|
||||
for(ParsedComposite.ParsedBucket subjectBucket : subjectBuckets) {
|
||||
Aggregations responseAggregations = theSearchResponse.getAggregations();
|
||||
ParsedComposite aggregatedSubjects = responseAggregations.get("group_by_subject");
|
||||
List<ParsedComposite.ParsedBucket> subjectBuckets = aggregatedSubjects.getBuckets();
|
||||
List<ObservationJson> codes = new ArrayList<>();
|
||||
for(ParsedComposite.ParsedBucket subjectBucket : subjectBuckets) {
|
||||
Aggregations observationCodeAggregations = subjectBucket.getAggregations();
|
||||
ParsedTerms aggregatedObservationCodes = observationCodeAggregations.get("group_by_code");
|
||||
List<? extends Terms.Bucket> observationCodeBuckets = aggregatedObservationCodes.getBuckets();
|
||||
@ -262,7 +280,30 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
return codes;
|
||||
}
|
||||
|
||||
public List<ObservationJson> buildObservationTermsResults(SearchResponse theSearchResponse) throws IOException {
|
||||
private List<ResourcePersistentId> buildObservationIdList(SearchResponse theSearchResponse, IdHelperService theIdHelperService) throws IOException {
|
||||
Aggregations responseAggregations = theSearchResponse.getAggregations();
|
||||
ParsedComposite aggregatedSubjects = responseAggregations.get("group_by_subject");
|
||||
List<ParsedComposite.ParsedBucket> subjectBuckets = aggregatedSubjects.getBuckets();
|
||||
List<ResourcePersistentId> myObservationIds = new ArrayList<>();
|
||||
for(ParsedComposite.ParsedBucket subjectBucket : subjectBuckets) {
|
||||
Aggregations observationCodeAggregations = subjectBucket.getAggregations();ParsedTerms aggregatedObservationCodes = observationCodeAggregations.get("group_by_code");
|
||||
List<? extends Terms.Bucket> observationCodeBuckets = aggregatedObservationCodes.getBuckets();
|
||||
for (Terms.Bucket observationCodeBucket : observationCodeBuckets) {
|
||||
Aggregations topHitObservationCodes = observationCodeBucket.getAggregations();
|
||||
ParsedTopHits parsedTopHits = topHitObservationCodes.get("most_recent_effective");
|
||||
SearchHit[] topHits = parsedTopHits.getHits().getHits();
|
||||
for (SearchHit topHit : topHits) {
|
||||
String sources = topHit.getSourceAsString();
|
||||
ObservationJson code = objectMapper.readValue(sources, ObservationJson.class);
|
||||
|
||||
myObservationIds.add(theIdHelperService.resolveResourcePersistentIds("Observation", code.getIdentifier()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return myObservationIds;
|
||||
}
|
||||
|
||||
public List<ObservationJson> buildObservationTermsResults(SearchResponse theSearchResponse) throws IOException {
|
||||
Aggregations responseAggregations = theSearchResponse.getAggregations();
|
||||
ParsedTerms aggregatedSubjects = responseAggregations.get("group_by_subject");
|
||||
List<? extends Terms.Bucket> subjectBuckets = aggregatedSubjects.getBuckets();
|
||||
@ -295,7 +336,6 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
return codes;
|
||||
}
|
||||
|
||||
// @VisibleForTesting
|
||||
public SearchRequest buildObservationAllFieldsCompositeSearchRequest(int maxResultSetSize, SearchParameterMap theSearchParameterMap, int theMaxObservationsPerCode) {
|
||||
|
||||
return buildObservationsSearchRequest(theSearchParameterMap, createCompositeAggregationBuilder(maxResultSetSize, theMaxObservationsPerCode, null));
|
||||
@ -307,7 +347,6 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
return buildObservationsSearchRequest(theSearchParameterMap, createCompositeAggregationBuilder(maxResultSetSize, theMaxObservationsPerCode, topHitsInclude));
|
||||
}
|
||||
|
||||
// @VisibleForTesting
|
||||
public SearchRequest buildObservationAllFieldsTermsSearchRequest(int maxResultSetSize, SearchParameterMap theSearchParameterMap, int theMaxObservationsPerCode) {
|
||||
return buildObservationsSearchRequest(theSearchParameterMap, createTermsAggregationBuilder(maxResultSetSize, theMaxObservationsPerCode, null));
|
||||
}
|
||||
@ -518,18 +557,7 @@ public class ElasticsearchSvcImpl implements IElasticsearchSvc {
|
||||
|
||||
}
|
||||
|
||||
// @VisibleForTesting
|
||||
public boolean deleteIndex(String theIndexName) throws IOException {
|
||||
DeleteIndexRequest request = new DeleteIndexRequest(theIndexName);
|
||||
AcknowledgedResponse deleteIndexResponse = myRestHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
|
||||
|
||||
return deleteIndexResponse.isAcknowledged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @VisibleForTesting
|
||||
public void deleteAllDocuments(String theIndexName) throws IOException {
|
||||
void deleteAllDocuments(String theIndexName) throws IOException {
|
||||
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(theIndexName);
|
||||
deleteByQueryRequest.setQuery(QueryBuilders.matchAllQuery());
|
||||
myRestHighLevelClient.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
|
||||
|
@ -2,6 +2,13 @@ package ca.uhn.fhir.jpa.search.lastn;
|
||||
|
||||
//import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
|
||||
import ca.uhn.fhir.jpa.model.cross.ResourcePersistentId;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IElasticsearchSvc {
|
||||
|
||||
|
||||
@ -9,4 +16,5 @@ public interface IElasticsearchSvc {
|
||||
|
||||
// IBundleProvider uniqueCodes(javax.servlet.http.HttpServletRequest theServletRequest, ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails);
|
||||
|
||||
List<ResourcePersistentId> executeLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, IdHelperService theIdHelperService);
|
||||
}
|
||||
|
26
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/config/ElasticsearchConfig.java
26
hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/lastn/config/ElasticsearchConfig.java
@ -1,26 +0,0 @@
|
||||
package ca.uhn.fhir.jpa.search.lastn.config;
|
||||
|
||||
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Configuration
|
||||
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory")
|
||||
@EnableTransactionManagement
|
||||
public class ElasticsearchConfig {
|
||||
|
||||
private final String elasticsearchHost = "127.0.0.1";
|
||||
private final Integer elasticsearchPort = 9301;
|
||||
private final String elasticsearchUserId = "elastic";
|
||||
private final String elasticsearchPassword = "changeme";
|
||||
|
||||
@Bean()
|
||||
public ElasticsearchSvcImpl myElasticsearchSvc() throws IOException {
|
||||
return new ElasticsearchSvcImpl(elasticsearchHost, elasticsearchPort, elasticsearchUserId, elasticsearchPassword);
|
||||
}
|
||||
|
||||
}
|
@ -53,16 +53,24 @@ public class ObservationJson {
|
||||
private String myCode_concept_text;
|
||||
|
||||
@JsonProperty(value = "codeconceptcodingcode", required = false)
|
||||
private List<String> myCode_coding_code = new ArrayList<>();
|
||||
// TODO: Temporary change until sort out how to deal with multiple observation code codings
|
||||
// private List<String> myCode_coding_code = new ArrayList<>();
|
||||
private String myCode_coding_code;
|
||||
|
||||
@JsonProperty(value = "codeconceptcodingcode_system_hash", required = false)
|
||||
private List<String> myCode_coding_code_system_hash = new ArrayList<>();
|
||||
// TODO: Temporary change until sort out how to deal with multiple observation code codings
|
||||
// private List<String> myCode_coding_code_system_hash = new ArrayList<>();
|
||||
private String myCode_coding_code_system_hash;
|
||||
|
||||
@JsonProperty(value = "codeconceptcodingdisplay", required = false)
|
||||
private List<String> myCode_coding_display = new ArrayList<>();
|
||||
// TODO: Temporary change until sort out how to deal with multiple observation code codings
|
||||
// private List<String> myCode_coding_display = new ArrayList<>();
|
||||
private String myCode_coding_display;
|
||||
|
||||
@JsonProperty(value = "codeconceptcodingsystem", required = false)
|
||||
private List<String> myCode_coding_system = new ArrayList<>();
|
||||
// TODO: Temporary change until sort out how to deal with multiple observation code codings
|
||||
// private List<String> myCode_coding_system = new ArrayList<>();
|
||||
private String myCode_coding_system;
|
||||
|
||||
@JsonProperty(value = "effectivedtm", required = true)
|
||||
private Date myEffectiveDtm;
|
||||
@ -120,10 +128,16 @@ public class ObservationJson {
|
||||
public void setCode(CodeableConcept theCode) {
|
||||
myCode_concept_text = theCode.getText();
|
||||
for(Coding theCodeCoding : theCode.getCoding()) {
|
||||
myCode_coding_code_system_hash.add(String.valueOf(CodeSystemHash.hashCodeSystem(theCodeCoding.getSystem(), theCodeCoding.getCode())));
|
||||
// TODO: Temporary change until address how to manage multiple Observation Code codings.
|
||||
/* myCode_coding_code_system_hash.add(String.valueOf(CodeSystemHash.hashCodeSystem(theCodeCoding.getSystem(), theCodeCoding.getCode())));
|
||||
myCode_coding_code.add(theCodeCoding.getCode());
|
||||
myCode_coding_display.add(theCodeCoding.getDisplay());
|
||||
myCode_coding_system.add(theCodeCoding.getSystem());
|
||||
*/
|
||||
myCode_coding_code_system_hash = String.valueOf(CodeSystemHash.hashCodeSystem(theCodeCoding.getSystem(), theCodeCoding.getCode()));
|
||||
myCode_coding_code = theCodeCoding.getCode();
|
||||
myCode_coding_display = theCodeCoding.getDisplay();
|
||||
myCode_coding_system = theCodeCoding.getSystem();
|
||||
}
|
||||
|
||||
}
|
||||
@ -132,6 +146,8 @@ public class ObservationJson {
|
||||
return myCode_concept_text;
|
||||
}
|
||||
|
||||
// TODO: Temporary changes until resolve problem of how to manage Observation Code with multiple codings
|
||||
/*
|
||||
public List<String> getCode_coding_code_system_hash() {
|
||||
return myCode_coding_code_system_hash;
|
||||
}
|
||||
@ -147,6 +163,22 @@ public class ObservationJson {
|
||||
public List<String> getCode_coding_system() {
|
||||
return myCode_coding_system;
|
||||
}
|
||||
*/
|
||||
public String getCode_coding_code_system_hash() {
|
||||
return myCode_coding_code_system_hash;
|
||||
}
|
||||
|
||||
public String getCode_coding_code() {
|
||||
return myCode_coding_code;
|
||||
}
|
||||
|
||||
public String getCode_coding_display() {
|
||||
return myCode_coding_display;
|
||||
}
|
||||
|
||||
public String getCode_coding_system() {
|
||||
return myCode_coding_system;
|
||||
}
|
||||
|
||||
public void setCode_concept_id(String theCodeId) {
|
||||
myCode_concept_id = theCodeId;
|
||||
|
@ -1,13 +1,19 @@
|
||||
package ca.uhn.fhir.jpa.dao.lastn;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
||||
import ca.uhn.fhir.jpa.dao.lastn.config.TestIntegratedObservationIndexSearchConfig;
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedCodeCodeableConceptSearchParamDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.IObservationIndexedSearchParamLastNDao;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.LenientErrorHandler;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchSvcImpl;
|
||||
import ca.uhn.fhir.jpa.search.lastn.json.ObservationJson;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.shadehapi.elasticsearch.action.search.SearchRequest;
|
||||
import org.shadehapi.elasticsearch.action.search.SearchResponse;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
@ -16,11 +22,14 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@ -35,11 +44,14 @@ public class IntegratedObservationIndexedSearchParamLastNTest {
|
||||
IObservationIndexedCodeCodeableConceptSearchParamDao myCodeableConceptIndexedSearchParamNormalizedDao;
|
||||
|
||||
@Autowired
|
||||
ObservationLastNIndexPersistSvc myObservationLastNIndexPersistSvc;
|
||||
ObservationLastNIndexPersistR4Svc myObservationLastNIndexPersistR4Svc;
|
||||
|
||||
@Autowired
|
||||
private ElasticsearchSvcImpl elasticsearchSvc;
|
||||
|
||||
@Autowired
|
||||
private IFhirSystemDao<Bundle, Meta> myDao;
|
||||
|
||||
final String RESOURCEPID = "123";
|
||||
final String SUBJECTID = "4567";
|
||||
final String CATEGORYFIRSTCODINGSYSTEM = "http://mycodes.org/fhir/observation-category";
|
||||
@ -107,11 +119,11 @@ public class IntegratedObservationIndexedSearchParamLastNTest {
|
||||
String observationCodeText = "Test Codeable Concept Field for Code";
|
||||
CodeableConcept codeableConceptField = new CodeableConcept().setText(observationCodeText);
|
||||
codeableConceptField.addCoding(new Coding("http://mycodes.org/fhir/observation-code", "test-code", "test-code display"));
|
||||
codeableConceptField.addCoding(new Coding("http://myalternatecodes.org/fhir/observation-code", "test-alt-code", "test-alt-code display"));
|
||||
codeableConceptField.addCoding(new Coding("http://mysecondaltcodes.org/fhir/observation-code", "test-second-alt-code", "test-second-alt-code display"));
|
||||
// codeableConceptField.addCoding(new Coding("http://myalternatecodes.org/fhir/observation-code", "test-alt-code", "test-alt-code display"));
|
||||
// codeableConceptField.addCoding(new Coding("http://mysecondaltcodes.org/fhir/observation-code", "test-second-alt-code", "test-second-alt-code display"));
|
||||
myObservation.setCode(codeableConceptField);
|
||||
|
||||
myObservationLastNIndexPersistSvc.indexObservation(myObservation);
|
||||
myObservationLastNIndexPersistR4Svc.indexObservation(myObservation);
|
||||
|
||||
SearchParameterMap searchParameterMap = new SearchParameterMap();
|
||||
ReferenceParam subjectParam = new ReferenceParam("Patient", "", SUBJECTID);
|
||||
@ -131,18 +143,18 @@ public class IntegratedObservationIndexedSearchParamLastNTest {
|
||||
assertEquals(RESOURCEPID, observationIdOnly.getIdentifier());
|
||||
|
||||
// execute Observation ID search - Composite Aggregation
|
||||
// searchRequestIdsOnly = elasticsearchSvc.buildObservationAllFieldsCompositeSearchRequest(1000, searchParameterMap, 3);
|
||||
// responseIds = elasticsearchSvc.executeSearchRequest(searchRequestIdsOnly);
|
||||
// observationIdsOnly = elasticsearchSvc.buildObservationCompositeResults(responseIds);
|
||||
searchRequestIdsOnly = elasticsearchSvc.buildObservationAllFieldsCompositeSearchRequest(1000, searchParameterMap, 3);
|
||||
responseIds = elasticsearchSvc.executeSearchRequest(searchRequestIdsOnly);
|
||||
observationIdsOnly = elasticsearchSvc.buildObservationCompositeResults(responseIds);
|
||||
|
||||
// assertEquals(1, observationIdsOnly.size());
|
||||
// observationIdOnly = observationIdsOnly.get(0);
|
||||
// assertEquals(RESOURCEPID, observationIdOnly.getIdentifier());
|
||||
assertEquals(1, observationIdsOnly.size());
|
||||
observationIdOnly = observationIdsOnly.get(0);
|
||||
assertEquals(RESOURCEPID, observationIdOnly.getIdentifier());
|
||||
|
||||
}
|
||||
|
||||
|
||||
// @Test
|
||||
@Test
|
||||
public void testIndexObservationMultiple() {
|
||||
|
||||
// Create two CodeableConcept values each for a Code with three codings.
|
||||
@ -200,7 +212,7 @@ public class IntegratedObservationIndexedSearchParamLastNTest {
|
||||
Date effectiveDtm = observationDate.getTime();
|
||||
observation.setEffective(new DateTimeType(effectiveDtm));
|
||||
|
||||
myObservationLastNIndexPersistSvc.indexObservation(observation);
|
||||
myObservationLastNIndexPersistR4Svc.indexObservation(observation);
|
||||
|
||||
}
|
||||
|
||||
@ -211,4 +223,57 @@ public class IntegratedObservationIndexedSearchParamLastNTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSampleBundle() {
|
||||
FhirContext myFhirCtx = FhirContext.forR4();
|
||||
|
||||
PathMatchingResourcePatternResolver provider = new PathMatchingResourcePatternResolver();
|
||||
final Resource[] bundleResources;
|
||||
try {
|
||||
bundleResources = provider.getResources("lastntestbundle.json");
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unexpected error during transmission: " + e.toString(), e);
|
||||
}
|
||||
|
||||
AtomicInteger index = new AtomicInteger();
|
||||
|
||||
Arrays.stream(bundleResources).forEach(
|
||||
resource -> {
|
||||
index.incrementAndGet();
|
||||
|
||||
InputStream resIs = null;
|
||||
String nextBundleString;
|
||||
try {
|
||||
resIs = resource.getInputStream();
|
||||
nextBundleString = IOUtils.toString(resIs, Charsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
return;
|
||||
} finally {
|
||||
try {
|
||||
if (resIs != null) {
|
||||
resIs.close();
|
||||
}
|
||||
} catch (final IOException ioe) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SMART demo apps rely on the use of LOINC 3141-9 (Body Weight Measured)
|
||||
* instead of LOINC 29463-7 (Body Weight)
|
||||
*/
|
||||
nextBundleString = nextBundleString.replace("\"29463-7\"", "\"3141-9\"");
|
||||
|
||||
IParser parser = myFhirCtx.newJsonParser();
|
||||
parser.setParserErrorHandler(new LenientErrorHandler(false));
|
||||
Bundle bundle = parser.parseResource(Bundle.class, nextBundleString);
|
||||
|
||||
myDao.transaction(null, bundle);
|
||||
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public class PersistObservationIndexedSearchParamLastNTest {
|
||||
IObservationIndexedCodeCodeableConceptSearchParamDao myCodeableConceptIndexedSearchParamNormalizedDao;
|
||||
|
||||
@Autowired
|
||||
ObservationLastNIndexPersistSvc myObservationLastNIndexPersistSvc;
|
||||
ObservationLastNIndexPersistR4Svc myObservationLastNIndexPersistR4Svc;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
@ -94,7 +94,7 @@ public class PersistObservationIndexedSearchParamLastNTest {
|
||||
codeableConceptField.addCoding(new Coding("http://mysecondaltcodes.org/fhir/observation-code", "test-second-alt-code", "test-second-alt-code display"));
|
||||
myObservation.setCode(codeableConceptField);
|
||||
|
||||
myObservationLastNIndexPersistSvc.indexObservation(myObservation);
|
||||
myObservationLastNIndexPersistR4Svc.indexObservation(myObservation);
|
||||
|
||||
List<ObservationIndexedSearchParamLastNEntity> persistedObservationEntities = myResourceIndexedObservationLastNDao.findAll();
|
||||
assertEquals(1, persistedObservationEntities.size());
|
||||
@ -171,7 +171,7 @@ public class PersistObservationIndexedSearchParamLastNTest {
|
||||
Date effectiveDtm = observationDate.getTime();
|
||||
observation.setEffective(new DateTimeType(effectiveDtm));
|
||||
|
||||
myObservationLastNIndexPersistSvc.indexObservation(observation);
|
||||
myObservationLastNIndexPersistR4Svc.indexObservation(observation);
|
||||
|
||||
}
|
||||
|
||||
@ -180,6 +180,11 @@ public class PersistObservationIndexedSearchParamLastNTest {
|
||||
assertEquals(100, myResourceIndexedObservationLastNDao.count());
|
||||
assertEquals(2, myCodeableConceptIndexedSearchParamNormalizedDao.count());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSampleObservationResource() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import java.io.IOException;
|
||||
|
||||
@Configuration
|
||||
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory",
|
||||
basePackages = {"ca.uhn.fhir.jpa.dao"})
|
||||
basePackages = {"ca.uhn.fhir.jpa.dao.data"})
|
||||
@EnableTransactionManagement
|
||||
public class TestIntegratedObservationIndexSearchConfig extends TestObservationIndexSearchConfig {
|
||||
|
||||
|
@ -15,6 +15,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import pl.allegro.tech.embeddedelasticsearch.EmbeddedElastic;
|
||||
import pl.allegro.tech.embeddedelasticsearch.PopularProperties;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
@ -22,7 +23,7 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Configuration
|
||||
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory",
|
||||
basePackages = {"ca.uhn.fhir.jpa.dao"})
|
||||
basePackages = {"ca.uhn.fhir.jpa.dao.data"})
|
||||
@EnableTransactionManagement
|
||||
public class TestObservationIndexSearchConfig extends TestR4Config {
|
||||
|
||||
@ -84,5 +85,9 @@ public class TestObservationIndexSearchConfig extends TestR4Config {
|
||||
return embeddedElastic;
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void stop() {
|
||||
embeddedElasticSearch().stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
@Ignore
|
||||
public class ElasticsearchV5PerformanceTests {
|
||||
|
||||
/*
|
||||
private ElasticsearchV5SvcImpl elasticsearchSvc = new ElasticsearchV5SvcImpl("localhost", 9301, "elastic", "changeme");
|
||||
private List<String> patientIds = new ArrayList<>();
|
||||
|
||||
@ -148,6 +148,6 @@ public class ElasticsearchV5PerformanceTests {
|
||||
}
|
||||
return identifiers;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
@ -234,6 +234,8 @@ public class LastNElasticsearchSvcSingleObservationTest {
|
||||
String code_concept_text_values = observation.getCode_concept_text();
|
||||
assertEquals(OBSERVATIONCODETEXT, code_concept_text_values);
|
||||
|
||||
// TODO: Temporary changes until find a solution for addressing Observation Code with multiple codings.
|
||||
/*
|
||||
List<String> code_coding_systems = observation.getCode_coding_system();
|
||||
assertEquals(3,code_coding_systems.size());
|
||||
assertEquals(CODEFIRSTCODINGSYSTEM, code_coding_systems.get(0));
|
||||
@ -257,6 +259,18 @@ public class LastNElasticsearchSvcSingleObservationTest {
|
||||
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE)), code_coding_code_system_hash.get(0));
|
||||
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODESECONDCODINGSYSTEM, CODESECONDCODINGCODE)), code_coding_code_system_hash.get(1));
|
||||
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODETHIRDCODINGSYSTEM, CODETHIRDCODINGCODE)), code_coding_code_system_hash.get(2));
|
||||
*/
|
||||
String code_coding_systems = observation.getCode_coding_system();
|
||||
assertEquals(CODEFIRSTCODINGSYSTEM, code_coding_systems);
|
||||
|
||||
String code_coding_codes = observation.getCode_coding_code();
|
||||
assertEquals(CODEFIRSTCODINGCODE, code_coding_codes);
|
||||
|
||||
String code_coding_display = observation.getCode_coding_display();
|
||||
assertEquals(CODEFIRSTCODINGDISPLAY, code_coding_display);
|
||||
|
||||
String code_coding_code_system_hash = observation.getCode_coding_code_system_hash();
|
||||
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE)), code_coding_code_system_hash);
|
||||
|
||||
// Retrieve all Observation codes
|
||||
SearchRequest searchRequest = elasticsearchSvc.buildObservationCodesSearchRequest(1000);
|
||||
|
@ -34,7 +34,7 @@ import static org.junit.Assert.*;
|
||||
public class LastNElasticsearchV5SvcMultipleObservationsTest {
|
||||
|
||||
@Autowired
|
||||
private ElasticsearchV5SvcImpl elasticsearchSvc;
|
||||
// private ElasticsearchV5SvcImpl elasticsearchSvc;
|
||||
|
||||
private static ObjectMapper ourMapperNonPrettyPrint;
|
||||
|
||||
@ -56,8 +56,8 @@ public class LastNElasticsearchV5SvcMultipleObservationsTest {
|
||||
|
||||
@After
|
||||
public void after() throws IOException {
|
||||
elasticsearchSvc.deleteAllDocuments(IndexConstants.OBSERVATION_INDEX);
|
||||
elasticsearchSvc.deleteAllDocuments(IndexConstants.CODE_INDEX);
|
||||
// elasticsearchSvc.deleteAllDocuments(IndexConstants.OBSERVATION_INDEX);
|
||||
// elasticsearchSvc.deleteAllDocuments(IndexConstants.CODE_INDEX);
|
||||
}
|
||||
/*
|
||||
@Test
|
||||
|
@ -37,7 +37,7 @@ import static org.junit.Assert.assertTrue;
|
||||
public class LastNElasticsearchV5SvcSingleObservationTest {
|
||||
|
||||
@Autowired
|
||||
ElasticsearchV5SvcImpl elasticsearchSvc;
|
||||
// ElasticsearchV5SvcImpl elasticsearchSvc;
|
||||
|
||||
static ObjectMapper ourMapperNonPrettyPrint;
|
||||
|
||||
@ -93,14 +93,14 @@ public class LastNElasticsearchV5SvcSingleObservationTest {
|
||||
|
||||
// @Before
|
||||
public void before() throws IOException {
|
||||
elasticsearchSvc.deleteAllDocuments(IndexConstants.OBSERVATION_INDEX);
|
||||
elasticsearchSvc.deleteAllDocuments(IndexConstants.CODE_INDEX);
|
||||
// elasticsearchSvc.deleteAllDocuments(IndexConstants.OBSERVATION_INDEX);
|
||||
// elasticsearchSvc.deleteAllDocuments(IndexConstants.CODE_INDEX);
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException {
|
||||
elasticsearchSvc.deleteAllDocuments(IndexConstants.OBSERVATION_INDEX);
|
||||
elasticsearchSvc.deleteAllDocuments(IndexConstants.CODE_INDEX);
|
||||
// elasticsearchSvc.deleteAllDocuments(IndexConstants.OBSERVATION_INDEX);
|
||||
// elasticsearchSvc.deleteAllDocuments(IndexConstants.CODE_INDEX);
|
||||
}
|
||||
@Test
|
||||
public void testSingleObservationQuery() throws IOException {
|
||||
@ -222,7 +222,7 @@ public class LastNElasticsearchV5SvcSingleObservationTest {
|
||||
|
||||
String code_concept_text_values = observation.getCode_concept_text();
|
||||
assertEquals(OBSERVATIONCODETEXT, code_concept_text_values);
|
||||
|
||||
/*
|
||||
List<String> code_coding_systems = observation.getCode_coding_system();
|
||||
assertEquals(3,code_coding_systems.size());
|
||||
assertEquals(CODEFIRSTCODINGSYSTEM, code_coding_systems.get(0));
|
||||
@ -246,7 +246,7 @@ public class LastNElasticsearchV5SvcSingleObservationTest {
|
||||
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODEFIRSTCODINGSYSTEM, CODEFIRSTCODINGCODE)), code_coding_code_system_hash.get(0));
|
||||
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODESECONDCODINGSYSTEM, CODESECONDCODINGCODE)), code_coding_code_system_hash.get(1));
|
||||
assertEquals(String.valueOf(CodeSystemHash.hashCodeSystem(CODETHIRDCODINGSYSTEM, CODETHIRDCODINGCODE)), code_coding_code_system_hash.get(2));
|
||||
|
||||
*/
|
||||
// Retrieve all Observation codes
|
||||
/* SearchRequest searchRequest = elasticsearchSvc.buildObservationCodesSearchRequest(1000);
|
||||
SearchResponse response = elasticsearchSvc.executeSearchRequest(searchRequest);
|
||||
@ -329,11 +329,11 @@ public class LastNElasticsearchV5SvcSingleObservationTest {
|
||||
indexedObservation.setCode(codeableConceptField);
|
||||
|
||||
String observationDocument = ourMapperNonPrettyPrint.writeValueAsString(indexedObservation);
|
||||
assertTrue(elasticsearchSvc.performIndex(IndexConstants.OBSERVATION_INDEX, RESOURCEPID, observationDocument, IndexConstants.OBSERVATION_DOCUMENT_TYPE));
|
||||
// assertTrue(elasticsearchSvc.performIndex(IndexConstants.OBSERVATION_INDEX, RESOURCEPID, observationDocument, IndexConstants.OBSERVATION_DOCUMENT_TYPE));
|
||||
|
||||
CodeJson observationCode = new CodeJson(codeableConceptField, OBSERVATIONSINGLECODEID);
|
||||
String codeDocument = ourMapperNonPrettyPrint.writeValueAsString(observationCode);
|
||||
assertTrue(elasticsearchSvc.performIndex(IndexConstants.CODE_INDEX, OBSERVATIONSINGLECODEID, codeDocument, IndexConstants.CODE_DOCUMENT_TYPE));
|
||||
// assertTrue(elasticsearchSvc.performIndex(IndexConstants.CODE_INDEX, OBSERVATIONSINGLECODEID, codeDocument, IndexConstants.CODE_DOCUMENT_TYPE));
|
||||
|
||||
try {
|
||||
Thread.sleep(1000L);
|
||||
|
@ -9,6 +9,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
import pl.allegro.tech.embeddedelasticsearch.EmbeddedElastic;
|
||||
import pl.allegro.tech.embeddedelasticsearch.PopularProperties;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -50,4 +51,9 @@ public class TestElasticsearchConfig {
|
||||
return embeddedElastic;
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void stop() {
|
||||
embeddedElasticSearch().stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ca.uhn.fhir.jpa.search.lastn.config;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.jpa.search.lastn.ElasticsearchV5SvcImpl;
|
||||
//import ca.uhn.fhir.jpa.search.lastn.ElasticsearchV5SvcImpl;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
@ -13,9 +13,9 @@ import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Configuration
|
||||
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory")
|
||||
@EnableTransactionManagement
|
||||
//@Configuration
|
||||
//@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory")
|
||||
//@EnableTransactionManagement
|
||||
public class TestElasticsearchV5Config {
|
||||
|
||||
private final String elasticsearchHost = "127.0.0.1";
|
||||
@ -24,7 +24,7 @@ public class TestElasticsearchV5Config {
|
||||
|
||||
private static final String ELASTIC_VERSION = "5.6.16";
|
||||
|
||||
|
||||
/*
|
||||
@Bean()
|
||||
public ElasticsearchV5SvcImpl myElasticsearchSvc() throws IOException {
|
||||
int elasticsearchPort = embeddedElasticSearch().getHttpPort();
|
||||
@ -49,5 +49,5 @@ public class TestElasticsearchV5Config {
|
||||
|
||||
return embeddedElastic;
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
@ -191,6 +191,11 @@ public class JpaConstants {
|
||||
*/
|
||||
public static final String OPERATION_EXPORT_POLL_STATUS = "$export-poll-status";
|
||||
|
||||
/**
|
||||
* Operation name for the "$lastn" operation
|
||||
*/
|
||||
public static final String OPERATION_LASTN = "$lastn";
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This extension should be of type <code>string</code> and should be
|
||||
|
19
hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/SearchParameterMap.java
19
hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/SearchParameterMap.java
@ -61,6 +61,7 @@ public class SearchParameterMap implements Serializable {
|
||||
private SummaryEnum mySummaryMode;
|
||||
private SearchTotalModeEnum mySearchTotalMode;
|
||||
private QuantityParam myNearDistanceParam;
|
||||
private boolean myLastN;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -303,6 +304,24 @@ public class SearchParameterMap implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set, tells the server to use an Elasticsearch query to generate a list of
|
||||
* Resource IDs for the LastN operation
|
||||
*/
|
||||
public boolean isLastN() {
|
||||
return myLastN;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set, tells the server to use an Elasticsearch query to generate a list of
|
||||
* Resource IDs for the LastN operation
|
||||
*/
|
||||
public SearchParameterMap setLastN(boolean theLastN) {
|
||||
myLastN = theLastN;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates a URL query string representation of the parameters in this
|
||||
* object, excluding the part before the parameters, e.g.
|
||||
|
@ -24,7 +24,7 @@ import ca.uhn.fhir.rest.api.SearchTotalModeEnum;
|
||||
public class ${className}ResourceProvider extends
|
||||
## We have specialized base classes for RPs that handle certain resource types. These
|
||||
## RPs implement type specific operations
|
||||
#if ( $version != 'dstu' && (${className} == 'Encounter' || ${className} == 'Patient' || ${className} == 'ValueSet' || ${className} == 'QuestionnaireAnswers' || ${className} == 'CodeSystem' || ($version != 'dstu2' && ${className} == 'ConceptMap') || ${className} == 'MessageHeader' || ${className} == 'Composition' || ${className} == 'StructureDefinition'))
|
||||
#if ( $version != 'dstu' && (${className} == 'Encounter' || ${className} == 'Patient' || ${className} == 'ValueSet' || ${className} == 'QuestionnaireAnswers' || ${className} == 'CodeSystem' || ($version != 'dstu2' && ${className} == 'ConceptMap') || ${className} == 'MessageHeader' || ${className} == 'Composition' || ${className} == 'StructureDefinition' || ${className} == 'Observation' ))
|
||||
BaseJpaResourceProvider${className}${versionCapitalized}
|
||||
#else
|
||||
JpaResourceProvider${versionCapitalized}<${className}>
|
||||
|
@ -50,6 +50,8 @@
|
||||
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${res.name}${versionCapitalized}">
|
||||
#elseif ( ${versionCapitalized} != 'Dstu1' && ( ${res.name} == 'Bundle' || ${res.name} == 'Encounter' || ${res.name} == 'Composition' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'ValueSet' || ${res.name} == 'QuestionnaireResponse' || ${res.name} == 'SearchParameter'))
|
||||
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${res.name}${versionCapitalized}">
|
||||
#elseif ( ${versionCapitalized} != 'Dstu1' && ${versionCapitalized} != 'Dstu2' && ${res.name} == 'Observation')
|
||||
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${res.name}${versionCapitalized}">
|
||||
#else
|
||||
class="ca.uhn.fhir.jpa.dao.FhirResourceDao${versionCapitalized}">
|
||||
#end
|
||||
|
@ -68,6 +68,8 @@ public abstract class BaseJavaConfig${versionCapitalized} extends ca.uhn.fhir.jp
|
||||
IFhirResourceDaoConceptMap<org.hl7.fhir.${version}.model.ConceptMap>
|
||||
#elseif ( ${versionCapitalized} != 'Dstu1' && (${res.name} == 'Composition' || ${res.name} == 'Encounter' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'SearchParameter' || ${res.name} == 'MessageHeader' || ${res.name} == 'StructureDefinition'))
|
||||
IFhirResourceDao${res.name}<${resourcePackage}.${res.declaringClassNameComplete}>
|
||||
#elseif ( ${versionCapitalized} != 'Dstu1' && ${versionCapitalized} != 'Dstu2' && (${res.name} == 'Observation'))
|
||||
IFhirResourceDao${res.name}<${resourcePackage}.${res.declaringClassNameComplete}>
|
||||
#else
|
||||
IFhirResourceDao<${resourcePackage}.${res.declaringClassNameComplete}>
|
||||
#end
|
||||
@ -82,6 +84,9 @@ public abstract class BaseJavaConfig${versionCapitalized} extends ca.uhn.fhir.jp
|
||||
#elseif ( ${res.name} == 'Bundle' || ${res.name} == 'Encounter' || ${res.name} == 'Everything' || ${res.name} == 'Patient' || ${res.name} == 'Subscription' || ${res.name} == 'ValueSet' || ${res.name} == 'QuestionnaireResponse' || ${res.name} == 'SearchParameter' || ${res.name} == 'CodeSystem' || ${res.name} == 'MessageHeader' || ${res.name} == 'Composition' || ${res.name} == 'StructureDefinition')
|
||||
ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized} retVal;
|
||||
retVal = new ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized}();
|
||||
#elseif ( ${versionCapitalized} != 'Dstu1' && ${versionCapitalized} != 'Dstu2' && ${res.name} == 'Observation')
|
||||
ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized} retVal;
|
||||
retVal = new ca.uhn.fhir.jpa.dao${package_suffix}.FhirResourceDao${res.name}${versionCapitalized}();
|
||||
#else
|
||||
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao<${resourcePackage}.${res.declaringClassNameComplete}> retVal;
|
||||
retVal = new ca.uhn.fhir.jpa.dao.JpaResourceDao<${resourcePackage}.${res.declaringClassNameComplete}>();
|
||||
|
Loading…
x
Reference in New Issue
Block a user