Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for optional questionnaire items #161

Closed
wants to merge 9 commits into from
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package dev.dsf.fhir.authorization;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.hl7.fhir.r4.model.Questionnaire;
import org.hl7.fhir.r4.model.QuestionnaireResponse;
import org.hl7.fhir.r4.model.QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent;
import org.hl7.fhir.r4.model.QuestionnaireResponse.QuestionnaireResponseItemComponent;
Expand Down Expand Up @@ -87,6 +89,13 @@ private Optional<String> newResourceOk(QuestionnaireResponse newResource,

getItemAndValidate(newResource, CODESYSTEM_DSF_BPMN_USER_TASK_VALUE_USER_TASK_ID, errors);

String questionnaireUrlAndVersion = newResource.getQuestionnaire();
if (!questionnaireExists(questionnaireUrlAndVersion))
{
errors.add(
"Questionnaire ressource referenced via canonical QuestionnaireResponse.questionnaire does not exist");
}

if (errors.isEmpty())
return Optional.empty();
else
Expand Down Expand Up @@ -140,6 +149,23 @@ private Optional<String> getItemAndValidate(QuestionnaireResponse newResource, S
return Optional.of(value.getValue());
}

private boolean questionnaireExists(String questionnaireUrlAndVersion)
{
try
{
Optional<Questionnaire> questionnaire = daoProvider.getQuestionnaireDao()
.readByUrlAndVersion(questionnaireUrlAndVersion);

return questionnaire.isPresent();
}
catch (SQLException e)
{
logger.warn("Could not check questionnaire with url|version '{}' for questionnaire-response - {}",
questionnaireUrlAndVersion, e.getMessage());
throw new RuntimeException(e);
}
}

@Override
public Optional<String> reasonReadAllowed(Connection connection, Identity identity,
QuestionnaireResponse existingResource)
Expand Down Expand Up @@ -228,7 +254,16 @@ private boolean modificationsOk(QuestionnaireResponse oldResource, Questionnaire
"Modifications only allowed if item.answer with linkId '{}' not changed, change from '{}' to '{}' not allowed",
CODESYSTEM_DSF_BPMN_USER_TASK_VALUE_BUSINESS_KEY, oldUserTaskId, newUserTaskId);

return statusModificationOk && userTaskIdOk && businesssKeyOk;
String oldQuestionnaireUrlAndVersion = oldResource.getQuestionnaire();
String newQuestionnaireUrlAndVersion = newResource.getQuestionnaire();
boolean questionnaireCanonicalOk = oldResource.hasQuestionnaire() && newResource.hasQuestionnaire()
&& oldQuestionnaireUrlAndVersion.equals(newQuestionnaireUrlAndVersion);

if (!questionnaireCanonicalOk)
logger.warn("Modifications of QuestionnaireResponse.questionnaire not allowed, changed from '{}' to '{}'",
oldQuestionnaireUrlAndVersion, newQuestionnaireUrlAndVersion);

return statusModificationOk && userTaskIdOk && businesssKeyOk && questionnaireCanonicalOk;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.Measure;
import org.hl7.fhir.r4.model.Questionnaire;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.ValueSet;
import org.slf4j.Logger;
Expand All @@ -23,6 +24,7 @@
import ca.uhn.fhir.context.support.IValidationSupport;
import dev.dsf.fhir.dao.CodeSystemDao;
import dev.dsf.fhir.dao.MeasureDao;
import dev.dsf.fhir.dao.QuestionnaireDao;
import dev.dsf.fhir.dao.StructureDefinitionDao;
import dev.dsf.fhir.dao.ValueSetDao;
import dev.dsf.fhir.function.SupplierWithSqlException;
Expand All @@ -38,10 +40,11 @@ public class ValidationSupportWithFetchFromDb implements IValidationSupport, Ini
private final CodeSystemDao codeSystemDao;
private final ValueSetDao valueSetDao;
private final MeasureDao measureDao;
private final QuestionnaireDao questionnaireDao;

public ValidationSupportWithFetchFromDb(FhirContext context, StructureDefinitionDao structureDefinitionDao,
StructureDefinitionDao structureDefinitionSnapshotDao, CodeSystemDao codeSystemDao, ValueSetDao valueSetDao,
MeasureDao measureDao)
MeasureDao measureDao, QuestionnaireDao questionnaireDao)
{
this.context = context;

Expand All @@ -50,6 +53,7 @@ public ValidationSupportWithFetchFromDb(FhirContext context, StructureDefinition
this.codeSystemDao = codeSystemDao;
this.valueSetDao = valueSetDao;
this.measureDao = measureDao;
this.questionnaireDao = questionnaireDao;
}

@Override
Expand All @@ -59,6 +63,8 @@ public void afterPropertiesSet() throws Exception
Objects.requireNonNull(structureDefinitionSnapshotDao, "structureDefinitionSnapshotDao");
Objects.requireNonNull(codeSystemDao, "codeSystemDao");
Objects.requireNonNull(valueSetDao, "valueSetDao");
Objects.requireNonNull(measureDao, "measureDao");
Objects.requireNonNull(questionnaireDao, "questionnaireDao");
}

@Override
Expand Down Expand Up @@ -102,6 +108,11 @@ public <T extends IBaseResource> T fetchResource(Class<T> theClass, String theUr
return theClass.cast(fetchMeasure(theUri));
}

if (Questionnaire.class.equals(theClass))
{
return theClass.cast(fetchQuestionnaire(theUri));
}

return null;
}

Expand Down Expand Up @@ -163,4 +174,10 @@ public Measure fetchMeasure(String url)
else
return null;
}

public Questionnaire fetchQuestionnaire(String url)
{
Optional<Questionnaire> questionnaire = throwRuntimeException(() -> questionnaireDao.readByUrlAndVersion(url));
return questionnaire.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.Measure;
import org.hl7.fhir.r4.model.Questionnaire;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.ValueSet;
import org.slf4j.Logger;
Expand All @@ -22,6 +24,8 @@
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IValidationSupport;
import dev.dsf.fhir.dao.CodeSystemDao;
import dev.dsf.fhir.dao.MeasureDao;
import dev.dsf.fhir.dao.QuestionnaireDao;
import dev.dsf.fhir.dao.StructureDefinitionDao;
import dev.dsf.fhir.dao.ValueSetDao;
import dev.dsf.fhir.function.SupplierWithSqlException;
Expand All @@ -36,19 +40,24 @@ public class ValidationSupportWithFetchFromDbWithTransaction implements IValidat
private final StructureDefinitionDao structureDefinitionSnapshotDao;
private final CodeSystemDao codeSystemDao;
private final ValueSetDao valueSetDao;
private final MeasureDao measureDao;
private final QuestionnaireDao questionnaireDao;

private final Connection connection;

public ValidationSupportWithFetchFromDbWithTransaction(FhirContext context,
StructureDefinitionDao structureDefinitionDao, StructureDefinitionDao structureDefinitionSnapshotDao,
CodeSystemDao codeSystemDao, ValueSetDao valueSetDao, Connection connection)
CodeSystemDao codeSystemDao, ValueSetDao valueSetDao, MeasureDao measureDao,
QuestionnaireDao questionnaireDao, Connection connection)
{
this.context = context;

this.structureDefinitionDao = structureDefinitionDao;
this.structureDefinitionSnapshotDao = structureDefinitionSnapshotDao;
this.codeSystemDao = codeSystemDao;
this.valueSetDao = valueSetDao;
this.measureDao = measureDao;
this.questionnaireDao = questionnaireDao;

this.connection = connection;
}
Expand Down Expand Up @@ -91,6 +100,28 @@ public List<StructureDefinition> fetchAllStructureDefinitions()
return new ArrayList<>(byUrl.values());
}

@Override
public <T extends IBaseResource> T fetchResource(Class<T> theClass, String theUri)
{
T resource = IValidationSupport.super.fetchResource(theClass, theUri);
if (resource != null)
{
return resource;
}

if (Measure.class.equals(theClass))
{
return theClass.cast(fetchMeasure(theUri));
}

if (Questionnaire.class.equals(theClass))
{
return theClass.cast(fetchQuestionnaire(theUri));
}

return null;
}

@Override
public StructureDefinition fetchStructureDefinition(String url)
{
Expand Down Expand Up @@ -144,4 +175,19 @@ public ValueSet fetchValueSet(String url)
else
return null;
}

public Measure fetchMeasure(String url)
{
Optional<Measure> measure = throwRuntimeException(() -> measureDao.readByUrlAndVersion(url));
if (measure.isPresent())
return measure.get();
else
return null;
}

public Questionnaire fetchQuestionnaire(String url)
{
Optional<Questionnaire> questionnaire = throwRuntimeException(() -> questionnaireDao.readByUrlAndVersion(url));
return questionnaire.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public IValidationSupport validationSupport()
return new ValidationSupportWithCache(fhirConfig.fhirContext(),
validationSupportChain(new ValidationSupportWithFetchFromDb(fhirConfig.fhirContext(),
daoConfig.structureDefinitionDao(), daoConfig.structureDefinitionSnapshotDao(),
daoConfig.codeSystemDao(), daoConfig.valueSetDao(), daoConfig.measureDao())));
daoConfig.codeSystemDao(), daoConfig.valueSetDao(), daoConfig.measureDao(),
daoConfig.questionnaireDao())));
}

private ValidationSupportChain validationSupportChain(IValidationSupport dbSupport)
Expand Down Expand Up @@ -71,7 +72,8 @@ public IValidationSupport validationSupportWithTransaction(Connection connection
ValidationSupportWithCache validationSupport = new ValidationSupportWithCache(fhirConfig.fhirContext(),
validationSupportChain(new ValidationSupportWithFetchFromDbWithTransaction(fhirConfig.fhirContext(),
daoConfig.structureDefinitionDao(), daoConfig.structureDefinitionSnapshotDao(),
daoConfig.codeSystemDao(), daoConfig.valueSetDao(), connection)));
daoConfig.codeSystemDao(), daoConfig.valueSetDao(), daoConfig.measureDao(),
daoConfig.questionnaireDao(), connection)));

return validationSupport.populateCache(validationSupport().fetchAllConformanceResources());
}
Expand Down
Loading
Loading