Skip to content

Commit

Permalink
CDR-1397 cleanup aql meta (ehrbase#604)
Browse files Browse the repository at this point in the history
* simplify set/get of additional properties in Meta
* deprecate old MetaData additional props
* add missing json annotation

---------

Co-authored-by: vinzenz.mueller <[email protected]>
Co-authored-by: Alexander Lehnert <[email protected]>
  • Loading branch information
3 people authored May 17, 2024
1 parent e7487f4 commit 7a3ef46
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 128 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public class MetaData {
* @see MetaData#setAdditionalProperty(String, Object)
* @param <T> of the additional property.
*/
@SuppressWarnings("unused")
@Deprecated(forRemoval = true)
public interface AdditionalProperty<T> extends Function<Object, T> {

/**
Expand Down Expand Up @@ -145,11 +147,13 @@ default Map<String, Object> apply(Object o) {

/**
* Meta additional property of type <code>any</code>.
* The entries are ordered by key.
*/
private final Map<String, Object> additionalProperties = new TreeMap<>();

public MetaData() {}

@Deprecated(forRemoval = true)
public MetaData(QueryResultDto queryResultDto) {

// initialize basic response meta data
Expand All @@ -159,7 +163,7 @@ public MetaData(QueryResultDto queryResultDto) {

// we always add the response set size - also in case it is empty
setAdditionalProperty(
AdditionalProperty.resultSize,
"resultsize",
Optional.ofNullable(queryResultDto.getResultSet())
.map(List::size)
.orElse(0));
Expand All @@ -168,8 +172,8 @@ public MetaData(QueryResultDto queryResultDto) {
Integer resultLimit = queryResultDto.getLimit();
Integer resultOffset = queryResultDto.getOffset();
if (resultLimit != null) {
setAdditionalProperty(AdditionalProperty.fetch, resultLimit);
setAdditionalProperty(AdditionalProperty.offset, resultOffset != null ? resultOffset : 0);
setAdditionalProperty("fetch", resultLimit);
setAdditionalProperty("offset", resultOffset != null ? resultOffset : 0);
}
// the following properties needs to be specified by the application
this.href = null;
Expand Down Expand Up @@ -240,6 +244,7 @@ public void setExecutedAql(String executedAql) {
* @param value to use
* @param <T> of the {@link AdditionalProperty}
*/
@Deprecated(forRemoval = true)
public <T> void setAdditionalProperty(AdditionalProperty<T> property, @Nullable T value) {
setAdditionalProperty(property.getName(), value);
}
Expand All @@ -249,15 +254,22 @@ public <T> void setAdditionalProperty(AdditionalProperty<T> property, @Nullable
*
* @see #setAdditionalProperty(AdditionalProperty, Object)
*/
@Deprecated(forRemoval = true)
public <T> @Nullable T getAdditionalProperty(AdditionalProperty<T> property) {
Object prop = additionalProperties().get(property.getName());
return prop != null ? (T) property.apply(prop) : null;
return prop != null ? property.apply(prop) : null;
}

// Internal access to additional properties
public <T> T getAdditionalProperty(String name, Class<T> type) {
return type.cast(getAdditionalProperty(name));
}

public Object getAdditionalProperty(String name) {
return additionalProperties.get(name);
}

@JsonAnySetter
private void setAdditionalProperty(String name, Object value) {
public void setAdditionalProperty(String name, Object value) {
additionalProperties.put(name, value);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class QueryResponseData {

// the initial query without substitution (!)
@JsonProperty(value = "q")
@JsonInclude(JsonInclude.Include.NON_NULL)
private String query;

@JsonProperty(value = "name")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,16 @@
*/
package org.ehrbase.openehr.sdk.response.dto;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.ehrbase.openehr.sdk.response.dto.util.JacksonTestUtil.objectMapper;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import com.fasterxml.jackson.core.JsonProcessingException;
import java.io.IOException;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.ehrbase.openehr.sdk.response.dto.util.DTOFixtures;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -67,13 +64,15 @@ void serializedJSON() throws JsonProcessingException {
metaData.setCreated(OffsetDateTime.parse("2017-08-19T12:30:00.568+02:00"));
metaData.setGenerator("DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)");
metaData.setExecutedAql("SELECT e/ehr_id/value FROM EHR e");
// debug info
metaData.setAdditionalProperty(MetaData.AdditionalProperty.fetch, 50);
metaData.setAdditionalProperty(MetaData.AdditionalProperty.offset, 100);
metaData.setAdditionalProperty(MetaData.AdditionalProperty.resultSize, 42);
// additional properties
metaData.setAdditionalProperty("string_value", "a_string");
metaData.setAdditionalProperty("numeric_value", 50);
metaData.setAdditionalProperty("boolean_value", true);
metaData.setAdditionalProperty("json_value", Map.of("key", "value"));

String json = objectMapper.writeValueAsString(metaData);

// the additional properties are ordered by key
assertThat(json)
.isEqualToNormalizingWhitespace(
"""
Expand All @@ -84,44 +83,12 @@ void serializedJSON() throws JsonProcessingException {
"_created" : "2017-08-19T12:30:00.568+02:00",
"_generator" : "DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)",
"_executed_aql" : "SELECT e/ehr_id/value FROM EHR e",
"fetch" : 50,
"offset" : 100,
"resultsize" : 42
}""");
}

@Test
void serializedJSONWithExecutionData() throws JsonProcessingException {

MetaData metaData = new MetaData();
metaData.setHref("https://example.com/subpath/ehrbase/rest/openehr/v1/query/aql");
metaData.setType(MetaData.RESULTSET);
metaData.setSchemaVersion("1.0.4");
metaData.setCreated(OffsetDateTime.parse("2017-08-19T12:30:00.568+02:00"));
metaData.setGenerator("DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)");
metaData.setExecutedAql("SELECT e/ehr_id/value FROM EHR e");
// debug info
metaData.setAdditionalProperty(MetaData.AdditionalProperty.dryRun, true);
metaData.setAdditionalProperty(MetaData.AdditionalProperty.executedSQL, "SELECT TRUE");
metaData.setAdditionalProperty(MetaData.AdditionalProperty.queryPlan, Map.of("key", "value"));

String json = objectMapper.writeValueAsString(metaData);

assertThat(json)
.isEqualToNormalizingWhitespace(
"""
{
"_href" : "https://example.com/subpath/ehrbase/rest/openehr/v1/query/aql",
"_type" : "RESULTSET",
"_schema_version" : "1.0.4",
"_created" : "2017-08-19T12:30:00.568+02:00",
"_generator" : "DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)",
"_executed_aql" : "SELECT e/ehr_id/value FROM EHR e",
"_dry_run" : true,
"_executed_sql" : "SELECT TRUE",
"_query_plan" : {
"boolean_value" : true,
"json_value" : {
"key" : "value"
}
},
"numeric_value" : 50,
"string_value" : "a_string"
}""");
}

Expand All @@ -140,9 +107,9 @@ void deserializedJSONMinimal() throws JsonProcessingException {

assertNull(metaData.getHref());
assertNull(metaData.getGenerator());
assertNull(metaData.getAdditionalProperty(MetaData.AdditionalProperty.fetch));
assertNull(metaData.getAdditionalProperty(MetaData.AdditionalProperty.offset));
assertNull(metaData.getAdditionalProperty(MetaData.AdditionalProperty.resultSize));
assertNull(metaData.getAdditionalProperty("fetch"));
assertNull(metaData.getAdditionalProperty("offset"));
assertNull(metaData.getAdditionalProperty("resultsize"));

assertEquals(MetaData.RESULTSET, metaData.getType());
assertEquals("1.0.4", metaData.getSchemaVersion());
Expand All @@ -164,43 +131,12 @@ void deserializeJSON() throws JsonProcessingException {
"_created" : "2017-08-19T00:25:47.568+02:00",
"_generator" : "DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)",
"_executed_aql" : "SELECT e/ehr_id/value FROM EHR e",
"fetch" : 50,
"offset" : 100,
"resultsize": 20
}""",
MetaData.class);

assertEquals("https://example.com/ehrbase/rest/openehr/v1/query/aql", metaData.getHref());
assertEquals(MetaData.RESULTSET, metaData.getType());
assertEquals("1.0.4", metaData.getSchemaVersion());
assertEquals(
OffsetDateTime.parse("2017-08-19T00:25:47.568+02:00").atZoneSameInstant(ZoneOffset.UTC),
metaData.getCreated().atZoneSameInstant(ZoneOffset.UTC));
assertEquals(
"DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)", metaData.getGenerator());
assertEquals("SELECT e/ehr_id/value FROM EHR e", metaData.getExecutedAql());
assertEquals(50, metaData.getAdditionalProperty(MetaData.AdditionalProperty.fetch));
assertEquals(100, metaData.getAdditionalProperty(MetaData.AdditionalProperty.offset));
assertEquals(20, metaData.getAdditionalProperty(MetaData.AdditionalProperty.resultSize));
}

@Test
void deserializeJSONWithExecutionData() throws JsonProcessingException {

MetaData metaData = objectMapper.readValue(
"""
{
"_href" : "https://example.com/ehrbase/rest/openehr/v1/query/aql",
"_type" : "RESULTSET",
"_schema_version" : "1.0.4",
"_created" : "2017-08-19T00:25:47.568+02:00",
"_generator" : "DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)",
"_executed_aql" : "SELECT e/ehr_id/value FROM EHR e",
"_dry_run" : true,
"_executed_sql" : "SELECT TRUE",
"_query_plan" : {
"boolean_value" : true,
"json_value" : {
"key" : "value"
}
},
"numeric_value" : 50,
"string_value" : "a_string"
}""",
MetaData.class);

Expand All @@ -213,56 +149,39 @@ void deserializeJSONWithExecutionData() throws JsonProcessingException {
assertEquals(
"DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)", metaData.getGenerator());
assertEquals("SELECT e/ehr_id/value FROM EHR e", metaData.getExecutedAql());
assertEquals(true, metaData.getAdditionalProperty(MetaData.AdditionalProperty.dryRun));
assertEquals("SELECT TRUE", metaData.getAdditionalProperty(MetaData.AdditionalProperty.executedSQL));
assertEquals(Map.of("key", "value"), metaData.getAdditionalProperty(MetaData.AdditionalProperty.queryPlan));
}

@Test
void deserializeRealWorldExample() throws IOException {

QueryResponseData queryResponseData = objectMapper.readValue(
IOUtils.resourceToString("/query_response.json", UTF_8), QueryResponseData.class);
MetaData metaData = queryResponseData.getMeta();

assertNotNull(metaData);

assertNull(metaData.getAdditionalProperty(MetaData.AdditionalProperty.fetch));
assertNull(metaData.getAdditionalProperty(MetaData.AdditionalProperty.offset));
assertNull(metaData.getAdditionalProperty(MetaData.AdditionalProperty.resultSize));

assertEquals("... the URI for the executed AQL - used only for GET executions ...", metaData.getHref());
assertEquals(
OffsetDateTime.parse("2017-08-19T00:25:47.568+02:00").atZoneSameInstant(ZoneOffset.UTC),
metaData.getCreated().atZoneSameInstant(ZoneOffset.UTC));
assertEquals(
"DIPS.OpenEhr.ResultSets.Serialization.Json.ResultSetJsonWriter (5.0.0.0)", metaData.getGenerator());
assertEquals("1.0.0", metaData.getSchemaVersion());
assertEquals("... the executed aql ...", metaData.getExecutedAql());
// additional properties
assertEquals("a_string", metaData.getAdditionalProperty("string_value"));
assertEquals(50, metaData.getAdditionalProperty("numeric_value", Integer.class));
assertEquals(true, metaData.getAdditionalProperty("boolean_value"));
assertEquals(Map.of("key", "value"), metaData.getAdditionalProperty("json_value"));
}

@Test
@Deprecated(forRemoval = true)
@SuppressWarnings("removal")
void fromQueryResult() {

MetaData metaData = new MetaData(DTOFixtures.fixtureQueryResultResultDto(resultDto -> {
resultDto.setCreated(OffsetDateTime.parse("2017-02-16T13:50:11.308+01:00"));
}));

assertNotNull(metaData, "Expected meta to be null");
assertEquals(metaData.getType(), "RESULTSET");
assertEquals(metaData.getExecutedAql(), "SELECT e/ehr_id/value FROM EHR e LIMIT 100 OFFSET 1");
assertEquals("RESULTSET", metaData.getType());
assertEquals("SELECT e/ehr_id/value FROM EHR e LIMIT 100 OFFSET 1", metaData.getExecutedAql());
assertEquals(
metaData.getCreated().atZoneSameInstant(ZoneOffset.UTC),
OffsetDateTime.parse("2017-02-16T13:50:11.308+01:00").atZoneSameInstant(ZoneOffset.UTC));
assertEquals(metaData.getAdditionalProperty(MetaData.AdditionalProperty.resultSize), 0);

assertNull(metaData.getAdditionalProperty(MetaData.AdditionalProperty.fetch));
assertNull(metaData.getAdditionalProperty(MetaData.AdditionalProperty.offset));
OffsetDateTime.parse("2017-02-16T13:50:11.308+01:00").atZoneSameInstant(ZoneOffset.UTC),
metaData.getCreated().atZoneSameInstant(ZoneOffset.UTC));
assertEquals(0, metaData.getAdditionalProperty("resultsize"));
assertNull(metaData.getAdditionalProperty("fetch"));
assertNull(metaData.getAdditionalProperty("offset"));
assertNull(metaData.getHref());
assertNull(metaData.getGenerator());
}

@Test
@Deprecated(forRemoval = true)
@SuppressWarnings("removal")
void fromQueryResultDoesContainFetchDefaultOffset() {

MetaData metaData = new MetaData(DTOFixtures.fixtureQueryResultResultDto(resultDto -> {
Expand All @@ -271,12 +190,14 @@ void fromQueryResultDoesContainFetchDefaultOffset() {
}));

assertNotNull(metaData, "Expected meta to be null");
assertEquals(metaData.getAdditionalProperty(MetaData.AdditionalProperty.fetch), 100);
assertEquals(metaData.getAdditionalProperty(MetaData.AdditionalProperty.offset), 0);
assertEquals(metaData.getAdditionalProperty(MetaData.AdditionalProperty.resultSize), 0);
assertEquals(100, metaData.getAdditionalProperty("fetch"));
assertEquals(0, metaData.getAdditionalProperty("offset"));
assertEquals(0, metaData.getAdditionalProperty("resultsize"));
}

@Test
@Deprecated(forRemoval = true)
@SuppressWarnings("removal")
void fromQueryResultContainsFetchOffset() {

MetaData metaData = new MetaData(DTOFixtures.fixtureQueryResultResultDto(resultDto -> {
Expand All @@ -286,8 +207,8 @@ void fromQueryResultContainsFetchOffset() {
}));

assertNotNull(metaData, "Expected meta to be null");
assertEquals(metaData.getAdditionalProperty(MetaData.AdditionalProperty.fetch), 100);
assertEquals(metaData.getAdditionalProperty(MetaData.AdditionalProperty.offset), 50);
assertEquals(metaData.getAdditionalProperty(MetaData.AdditionalProperty.resultSize), 0);
assertEquals(100, metaData.getAdditionalProperty("fetch"));
assertEquals(50, metaData.getAdditionalProperty("offset"));
assertEquals(0, metaData.getAdditionalProperty("resultsize"));
}
}

0 comments on commit 7a3ef46

Please sign in to comment.