diff --git a/.github/integration-test/docker-compose.yml b/.github/integration-test/docker-compose.yml
index ef9b191c..1ad177ae 100644
--- a/.github/integration-test/docker-compose.yml
+++ b/.github/integration-test/docker-compose.yml
@@ -87,7 +87,7 @@ services:
POSTGRES_DB: "dataportal"
dataportal-elastic:
- image: docker.elastic.co/elasticsearch/elasticsearch:8.16.0
+ image: docker.elastic.co/elasticsearch/elasticsearch:8.16.1
container_name: dataportal-elastic
ports:
- '9200:9200'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 94d155cd..7b5ea5f1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+## [6.0.4] - 2025-01-10
+
+### Fixed
+- Time Restriction validation was broken when only one of beforeDate or afterDate was set ([#421](https://github.com/medizininformatik-initiative/feasibility-backend/issues/421))
+- ### Security
+- Update Spring Boot to 3.4.1
+
## [6.0.3] - 2024-12-10
### Changed
diff --git a/docker-compose.yml b/docker-compose.yml
index 8b7af92e..0c2aa0d3 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -111,7 +111,7 @@ services:
source: dataportal-postgres-data
target: /var/lib/postgresql/data
dataportal-elastic:
- image: docker.elastic.co/elasticsearch/elasticsearch:8.16.0
+ image: docker.elastic.co/elasticsearch/elasticsearch:8.16.1
container_name: dataportal-elastic
ports:
- '9200:9200'
diff --git a/pom.xml b/pom.xml
index a039975c..59370360 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,13 +6,13 @@
org.springframework.boot
spring-boot-starter-parent
- 3.4.0
+ 3.4.1
de.medizininformatik-initiative
DataportalBackend
- 6.0.3
+ 6.0.4
Dataportal Backend
Backend of the Dataportal
diff --git a/src/main/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidation.java b/src/main/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidation.java
index d688580b..d8f23521 100644
--- a/src/main/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidation.java
+++ b/src/main/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidation.java
@@ -129,8 +129,8 @@ private boolean containsInvalidCriteria(List criteria) {
}
private boolean isTimeRestrictionInvalid(TimeRestriction timeRestriction) {
- // If no timeRestriction is set, it is not invalid
- if (timeRestriction == null) {
+ // If no timeRestriction is set or only on of both dates is set, it is not invalid
+ if (timeRestriction == null || timeRestriction.beforeDate() == null || timeRestriction.afterDate() == null) {
return false;
}
return LocalDate.parse(timeRestriction.beforeDate()).isBefore(LocalDate.parse(timeRestriction.afterDate()));
diff --git a/src/test/java/de/numcodex/feasibility_gui_backend/terminology/es/CodeableConceptServiceIT.java b/src/test/java/de/numcodex/feasibility_gui_backend/terminology/es/CodeableConceptServiceIT.java
index 3c16d568..27565b93 100644
--- a/src/test/java/de/numcodex/feasibility_gui_backend/terminology/es/CodeableConceptServiceIT.java
+++ b/src/test/java/de/numcodex/feasibility_gui_backend/terminology/es/CodeableConceptServiceIT.java
@@ -25,7 +25,6 @@
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-@Disabled("There seems to be a concurrency issue with TerminologyServiceIT. Disable this for now until it is fixed.")
@Tag("terminology")
@Tag("elasticsearch")
@Import({CodeableConceptService.class})
@@ -46,7 +45,7 @@ public class CodeableConceptServiceIT {
@Container
@ServiceConnection
- public static ElasticsearchContainer ELASTICSEARCH_CONTAINER = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:8.16.0")
+ public static ElasticsearchContainer ELASTICSEARCH_CONTAINER = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:8.16.1")
.withEnv("discovery.type", "single-node")
.withEnv("xpack.security.enabled", "false")
.withReuse(false)
@@ -56,7 +55,7 @@ public class CodeableConceptServiceIT {
.waitingFor(Wait.forHttp("/health").forStatusCodeMatching(c -> c >= 200 && c <= 500));
@BeforeAll
- static void setUp() {
+ static void setUp() throws InterruptedException {
ELASTICSEARCH_CONTAINER.start();
WebClient webClient = WebClient.builder().baseUrl("http://" + ELASTICSEARCH_CONTAINER.getHttpHostAddress()).build();
webClient.put()
@@ -72,6 +71,9 @@ static void setUp() {
.retrieve()
.toBodilessEntity()
.block();
+
+ // When running in github actions without a slight delay, the data might not be complete in the elastic search container (although a blocking call is used)
+ Thread.sleep(1000);
}
@AfterAll
diff --git a/src/test/java/de/numcodex/feasibility_gui_backend/terminology/es/TerminologyEsServiceIT.java b/src/test/java/de/numcodex/feasibility_gui_backend/terminology/es/TerminologyEsServiceIT.java
index b63d4bf2..0919222f 100644
--- a/src/test/java/de/numcodex/feasibility_gui_backend/terminology/es/TerminologyEsServiceIT.java
+++ b/src/test/java/de/numcodex/feasibility_gui_backend/terminology/es/TerminologyEsServiceIT.java
@@ -51,7 +51,7 @@ public class TerminologyEsServiceIT {
@Container
@ServiceConnection
- public static ElasticsearchContainer ELASTICSEARCH_CONTAINER = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:8.16.0")
+ public static ElasticsearchContainer ELASTICSEARCH_CONTAINER = new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:8.16.1")
.withEnv("discovery.type", "single-node")
.withEnv("xpack.security.enabled", "false")
.withReuse(false)
diff --git a/src/test/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidationTest.java b/src/test/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidationTest.java
index e4ab71b5..b9c6771a 100644
--- a/src/test/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidationTest.java
+++ b/src/test/java/de/numcodex/feasibility_gui_backend/terminology/validation/StructuredQueryValidationTest.java
@@ -70,6 +70,22 @@ void testIsValid_falseOnInvalidTimeRestriction() {
assertFalse(isValid);
}
+ @Test
+ void testIsValid_trueOnOnlyBeforeDateTimeRestriction() {
+ doReturn(true).when(terminologyService).isExistingTermCode(any(String.class), any(String.class));
+ var isValid = structuredQueryValidation.isValid(createStructuredQueryWithOnlyBeforeDate());
+
+ assertTrue(isValid);
+ }
+
+ @Test
+ void testIsValid_trueOnOnlyAfterDateTimeRestriction() {
+ doReturn(true).when(terminologyService).isExistingTermCode(any(String.class), any(String.class));
+ var isValid = structuredQueryValidation.isValid(createStructuredQueryWithOnlyAfterDate());
+
+ assertTrue(isValid);
+ }
+
@ParameterizedTest
@CsvSource({"true,true", "true,false", "false,true", "false,false"})
void testAnnotateStructuredQuery_emptyIssuesOnValidCriteriaOrSkippedValidation(String withExclusionCriteriaString, String skipValidationString) {
@@ -201,4 +217,64 @@ private static StructuredQuery createStructuredQueryWithInvalidTimeRestriction()
.display("foo")
.build();
}
+
+ @NotNull
+ private static StructuredQuery createStructuredQueryWithOnlyBeforeDate() {
+ var context = TermCode.builder()
+ .code("Laboruntersuchung")
+ .system("fdpg.mii.cds")
+ .display("Laboruntersuchung")
+ .version("1.0.0")
+ .build();
+ var termCode = TermCode.builder()
+ .code("19113-0")
+ .system("http://loinc.org")
+ .display("IgE")
+ .build();
+ var timeRestriction = TimeRestriction.builder()
+ .beforeDate("1991-06-15")
+ .build();
+ var criterion = Criterion.builder()
+ .termCodes(List.of(termCode))
+ .context(context)
+ .attributeFilters(List.of())
+ .timeRestriction(timeRestriction)
+ .build();
+ return StructuredQuery.builder()
+ .version(URI.create("http://to_be_decided.com/draft-2/schema#"))
+ .inclusionCriteria(List.of(List.of(criterion)))
+ .exclusionCriteria(List.of())
+ .display("foo")
+ .build();
+ }
+
+ @NotNull
+ private static StructuredQuery createStructuredQueryWithOnlyAfterDate() {
+ var context = TermCode.builder()
+ .code("Laboruntersuchung")
+ .system("fdpg.mii.cds")
+ .display("Laboruntersuchung")
+ .version("1.0.0")
+ .build();
+ var termCode = TermCode.builder()
+ .code("19113-0")
+ .system("http://loinc.org")
+ .display("IgE")
+ .build();
+ var timeRestriction = TimeRestriction.builder()
+ .afterDate("1998-05-09")
+ .build();
+ var criterion = Criterion.builder()
+ .termCodes(List.of(termCode))
+ .context(context)
+ .attributeFilters(List.of())
+ .timeRestriction(timeRestriction)
+ .build();
+ return StructuredQuery.builder()
+ .version(URI.create("http://to_be_decided.com/draft-2/schema#"))
+ .inclusionCriteria(List.of(List.of(criterion)))
+ .exclusionCriteria(List.of())
+ .display("foo")
+ .build();
+ }
}