Skip to content

Commit

Permalink
(manual) merge of master
Browse files Browse the repository at this point in the history
  • Loading branch information
sliver007 committed Sep 11, 2023
1 parent abb0480 commit d0432b6
Show file tree
Hide file tree
Showing 214 changed files with 21,507 additions and 22,856 deletions.
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ FROM openjdk:18-slim-bullseye
ARG COMMIT_HASH
LABEL COMMIT_HASH ${COMMIT_HASH}
ENV COMMIT_HASH ${COMMIT_HASH}

ENV VERSION=0.14.0-SNAPSHOT
RUN apt-get update && apt-get upgrade -y && rm -rf /var/lib/apt/lists/*
RUN groupadd -r cqfruler && useradd -r -g cqfruler cqfruler
USER cqfruler
WORKDIR /home/cqfruler

RUN mkdir server
RUN mkdir plugin
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.opencds.cqf/cqf-ruler-server/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.opencds.cqf/cqf-ruler-server) [![Build Status](https://app.travis-ci.com/DBCG/cqf-ruler.svg?branch=master)](https://app.travis-ci.com/DBCG/cqf-ruler) [![docker image](https://img.shields.io/docker/v/alphora/cqf-ruler/latest?style=flat&color=brightgreen&label=docker%20image)](https://hub.docker.com/r/alphora/cqf-ruler/tags) [![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://chat.fhir.org/#narrow/stream/179220-cql)

---

### **NOTICE**: The maintainers of the cqf-ruler (Alphora) and Smile Digital Health have [merged](https://www.globenewswire.com/en/news-release/2022/11/01/2545568/0/en/Smile-Digital-Health-Expands-Product-Offering-With-Alphora-Acquisition.html)! All the functionality in the cqf-ruler is in the process of being migrated upstream to the [hapi-fhir-jpaserver-starter](https://github.com/hapifhir/hapi-fhir-jpaserver-starter) project

---

The cqf-ruler is based on the [HAPI FHIR JPA Server Starter](https://github.com/hapifhir/hapi-fhir-jpaserver-starter) and adds a set of plugins that provide an implementation of FHIR's [Clinical Reasoning Module](
http://hl7.org/fhir/clinicalreasoning-module.html), serve as a
knowledge artifact repository, and a [cds-hooks](https://cds-hooks.org/) compatible clinical decision support service. The cqf-ruler provides an [extensibility API](#plugins) to allow adding custom FHIR operations without the need to fork or clone the entire project.
Expand All @@ -22,8 +28,8 @@ The public sandbox is not persistent, has no authentication, and is regularly re

### Docker

The easiest way to get started with the cqf-ruler is to pull and run the docker image

The easiest way to get started with the cqf-ruler is to pull and run the docker image.
For avoiding to run docker container by default root user permission, the container from this image will run with a user named `cqfruler`
```bash
docker pull alphora/cqf-ruler
docker run -p 8080:8080 alphora/cqf-ruler
Expand Down
2 changes: 2 additions & 0 deletions config/checkstyle/checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@
<property name="message" value="Line has trailing spaces."/>
</module>

<suppress checks=".*" files="org[\\/]opencds[\\/]cqf[\\/]external[\\/]"/>

</module>
74 changes: 70 additions & 4 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.opencds.cqf.ruler</groupId>
<artifactId>cqf-ruler</artifactId>
<version>0.14.0-SNAPSHOT</version>
<version>0.15.0-SNAPSHOT</version>
</parent>

<artifactId>cqf-ruler-core</artifactId>
Expand All @@ -13,20 +13,86 @@
<dependency>
<groupId>org.opencds.cqf.ruler</groupId>
<artifactId>cqf-ruler-external</artifactId>
<version>0.14.0-SNAPSHOT</version>
<version>0.15.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-storage</artifactId>
<version>${hapi_version}</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-server</artifactId>
<version>${hapi_version}</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-jpaserver-subscription</artifactId>
<version>${hapi_version}</version>
</dependency>

<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-validation-resources-r5</artifactId>
<version>${hapi_version}</version>
</dependency>

<dependency>
<groupId>org.simplejavamail</groupId>
<artifactId>simple-java-mail</artifactId>
<exclusions>
<exclusion>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.r5</artifactId>
<version>6.0.15</version>
</dependency>

<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>org.hl7.fhir.convertors</artifactId>
<version>6.0.15</version>
</dependency>
<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.jackson-deps</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.fhir</artifactId>
</dependency>

<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.library</artifactId>
</dependency>
<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.activitydefinition</artifactId>
</dependency>
<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.plandefinition</artifactId>
</dependency>
<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.questionnaire</artifactId>
</dependency>
<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.questionnaireresponse</artifactId>
</dependency>
<dependency>
<groupId>org.opencds.cqf.cql</groupId>
<artifactId>evaluator.spring</artifactId>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
Expand Down Expand Up @@ -139,7 +205,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.1.214</version>
<version>2.2.220</version>
<scope>test</scope>
</dependency>

Expand Down
35 changes: 19 additions & 16 deletions core/src/main/java/org/opencds/cqf/ruler/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,38 @@
import org.opencds.cqf.external.mdm.MdmConfig;
import org.opencds.cqf.ruler.config.BeanFinderConfig;
import org.opencds.cqf.ruler.config.RulerConfig;
import org.opencds.cqf.ruler.config.ServerProperties;
import org.opencds.cqf.ruler.config.TesterUIConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;

import ca.uhn.fhir.batch2.jobs.config.Batch2JobsConfig;
import ca.uhn.fhir.jpa.batch2.JpaBatch2Config;
import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig;
import ca.uhn.fhir.jpa.subscription.match.config.SubscriptionProcessorConfig;
import ca.uhn.fhir.jpa.subscription.match.config.WebsocketDispatcherConfig;
import ca.uhn.fhir.jpa.subscription.submit.config.SubscriptionSubmitterConfig;
import ca.uhn.fhir.rest.server.RestfulServer;

@ServletComponentScan(basePackageClasses = Application.class)
@SpringBootApplication(exclude = { ElasticsearchRestClientAutoConfiguration.class, QuartzAutoConfiguration.class })
@SpringBootApplication(exclude = { ElasticsearchRestClientAutoConfiguration.class, ThymeleafAutoConfiguration.class })
@Import({
RulerConfig.class,
ServerProperties.class,
SubscriptionSubmitterConfig.class,
SubscriptionProcessorConfig.class,
SubscriptionChannelConfig.class,
WebsocketDispatcherConfig.class,
MdmConfig.class,
TesterUIConfig.class,
BeanFinderConfig.class, })
JpaBatch2Config.class,
Batch2JobsConfig.class,
BeanFinderConfig.class,
RulerConfig.class })
public class Application extends SpringBootServletInitializer {

public static void main(String[] args) {
Expand All @@ -49,12 +54,10 @@ protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {

@Bean
@Conditional(OnEitherVersion.class)
public ServletRegistrationBean<Server> hapiServletRegistration() {
ServletRegistrationBean<Server> servletRegistrationBean = new ServletRegistrationBean<>();
Server server = new Server();
beanFactory.autowireBean(server);
servletRegistrationBean.setName("fhir servlet");
servletRegistrationBean.setServlet(server);
public ServletRegistrationBean hapiServletRegistration(RestfulServer restfulServer) {
var servletRegistrationBean = new ServletRegistrationBean();
beanFactory.autowireBean(restfulServer);
servletRegistrationBean.setServlet(restfulServer);
servletRegistrationBean.addUrlMappings("/fhir/*");
servletRegistrationBean.setLoadOnStartup(1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,100 +6,49 @@
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.ServletException;

import org.hl7.fhir.dstu3.model.CapabilityStatement;
import org.hl7.fhir.instance.model.api.IBaseConformance;
import org.opencds.cqf.external.AppProperties;
import org.opencds.cqf.external.BaseJpaRestfulServer;
import org.opencds.cqf.external.mdm.MdmConfig;
import org.opencds.cqf.ruler.api.Interceptor;
import org.opencds.cqf.ruler.api.MetadataExtender;
import org.opencds.cqf.ruler.api.OperationProvider;
import org.opencds.cqf.ruler.capability.ExtensibleJpaCapabilityStatementProvider;
import org.opencds.cqf.ruler.capability.ExtensibleJpaConformanceProviderDstu2;
import org.opencds.cqf.ruler.capability.ExtensibleJpaConformanceProviderDstu3;
import org.opencds.cqf.ruler.config.BeanFinderConfig;
import org.opencds.cqf.ruler.config.ServerProperties;
import org.opencds.cqf.ruler.config.TesterUIConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Import;

import ca.uhn.fhir.batch2.jobs.config.Batch2JobsConfig;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.batch2.JpaBatch2Config;
import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig;
import ca.uhn.fhir.jpa.subscription.match.config.SubscriptionProcessorConfig;
import ca.uhn.fhir.jpa.subscription.match.config.WebsocketDispatcherConfig;
import ca.uhn.fhir.jpa.subscription.submit.config.SubscriptionSubmitterConfig;
import ca.uhn.fhir.model.dstu2.resource.Conformance;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;

@Import({
ServerProperties.class,
SubscriptionSubmitterConfig.class,
SubscriptionProcessorConfig.class,
SubscriptionChannelConfig.class,
WebsocketDispatcherConfig.class,
MdmConfig.class,
JpaBatch2Config.class,
Batch2JobsConfig.class,
TesterUIConfig.class,
BeanFinderConfig.class })
public class Server extends BaseJpaRestfulServer {
private static final long serialVersionUID = 1L;

private static Logger log = LoggerFactory.getLogger(Server.class);

@Autowired
DaoConfig myDaoConfig;

@Autowired
ISearchParamRegistry mySearchParamRegistry;

@SuppressWarnings("rawtypes")
@Autowired
IFhirSystemDao myFhirSystemDao;
public class ServerConfig {

@Autowired
private IValidationSupport myValidationSupport;

@Autowired
ApplicationContext applicationContext;

@Autowired
AppProperties myAppProperties;

@Autowired
ServerProperties myServerProperties;

public Server() {
super();
}
private static Logger log = LoggerFactory.getLogger(ServerConfig.class);

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
protected void initialize() throws ServletException {
super.initialize();
@SuppressWarnings({ "unchecked", "rawtypes" })
public ServerConfig(RestfulServer server, ApplicationContext applicationContext,
JpaStorageSettings myJpaStorageSettings, ISearchParamRegistry mySearchParamRegistry,
IFhirSystemDao myFhirSystemDao, IValidationSupport myValidationSupport,
ServerProperties myServerProperties) {

log.info("Loading operation providers from plugins");
Map<String, OperationProvider> providers = applicationContext.getBeansOfType(OperationProvider.class);
for (OperationProvider o : providers.values()) {
log.info("Registering {}", o.getClass().getName());
this.registerProvider(o);
server.registerProvider(o);
}

log.info("Loading interceptors from plugins");
Map<String, Interceptor> interceptors = applicationContext.getBeansOfType(Interceptor.class);
for (Interceptor o : interceptors.values()) {
log.info("Registering {} interceptor", o.getClass().getName());
this.registerInterceptor(o);
server.registerInterceptor(o);
}

log.info("Loading metadata extenders from plugins");
Expand All @@ -114,34 +63,34 @@ protected void initialize() throws ServletException {
if (fhirVersion == FhirVersionEnum.DSTU2) {
List<MetadataExtender<Conformance>> extenderList = extenders.values().stream()
.map(x -> (MetadataExtender<Conformance>) x).collect(Collectors.toList());
ExtensibleJpaConformanceProviderDstu2 confProvider = new ExtensibleJpaConformanceProviderDstu2(this,
ExtensibleJpaConformanceProviderDstu2 confProvider = new ExtensibleJpaConformanceProviderDstu2(server,
myFhirSystemDao,
myDaoConfig, extenderList);
myJpaStorageSettings, extenderList);
confProvider.setImplementationDescription(firstNonNull(implementationDescription, "CQF RULER DSTU2 Server"));
setServerConformanceProvider(confProvider);
server.setServerConformanceProvider(confProvider);
} else {
if (fhirVersion == FhirVersionEnum.DSTU3) {
List<MetadataExtender<CapabilityStatement>> extenderList = extenders.values().stream()
.map(x -> (MetadataExtender<CapabilityStatement>) x).collect(Collectors.toList());
ExtensibleJpaConformanceProviderDstu3 confProvider = new ExtensibleJpaConformanceProviderDstu3(this,
myFhirSystemDao, myDaoConfig, mySearchParamRegistry, extenderList);
ExtensibleJpaConformanceProviderDstu3 confProvider = new ExtensibleJpaConformanceProviderDstu3(server,
myFhirSystemDao, myJpaStorageSettings, mySearchParamRegistry, extenderList);
confProvider
.setImplementationDescription(firstNonNull(implementationDescription, "CQF RULER DSTU3 Server"));
setServerConformanceProvider(confProvider);
server.setServerConformanceProvider(confProvider);
} else if (fhirVersion == FhirVersionEnum.R4) {
List<MetadataExtender<IBaseConformance>> extenderList = extenders.values().stream()
.map(x -> (MetadataExtender<IBaseConformance>) x).collect(Collectors.toList());
ExtensibleJpaCapabilityStatementProvider confProvider = new ExtensibleJpaCapabilityStatementProvider(this,
myFhirSystemDao, myDaoConfig, mySearchParamRegistry, myValidationSupport, extenderList);
ExtensibleJpaCapabilityStatementProvider confProvider = new ExtensibleJpaCapabilityStatementProvider(server,
myFhirSystemDao, myJpaStorageSettings, mySearchParamRegistry, myValidationSupport, extenderList);
confProvider.setImplementationDescription(firstNonNull(implementationDescription, "CQF RULER R4 Server"));
setServerConformanceProvider(confProvider);
server.setServerConformanceProvider(confProvider);
} else if (fhirVersion == FhirVersionEnum.R5) {
List<MetadataExtender<IBaseConformance>> extenderList = extenders.values().stream()
.map(x -> (MetadataExtender<IBaseConformance>) x).collect(Collectors.toList());
ExtensibleJpaCapabilityStatementProvider confProvider = new ExtensibleJpaCapabilityStatementProvider(this,
myFhirSystemDao, myDaoConfig, mySearchParamRegistry, myValidationSupport, extenderList);
ExtensibleJpaCapabilityStatementProvider confProvider = new ExtensibleJpaCapabilityStatementProvider(server,
myFhirSystemDao, myJpaStorageSettings, mySearchParamRegistry, myValidationSupport, extenderList);
confProvider.setImplementationDescription(firstNonNull(implementationDescription, "CQF RULER R5 Server"));
setServerConformanceProvider(confProvider);
server.setServerConformanceProvider(confProvider);
} else {
throw new IllegalStateException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static com.google.common.base.Preconditions.checkNotNull;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

Expand Down Expand Up @@ -231,10 +232,11 @@ protected void initializeR5(T theResource) {

composition
.setDate(myDate)
.setIdentifier(new org.hl7.fhir.r5.model.Identifier().setSystem(getIdentifier().getKey())
.setValue(getIdentifier().getValue()))
.setIdentifier(
Collections.singletonList(new org.hl7.fhir.r5.model.Identifier().setSystem(getIdentifier().getKey())
.setValue(getIdentifier().getValue())))
.setStatus(CompositionStatus.valueOf(myStatus))
.setSubject(new org.hl7.fhir.r5.model.Reference(mySubject))
.setSubject(Collections.singletonList(new org.hl7.fhir.r5.model.Reference(mySubject)))
.setTitle(myTitle)
.setType(new org.hl7.fhir.r5.model.CodeableConcept()
.addCoding(new org.hl7.fhir.r5.model.Coding()
Expand Down
Loading

0 comments on commit d0432b6

Please sign in to comment.