Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 43 additions & 11 deletions java/hapi-fhirstarters-rest-server-gradle-multmodule/build.gradle
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
buildscript {

ext {
spring_plugin_version = '2.7.18'
sonarqube_plugin_version = '3.0'
spring_plugin_version = '3.5.16'
sonarqube_plugin_version = '7.3.1.8318'
jacoco_tool_version = '0.8.6'

springBootVersion = '2.7.18'
// Note, there is a relationship between the spring-boot-version and the hapi-fhir-version as seen here (under 'Compile Dependencies'): https://mvnrepository.com/artifact/ca.uhn.hapi.fhir/hapi-fhir-server/6.2.5
hapiFhirVersion = '6.1.3'
springBootVersion = '3.5.16'
// Note, there is a relationship between the spring-boot-version and the hapi-fhir-version as seen here (under 'Compile Dependencies'): https://mvnrepository.com/artifact/ca.uhn.hapi.fhir/hapi-fhir-server/6.1.1
hapiFhirVersion = '8.8.1'

slf4jSimpleVersion = '1.7.36'
slf4jVersion = "1.7.36"
//below for granadacoder JT3 testing or any local SNAPSHOT testing
//hapiFhirVersion = '8.33.44-SNAPSHOT'


jakartaServletApiVersion = '6.0.0'


slf4jSimpleVersion = '2.0.17'
slf4jVersion = "2.0.17"
javaxInjectVersion = "1"

junitVersion = "4.13.2"
mockitoVersion = "4.8.0"

commonsLangVersion = '3.12.0'
commonsLangVersion = '3.14.0'

h2databaseVersion = '2.2.220'

versionBuildHolderVariable = '1.0-SNAPSHOT'

Expand Down Expand Up @@ -76,12 +85,35 @@ subprojects {

// ORDER MATTERS HERE. See : https://stackoverflow.com/questions/50726435/difference-among-mavencentral-jcenter-and-mavenlocal/50726436#50726436

/* below is a TEMPORARY maven-source for Hapi Fhir SNAPSHOTS
* as seen here https://hapifhir.io/hapi-fhir/docs/getting_started/downloading_and_importing.html#using-snapshot-builds
* once a "jakarta" friendly hapi fhir RELEASE version is available, the below temp maven-source should be removed
* also see : https://groups.google.com/g/hapi-fhir/c/U6dXYsC7LCg/m/Ssxk6Fs3AgAJ
*
* SNAPSHOT version values can be seen here:
* https://oss.sonatype.org/#nexus-search;gav~ca.uhn.hapi.fhir~hapi-fhir-server~~~~kw,versionexpand
*
*
* */
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
}



// As a general advice, you should avoid adding mavenLocal() as a repository.
// https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:case-for-maven-local
//
// However, it may be necessary when testing here with changes to a shared component library that have only
// been published locally (vi "gradle publishToMavenLocal".
//


//below for granadacoder JT3 testing or any local SNAPSHOT testing
//mavenLocal()



mavenCentral()

}
Expand All @@ -96,9 +128,9 @@ subprojects {

group = "build"
reports {
xml.enabled true
csv.enabled false
html.enabled false
xml.required = true
csv.required = false
html.required = false
}

afterEvaluate {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ rootProject.name = 'hapi-fhirstarters-rest-server-skeleton-gradlelayersandspring
* https://www.petrikainulainen.net/programming/gradle/getting-started-with-gradle-creating-a-multi-project-build/
* https://docs.gradle.org/current/samples/sample_building_java_applications_multi_project.html
*/
include ':source:javalayers:hapifhirmimics'
include ':source:javalayers:businesslogiclayer'
include ':source:javalayers:resourceproviderlayer'
include ':source:javalayers:toplayers:springboottoplayers:quickexampleserver'
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
plugins {
id 'java'
}

dependencies {
implementation group: 'javax.inject', name: 'javax.inject', version: javaxInjectVersion
// https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api
compileOnly group: 'jakarta.servlet', name: 'jakarta.servlet-api', version: jakartaServletApiVersion


implementation group: 'org.springframework.boot', name: 'spring-boot-starter', version: springBootVersion


implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-base', version: hapiFhirVersion
implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-structures-r4', version: hapiFhirVersion
implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-server', version: hapiFhirVersion
/* below items allow hapi-fhir-server to be configured by application.yml entries */
implementation(group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-spring-boot-autoconfigure', version: hapiFhirVersion) {

/*This keeps the needed HAPI autoconfigure classes for compile-time, while preventing it from pulling Spring Boot 3.5.x and related transitive jars that were overriding your intended 3.2.0 stack and causing NoClassDefFoundError: org/apache/hc/client5/http/ssl/TlsSocketStrategy. */
transitive = false
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package my.hapifhirmimics;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.client.api.IClientInterceptor;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor;
import ca.uhn.fhir.spring.boot.autoconfigure.FhirProperties;
import ca.uhn.fhir.spring.boot.autoconfigure.FhirRestfulServerCustomizer;
import jakarta.servlet.ServletException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ResourceCondition;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
* {@link EnableAutoConfiguration Auto-configuration} for HAPI FHIR.
*
* @author Mathieu Ouellet
*/
@Configuration
//@AutoConfigureAfter({DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
@EnableConfigurationProperties(FhirProperties.class)
public class MySuperCoolFhirAutoConfiguration {

private final FhirProperties properties;

public MySuperCoolFhirAutoConfiguration(FhirProperties properties) {
this.properties = properties;
}

@Bean
@ConditionalOnMissingBean
public FhirContext fhirContext() {
FhirContext fhirContext = new FhirContext(properties.getVersion());
return fhirContext;
}

@Configuration
//@ConditionalOnClass(AbstractJaxRsProvider.class)
@EnableConfigurationProperties(FhirProperties.class)
@ConfigurationProperties("hapi.fhir.rest")
@SuppressWarnings("serial")
static class FhirRestfulServerConfiguration extends RestfulServer {

private final FhirProperties properties;

private final FhirContext fhirContext;

private final List<IResourceProvider> resourceProviders;

private final IPagingProvider pagingProvider;

private final List<FhirRestfulServerCustomizer> customizers;

public FhirRestfulServerConfiguration(
FhirProperties properties,
FhirContext fhirContext,
ObjectProvider<List<IResourceProvider>> resourceProviders,
ObjectProvider<IPagingProvider> pagingProvider,
ObjectProvider<List<IServerInterceptor>> interceptors,
ObjectProvider<List<FhirRestfulServerCustomizer>> customizers) {
this.properties = properties;
this.fhirContext = fhirContext;
this.resourceProviders = resourceProviders.getIfAvailable();
this.pagingProvider = pagingProvider.getIfAvailable();
this.customizers = customizers.getIfAvailable();
}

private void customize() {
if (this.customizers != null) {
AnnotationAwareOrderComparator.sort(this.customizers);
for (FhirRestfulServerCustomizer customizer : this.customizers) {
customizer.customize(this);
}
}
}

@Bean
public ServletRegistrationBean fhirServerRegistrationBean() {
ServletRegistrationBean registration = new ServletRegistrationBean(
this, this.properties.getServer().getPath());
registration.setLoadOnStartup(1);
return registration;
}

@Override
protected void initialize() throws ServletException {
super.initialize();

setFhirContext(this.fhirContext);
setResourceProviders(this.resourceProviders);
setPagingProvider(this.pagingProvider);

setServerAddressStrategy(new HardcodedServerAddressStrategy(
this.properties.getServer().getPath()));

customize();
}
}


@Configuration
@Conditional(FhirValidationConfiguration.SchemaAvailableCondition.class)
@ConditionalOnProperty(name = "hapi.fhir.validation.enabled", matchIfMissing = true)
static class FhirValidationConfiguration {

@Bean
@ConditionalOnMissingBean
public RequestValidatingInterceptor requestValidatingInterceptor() {
return new RequestValidatingInterceptor();
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "hapi.fhir.validation.request-only", havingValue = "false")
public ResponseValidatingInterceptor responseValidatingInterceptor() {
return new ResponseValidatingInterceptor();
}

static class SchemaAvailableCondition extends ResourceCondition {

SchemaAvailableCondition() {
super(
"ValidationSchema",
"hapi.fhir.validation",
"schema-location",
"classpath:/org/hl7/fhir/instance/model/schema",
"classpath:/org/hl7/fhir/dstu2016may/model/schema",
"classpath:/org/hl7/fhir/dstu3/model/schema");
}
}
}

@Configuration
@ConditionalOnProperty("hapi.fhir.server.url")
@EnableConfigurationProperties(FhirProperties.class)
static class FhirRestfulClientConfiguration {

private final FhirProperties properties;

private final List<IClientInterceptor> clientInterceptors;

public FhirRestfulClientConfiguration(
FhirProperties properties, ObjectProvider<List<IClientInterceptor>> clientInterceptors) {
this.properties = properties;
this.clientInterceptors = clientInterceptors.getIfAvailable();
}

@Bean
@ConditionalOnBean(IRestfulClientFactory.class)
public IGenericClient fhirClient(final IRestfulClientFactory clientFactory) {
IGenericClient fhirClient =
clientFactory.newGenericClient(this.properties.getServer().getUrl());
if (!CollectionUtils.isEmpty(this.clientInterceptors)) {
for (IClientInterceptor interceptor : this.clientInterceptors) {
fhirClient.registerInterceptor(interceptor);
}
}
return fhirClient;
}



}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dependencies {

implementation project(':source:javalayers:resourceproviderlayer')
implementation project(':source:javalayers:businesslogiclayer')
implementation project(':source:javalayers:hapifhirmimics')

/* spring boot dependencies */
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion
Expand All @@ -25,9 +26,15 @@ dependencies {
implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-structures-r4', version: hapiFhirVersion
implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-server', version: hapiFhirVersion
/* below items allow hapi-fhir-server to be configured by application.yml entries */
implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-spring-boot-autoconfigure', version: hapiFhirVersion
implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-jaxrsserver-base', version: hapiFhirVersion

// implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-spring-boot-autoconfigure', version: hapiFhirVersion
// implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-jaxrsserver-base', version: hapiFhirVersion
//
// /* ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig */
// implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-jpaserver-base', version: hapiFhirVersion
// implementation group: 'ca.uhn.hapi.fhir', name: 'hapi-fhir-jpa', version: hapiFhirVersion

/* H2 JPA */
implementation group: 'com.h2database', name: 'h2', version: h2databaseVersion

implementation group: 'org.apache.commons', name: 'commons-lang3', version: commonsLangVersion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
import java.util.List;
import java.util.Objects;

@SpringBootApplication
@SpringBootApplication(scanBasePackages = {"ca.uhn.fhir.context",
"my.hapifhirmimics",
"ca.uhn.example.gradleandspringbootexample.toplayers.springboottoplayers.quickexampleserver.compositionroot",
"ca.uhn.example.gradleandspringbootexample.toplayers.springboottoplayers.quickexampleserver.websecurity"})
//@ServletComponentScan
@Configuration
@ImportResource({"classpath*:applicationContext.xml"})
Expand Down Expand Up @@ -50,18 +53,18 @@ public static void main(final String[] args) {
if (logger.isDebugEnabled()) {
Resource[] items = getXMLResources();
for (Resource item : items) {
logger.debug(LOG_MSG_XML_RESOURCE_FILENAME, item.getFilename());
logger.info(LOG_MSG_XML_RESOURCE_FILENAME, item.getFilename());
}

List<File> list = getFiles(System.getProperty("java.class.path"));
for (File file : list) {
logger.debug(LOG_MSG_JAVA_CLASS_PATH_FILE_PATH, file.getPath());
logger.info(LOG_MSG_JAVA_CLASS_PATH_FILE_PATH, file.getPath());
}

String[] beanNames = applicationContext.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
logger.debug(LOG_MSG_GET_BEAN_DEFINITION_NAME, beanName);
logger.info(LOG_MSG_GET_BEAN_DEFINITION_NAME, beanName);
}
}

Expand Down
Loading