Skip to content

Commit

Permalink
#374 - Extend API to save and load cohort and dataselection
Browse files Browse the repository at this point in the history
- remove unused methods
  • Loading branch information
michael-82 committed Feb 28, 2025
1 parent b4b7961 commit f3d8e98
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 244 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.numcodex.feasibility_gui_backend.query.api.Query;
import de.numcodex.feasibility_gui_backend.query.api.Dataquery;
import de.numcodex.feasibility_gui_backend.query.api.*;
import de.numcodex.feasibility_gui_backend.query.dataquery.DataqueryException;
import de.numcodex.feasibility_gui_backend.query.dataquery.DataqueryHandler;
import de.numcodex.feasibility_gui_backend.query.dispatch.QueryDispatchException;
import de.numcodex.feasibility_gui_backend.query.dispatch.QueryDispatcher;
import de.numcodex.feasibility_gui_backend.query.persistence.*;
Expand Down Expand Up @@ -36,9 +33,6 @@ public enum ResultDetail {
@NonNull
private final QueryDispatcher queryDispatcher;

@NonNull
private final DataqueryHandler dataqueryHandler;

@NonNull
private final QueryRepository queryRepository;

Expand Down Expand Up @@ -116,50 +110,10 @@ private Query convertQueryToApi(de.numcodex.feasibility_gui_backend.query.persis
.build();
}

public List<de.numcodex.feasibility_gui_backend.query.persistence.Query> getQueryListForAuthor(
String userId) {
return queryRepository.findByAuthor(userId).orElseGet(ArrayList::new);
}

public String getAuthorId(Long queryId) throws QueryNotFoundException {
return queryRepository.getAuthor(queryId).orElseThrow(QueryNotFoundException::new);
}

public QueryListEntry convertQueryToQueryListEntry(de.numcodex.feasibility_gui_backend.query.persistence.Query query,
boolean skipValidation) {
boolean isValid = true;
if (!skipValidation) {
try {
var sq = jsonUtil.readValue(query.getQueryContent().getQueryContent(), StructuredQuery.class);
isValid = structuredQueryValidation.isValid(sq);
} catch (JsonProcessingException e) {
isValid = false;
}
}

if (skipValidation) {
return
QueryListEntry.builder()
.id(query.getId())
.createdAt(query.getCreatedAt())
.build();
} else {
return
QueryListEntry.builder()
.id(query.getId())
.createdAt(query.getCreatedAt())
.isValid(isValid)
.build();
}
}

public List<QueryListEntry> convertQueriesToQueryListEntries(List<de.numcodex.feasibility_gui_backend.query.persistence.Query> queryList,
boolean skipValidation) {
var ret = new ArrayList<QueryListEntry>();
queryList.forEach(q -> ret.add(convertQueryToQueryListEntry(q, skipValidation)));
return ret;
}

public Long getAmountOfQueriesByUserAndInterval(String userId, int minutes) {
return queryRepository.countQueriesByAuthorInTheLastNMinutes(userId, minutes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import de.numcodex.feasibility_gui_backend.query.api.Crtdl;
import de.numcodex.feasibility_gui_backend.query.api.Dataquery;
import de.numcodex.feasibility_gui_backend.query.api.status.SavedQuerySlots;
import de.numcodex.feasibility_gui_backend.query.dataquery.DataqueryException;
import de.numcodex.feasibility_gui_backend.query.dataquery.DataqueryHandler;
import de.numcodex.feasibility_gui_backend.query.dataquery.DataqueryStorageFullException;
Expand All @@ -12,7 +11,6 @@
import jakarta.ws.rs.core.Context;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -55,8 +53,6 @@ public ResponseEntity<Object> storeDataquery(@RequestBody Dataquery dataquery,
} catch (DataqueryException e) {
log.error("Error while storing dataquery", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
} catch (DataIntegrityViolationException e) {
return new ResponseEntity<>(HttpStatus.CONFLICT);
} catch (DataqueryStorageFullException e) {
return new ResponseEntity<>("storage exceeded", HttpStatus.FORBIDDEN);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,178 +1,74 @@
package de.numcodex.feasibility_gui_backend.query;

import de.numcodex.feasibility_gui_backend.query.dataquery.DataqueryHandler;
import de.numcodex.feasibility_gui_backend.query.dispatch.QueryDispatchException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.numcodex.feasibility_gui_backend.common.api.Criterion;
import de.numcodex.feasibility_gui_backend.common.api.TermCode;
import de.numcodex.feasibility_gui_backend.query.api.QueryListEntry;
import de.numcodex.feasibility_gui_backend.query.api.StructuredQuery;
import de.numcodex.feasibility_gui_backend.query.dispatch.QueryDispatchException;
import de.numcodex.feasibility_gui_backend.query.dispatch.QueryDispatcher;
import de.numcodex.feasibility_gui_backend.query.persistence.*;
import de.numcodex.feasibility_gui_backend.query.persistence.QueryContentRepository;
import de.numcodex.feasibility_gui_backend.query.persistence.QueryRepository;
import de.numcodex.feasibility_gui_backend.query.result.ResultService;
import de.numcodex.feasibility_gui_backend.terminology.validation.StructuredQueryValidation;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.test.StepVerifier;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;

import java.net.URI;
import java.sql.Timestamp;
import java.util.List;
import java.util.Random;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doThrow;

@ExtendWith(MockitoExtension.class)
class QueryHandlerServiceTest {

private static final long QUERY_ID = 1L;
private static final long RESULT_SIZE = 150L;
private static final String CREATOR = "author-123";
private static final String QUERY_CONTENT_HASH = "c85f4c5c8e22275b6efcf41f4f3b6d4b";
private static final String LABEL = "label";
private static final String COMMENT = "comment";
public static final String LAST_MODIFIED_STRING = "1969-07-20 20:17:40.0";
private static final Timestamp LAST_MODIFIED = Timestamp.valueOf(LAST_MODIFIED_STRING);

@Spy
private ObjectMapper jsonUtil = new ObjectMapper();

@Mock
private QueryDispatcher queryDispatcher;

@Mock
private DataqueryHandler dataqueryHandler;

@Mock
private QueryRepository queryRepository;

@Mock
private QueryContentRepository queryContentRepository;

@Mock
private ResultService resultService;

@Mock
private StructuredQueryValidation structuredQueryValidation;

private QueryHandlerService queryHandlerService;

private QueryHandlerService createQueryHandlerService() {
return new QueryHandlerService(queryDispatcher, dataqueryHandler, queryRepository, queryContentRepository,
resultService, structuredQueryValidation, jsonUtil);
}

@BeforeEach
void setUp() {
Mockito.reset(queryDispatcher, dataqueryHandler, queryRepository, queryContentRepository,
resultService, jsonUtil);
queryHandlerService = createQueryHandlerService();
}

@Test
public void testRunQuery_failsWithMonoErrorOnQueryDispatchException() throws QueryDispatchException {
var testStructuredQuery = StructuredQuery.builder()
.inclusionCriteria(List.of(List.of()))
.exclusionCriteria(List.of(List.of()))
.build();
var queryHandlerService = createQueryHandlerService();
doThrow(QueryDispatchException.class).when(queryDispatcher).enqueueNewQuery(any(StructuredQuery.class), any(String.class));

StepVerifier.create(queryHandlerService.runQuery(testStructuredQuery, "uerid"))
.expectError(QueryDispatchException.class)
.verify();
}

@ParameterizedTest
@CsvSource({"false,true", "false,false"})
void convertQueriesToQueryListEntries(String skipValidation) throws JsonProcessingException {
var queryList = List.of(createQuery());
if (!Boolean.parseBoolean(skipValidation)) {
doReturn(
new Random().nextBoolean()
).when(structuredQueryValidation).isValid(any(StructuredQuery.class));
}

List<QueryListEntry> queryListEntries = queryHandlerService.convertQueriesToQueryListEntries(queryList, Boolean.parseBoolean(skipValidation));

assertThat(queryListEntries.size()).isEqualTo(1);
assertThat(queryListEntries.get(0).id()).isEqualTo(QUERY_ID);
assertThat(queryListEntries.get(0).createdAt()).isEqualTo(LAST_MODIFIED);
if (Boolean.parseBoolean(skipValidation)) {
assertThat(queryListEntries.get(0).isValid()).isNull();
} else {
assertThat(queryListEntries.get(0).isValid()).isNotNull();
}
}

@Test
void convertQueriesToQueryListEntries_JsonProcessingExceptionCausesInvalidQuery() throws JsonProcessingException {
var queryList = List.of(createQuery());
doThrow(JsonProcessingException.class).when(jsonUtil).readValue(any(String.class), any(Class.class));

List<QueryListEntry> queryListEntries = queryHandlerService.convertQueriesToQueryListEntries(queryList, false);

assertThat(queryListEntries.size()).isEqualTo(1);
assertThat(queryListEntries.get(0).id()).isEqualTo(QUERY_ID);
assertThat(queryListEntries.get(0).createdAt()).isEqualTo(LAST_MODIFIED);
assertThat(queryListEntries.get(0).isValid()).isFalse();
}

private Query createQuery() throws JsonProcessingException {
var query = new Query();
query.setId(QUERY_ID);
query.setCreatedAt(LAST_MODIFIED);
query.setCreatedBy(CREATOR);
query.setQueryContent(createQueryContent());
return query;
}

private QueryContent createQueryContent() throws JsonProcessingException {
var queryContentString = jsonUtil.writeValueAsString(createValidStructuredQuery());
var queryContent = new QueryContent(queryContentString);
queryContent.setHash(QUERY_CONTENT_HASH);
return queryContent;
}

private StructuredQuery createValidStructuredQuery() {
var termCode = TermCode.builder()
.code("LL2191-6")
.system("http://loinc.org")
.display("Geschlecht")
.build();
var inclusionCriterion = Criterion.builder()
.termCodes(List.of(termCode))
.attributeFilters(List.of())
.build();
return StructuredQuery.builder()
.version(URI.create("http://to_be_decided.com/draft-2/schema#"))
.inclusionCriteria(List.of(List.of(inclusionCriterion)))
.exclusionCriteria(List.of())
.display("foo")
.build();
}

private Criterion createInvalidCriterion() {
var termCode = TermCode.builder()
.code("LL2191-6")
.system("http://loinc.org")
.display("Geschlecht")
.build();
return Criterion.builder()
.context(null)
.termCodes(List.of(termCode))
.build();
}

@Spy
private ObjectMapper jsonUtil = new ObjectMapper();

@Mock
private QueryDispatcher queryDispatcher;

@Mock
private QueryRepository queryRepository;

@Mock
private QueryContentRepository queryContentRepository;

@Mock
private ResultService resultService;

@Mock
private StructuredQueryValidation structuredQueryValidation;

private QueryHandlerService queryHandlerService;

private QueryHandlerService createQueryHandlerService() {
return new QueryHandlerService(queryDispatcher, queryRepository, queryContentRepository,
resultService, structuredQueryValidation, jsonUtil);
}

@BeforeEach
void setUp() {
Mockito.reset(queryDispatcher, queryRepository, queryContentRepository,
resultService, jsonUtil);
queryHandlerService = createQueryHandlerService();
}

@Test
public void testRunQuery_failsWithMonoErrorOnQueryDispatchException() throws QueryDispatchException {
var testStructuredQuery = StructuredQuery.builder()
.inclusionCriteria(List.of(List.of()))
.exclusionCriteria(List.of(List.of()))
.build();
var queryHandlerService = createQueryHandlerService();
doThrow(QueryDispatchException.class).when(queryDispatcher).enqueueNewQuery(any(StructuredQuery.class), any(String.class));

StepVerifier.create(queryHandlerService.runQuery(testStructuredQuery, "uerid"))
.expectError(QueryDispatchException.class)
.verify();
}
}
Loading

0 comments on commit f3d8e98

Please sign in to comment.