Skip to content

Commit d76662c

Browse files
jkiddoadamzkoverCopilot
authored
Feature/cds config (#857)
* Added MCP support using SSE on http://localhost:8080/sse * Reverted change that IntelliJ complains about * Pre-rework * Cleaned up the code a fair bit * Renamed * Renamed * Running spotless * Reuse FhirContext in result serialization to make MCP server work with R5 * Added support for transactions * PoC tool for CDS Hooks * some cleanup * Upgrade of model protocol * Added comments * Removed field injection ... CDS to be changed to AutoConfig eventually * Adjusted to new builder pattern * Update src/main/java/ca/uhn/fhir/rest/server/MCPBridge.java Co-authored-by: Copilot <[email protected]> * A bit of restructuring * More rework * Removing (suspected unnecessary) formatting * Add more example doc * Added a smoke- / passthrough-test * Applied spotless * Update src/main/java/ca/uhn/fhir/jpa/starter/mcp/RequestBuilder.java Co-authored-by: Copilot <[email protected]> * Update src/main/java/ca/uhn/fhir/jpa/starter/mcp/RequestBuilder.java Co-authored-by: Copilot <[email protected]> * Update src/main/java/ca/uhn/fhir/jpa/starter/mcp/ToolFactory.java Co-authored-by: Copilot <[email protected]> * Update src/main/java/ca/uhn/fhir/rest/server/McpCdsBridge.java Co-authored-by: Copilot <[email protected]> * Update src/main/java/ca/uhn/fhir/rest/server/McpCdsBridge.java Co-authored-by: Copilot <[email protected]> * Formatting * Added some documentation * spotless cares about MD? * Reverting back to default values * minor refinements * Fixed CDS hooks configuration * Fixed some wirings * Readded missing elements * getting closer to get test running again ... * applying review * Readded exclude * Bumped spring-ai deps * added agents file * Updated according to review --------- Co-authored-by: Ádám Z. Kövér <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent d29b9f8 commit d76662c

20 files changed

+568
-537
lines changed

AGENTS.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Repository Guidelines
2+
3+
## Project Structure & Module Organization
4+
- `src/main/java`: Spring Boot entry point `ca.uhn.fhir.jpa.starter.Application`, resource providers, config.
5+
- `src/main/resources`: Application YAML, search parameter bundles, capability statements packaged with the WAR.
6+
- `src/main/webapp`: HAPI Testpage overlay shipped for the default UI.
7+
- `src/test/java` & `src/test/resources`: JUnit 5 suites (interceptors, MCP, MDM) plus matching fixtures grouped by FHIR version.
8+
- `charts/`, `docker-compose.yml`, `configs/`: Deployment templates for Helm, Docker, and Tomcat/server overrides.
9+
- `Dockerfile`, `build-docker-image.sh`: Reference container build scripts used by CI/CD.
10+
11+
## Build, Test, and Development Commands
12+
- `mvn clean install`: Compile, run Surefire + Failsafe, and emit `target/ROOT.war`.
13+
- `mvn spring-boot:run -Pboot`: Start the server on port 8080 with hot reload-friendly Boot profile.
14+
- `mvn clean package spring-boot:repackage -Pboot && java -jar target/ROOT.war`: Build and exercise the bootable WAR.
15+
- `docker-compose up -d --build`: Launch JPAServer + PostgreSQL using the local Dockerfile.
16+
- `docker run -p 8080:8080 hapiproject/hapi:latest`: Compare against the upstream binary distribution.
17+
18+
## Coding Style & Naming Conventions
19+
- Target Java 17, four-space indents, alphabetized imports, no wildcards.
20+
- Keep code under `ca.uhn.fhir.jpa.starter` and mirror packages in tests.
21+
- Prefer descriptive class suffixes (`*Provider`, `*Service`, `*Config`) and constructor injection with `final` collaborators.
22+
- YAML keys stay kebab-case; JSON fixtures use lower_snake_case filenames.
23+
24+
## Testing Guidelines
25+
- `mvn test`: Runs JUnit Jupiter unit suites such as `CustomBeanTest` and `ParallelUpdatesVersionConflictTest`.
26+
- `mvn verify`: Adds integration coverage through Failsafe with the default H2 datasource; if you pivot to PostgreSQL, run `mvn install -DskipTests` until fixtures are updated.
27+
- Store integration suites as `*IT.java` so Failsafe detects them and colocate datasets in `src/test/resources`.
28+
- Leverage Testcontainers and HAPI FHIR test utilities already declared in `pom.xml`.
29+
30+
## Commit & Pull Request Guidelines
31+
- Follow repository precedent: imperative summary, optional scope (`Feature/mcp`), and linked issue `(#123)` when applicable.
32+
- Keep commits narrowly scoped and include config or fixture updates with the code they support.
33+
- PRs should describe runtime impact (profiles, ports, env vars), reference issues, and include UI screenshots when behaviour changes.
34+
- Run `mvn verify` or the relevant Docker workflow before review; note any skipped checks and how to reproduce the result.
35+
36+
## Security & Configuration Tips
37+
- Do not commit secrets; stash overrides under `configs/` and explain required env vars in the PR.
38+
- When enabling external services, update `src/main/resources/application.yaml` plus sample overrides and mention connection expectations for reviewers.

pom.xml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -391,20 +391,14 @@
391391
<dependency>
392392
<groupId>org.springframework.ai</groupId>
393393
<artifactId>spring-ai-mcp</artifactId>
394-
<version>1.1.0-M1</version>
394+
<version>1.1.0-M2</version>
395395
</dependency>
396396

397397
<!--implementation("org.springframework.ai:spring-ai-starter-mcp-server-webmvc:1.1.0-M1")-->
398398
<dependency>
399399
<groupId>org.springframework.ai</groupId>
400400
<artifactId>spring-ai-starter-mcp-server</artifactId>
401-
<version>1.1.0-M1</version>
402-
</dependency>
403-
404-
<dependency>
405-
<groupId>io.modelcontextprotocol.sdk</groupId>
406-
<artifactId>mcp</artifactId>
407-
<version>0.12.1</version>
401+
<version>1.1.0-M2</version>
408402
</dependency>
409403

410404
<dependency>

src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksProperties.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package ca.uhn.fhir.jpa.starter.cdshooks;
22

33
import org.springframework.boot.context.properties.ConfigurationProperties;
4+
import org.springframework.context.annotation.Configuration;
45

6+
@Configuration
57
@ConfigurationProperties(prefix = "hapi.fhir.cdshooks")
68
public class CdsHooksProperties {
79

src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/CdsHooksServlet.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import ca.uhn.fhir.jpa.starter.AppProperties;
44
import ca.uhn.fhir.rest.api.server.cdshooks.CdsServiceRequestJson;
5-
import ca.uhn.fhir.rest.server.RestfulServer;
65
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
76
import ca.uhn.hapi.fhir.cdshooks.api.ICdsServiceRegistry;
87
import ca.uhn.hapi.fhir.cdshooks.api.json.CdsServiceResponseJson;
@@ -43,9 +42,6 @@ public class CdsHooksServlet extends HttpServlet {
4342
@Autowired
4443
ICdsServiceRegistry cdsServiceRegistry;
4544

46-
@Autowired
47-
RestfulServer restfulServer;
48-
4945
@Autowired
5046
@Qualifier(CDS_HOOKS_OBJECT_MAPPER_FACTORY)
5147
ObjectMapper objectMapper;

src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/ProviderConfiguration.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package ca.uhn.fhir.jpa.starter.cdshooks;
22

3-
import ca.uhn.fhir.jpa.starter.cr.CrProperties;
3+
import ca.uhn.fhir.jpa.starter.cr.CqlRuntimeProperties;
44

55
public class ProviderConfiguration {
66
private final String clientIdHeaderName;
@@ -11,8 +11,8 @@ public ProviderConfiguration(boolean cqlLoggingEnabled, String clientIdHeaderNam
1111
this.clientIdHeaderName = clientIdHeaderName;
1212
}
1313

14-
public ProviderConfiguration(CdsHooksProperties cdsProperties, CrProperties crProperties) {
15-
this(crProperties.getCql().getRuntime().isDebugLoggingEnabled(), cdsProperties.getClientIdHeaderName());
14+
public ProviderConfiguration(CdsHooksProperties cdsProperties, CqlRuntimeProperties cqlRuntimeProperties) {
15+
this(cqlRuntimeProperties.isDebugLoggingEnabled(), cdsProperties.getClientIdHeaderName());
1616
}
1717

1818
public String getClientIdHeaderName() {

src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/StarterCdsHooksConfig.java

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
package ca.uhn.fhir.jpa.starter.cdshooks;
22

3-
import ca.uhn.fhir.context.FhirVersionEnum;
4-
import ca.uhn.fhir.jpa.starter.cr.CrCommonConfig;
5-
import ca.uhn.fhir.jpa.starter.cr.CrConfigCondition;
6-
import ca.uhn.fhir.jpa.starter.cr.CrProperties;
3+
import ca.uhn.fhir.jpa.starter.cr.*;
74
import ca.uhn.hapi.fhir.cdshooks.api.ICdsHooksDaoAuthorizationSvc;
5+
import ca.uhn.hapi.fhir.cdshooks.config.CdsHooksConfig;
86
import ca.uhn.hapi.fhir.cdshooks.svc.CdsHooksContextBooter;
97
import org.hl7.fhir.instance.model.api.IBaseResource;
10-
import org.opencds.cqf.fhir.cr.hapi.cdshooks.CdsCrServiceRegistry;
118
import org.opencds.cqf.fhir.cr.hapi.cdshooks.CdsCrSettings;
12-
import org.opencds.cqf.fhir.cr.hapi.cdshooks.ICdsCrServiceRegistry;
13-
import org.opencds.cqf.fhir.cr.hapi.cdshooks.discovery.CdsCrDiscoveryServiceRegistry;
14-
import org.opencds.cqf.fhir.cr.hapi.cdshooks.discovery.ICdsCrDiscoveryServiceRegistry;
159
import org.opencds.cqf.fhir.cr.hapi.config.CrCdsHooksConfig;
1610
import org.opencds.cqf.fhir.cr.hapi.config.RepositoryConfig;
17-
import org.opencds.cqf.fhir.cr.hapi.config.test.TestCdsHooksConfig;
1811
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
1912
import org.springframework.boot.web.servlet.ServletRegistrationBean;
2013
import org.springframework.context.annotation.Bean;
@@ -24,30 +17,9 @@
2417

2518
@Configuration
2619
@Conditional({CdsHooksConfigCondition.class, CrConfigCondition.class})
27-
@Import({RepositoryConfig.class, TestCdsHooksConfig.class, CrCdsHooksConfig.class, CrCommonConfig.class})
20+
@Import({RepositoryConfig.class, CrCdsHooksConfig.class, CrCommonConfig.class, CdsHooksConfig.class})
2821
public class StarterCdsHooksConfig {
2922

30-
@Bean
31-
public ICdsCrDiscoveryServiceRegistry cdsCrDiscoveryServiceRegistry() {
32-
CdsCrDiscoveryServiceRegistry registry = new CdsCrDiscoveryServiceRegistry();
33-
registry.unregister(FhirVersionEnum.R4);
34-
registry.register(FhirVersionEnum.R4, UpdatedCrDiscoveryService.class);
35-
return registry;
36-
}
37-
38-
@Bean
39-
public ICdsCrServiceRegistry cdsCrServiceRegistry() {
40-
CdsCrServiceRegistry registry = new CdsCrServiceRegistry();
41-
registry.unregister(FhirVersionEnum.R4);
42-
registry.register(FhirVersionEnum.R4, UpdatedCdsCrService.class);
43-
return registry;
44-
}
45-
46-
@Bean
47-
public CdsHooksProperties cdsHooksProperties() {
48-
return new CdsHooksProperties();
49-
}
50-
5123
@Bean
5224
public CdsCrSettings cdsCrSettings(CdsHooksProperties cdsHooksProperties) {
5325
CdsCrSettings settings = CdsCrSettings.getDefault();
@@ -67,8 +39,9 @@ public void authorizePreShow(IBaseResource theResource) {}
6739
}
6840

6941
@Bean
70-
public ProviderConfiguration providerConfiguration(CdsHooksProperties cdsProperties, CrProperties crProperties) {
71-
return new ProviderConfiguration(cdsProperties, crProperties);
42+
public ProviderConfiguration providerConfiguration(
43+
CdsHooksProperties cdsProperties, CqlProperties cqlProperties, CqlRuntimeProperties cqlRuntimeProperties) {
44+
return new ProviderConfiguration(cdsProperties, cqlRuntimeProperties);
7245
}
7346

7447
@Bean

src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/UpdatedCdsCrService.java

Lines changed: 0 additions & 42 deletions
This file was deleted.

src/main/java/ca/uhn/fhir/jpa/starter/cdshooks/UpdatedCrDiscoveryService.java

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/main/java/ca/uhn/fhir/jpa/starter/cr/CareGapsProperties.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package ca.uhn.fhir.jpa.starter.cr;
22

3+
import org.springframework.boot.context.properties.ConfigurationProperties;
4+
import org.springframework.context.annotation.Configuration;
5+
6+
@Configuration
7+
@ConfigurationProperties(prefix = "hapi.fhir.cr.caregaps")
38
public class CareGapsProperties {
49
private String reporter = "default";
510
private String section_author = "default";

src/main/java/ca/uhn/fhir/jpa/starter/cr/CqlCompilerProperties.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import org.cqframework.cql.cql2elm.CqlCompilerException;
44
import org.cqframework.cql.cql2elm.CqlTranslator;
55
import org.cqframework.cql.cql2elm.LibraryBuilder;
6+
import org.springframework.boot.context.properties.ConfigurationProperties;
7+
import org.springframework.context.annotation.Configuration;
68

9+
@Configuration
10+
@ConfigurationProperties(prefix = "hapi.fhir.cr.cql.compiler")
711
public class CqlCompilerProperties {
812
private Boolean validate_units = true;
913
private Boolean verify_only = false;

0 commit comments

Comments
 (0)