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

FM2-130:Adding support for the FHIR Media resource #328

Draft
wants to merge 31 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d785e97
FM2-130:Adding support for the FHIR Media resource
tendomart Feb 15, 2021
68e5bd4
Refining Media Complex Obs Handler
tendomart Feb 16, 2021
d508846
Merge branch 'master' of https://github.com/openmrs/openmrs-module-fh…
tendomart Feb 16, 2021
39be2b1
Adding Search params , Service and Translator Layers
tendomart Feb 16, 2021
0aca54d
Doing more refining
tendomart Feb 18, 2021
b28be07
Merge branch 'master' of https://github.com/openmrs/openmrs-module-fh…
tendomart Feb 18, 2021
53d8ff7
Implementing fhir media translator
tendomart Mar 30, 2021
ba5c351
Merge branch 'master' of https://github.com/openmrs/openmrs-module-fh…
tendomart Mar 30, 2021
027f483
Doing cleaning
tendomart Mar 30, 2021
9fda48d
Removing duplicate code
tendomart Mar 30, 2021
5041fa2
Doing more refactorings and adding unit tests for Tranlator , service…
tendomart Mar 31, 2021
f4a4bed
Fine tuning Media search params doing other changes
tendomart Apr 1, 2021
1ba904b
Merge branch 'master' of https://github.com/openmrs/openmrs-module-fh…
tendomart Apr 1, 2021
dd4b80e
Doing more refactoring
tendomart Apr 6, 2021
da7d841
Removing commented out lines
tendomart Apr 6, 2021
aea79f8
Doing more rectifications
tendomart Apr 7, 2021
b26adb3
Adding search params and FhirMediaDaoImplTest
tendomart Apr 12, 2021
d2625e6
Adding Media element translators
tendomart Apr 14, 2021
74103bc
Merge branch 'master' of https://github.com/openmrs/openmrs-module-fh…
tendomart Apr 14, 2021
119fb76
Deleting unnecessary Media Translators
tendomart Apr 15, 2021
619d08b
Refining Translators
tendomart Apr 28, 2021
ee13f88
Merge branch 'master' of https://github.com/openmrs/openmrs-module-fh…
tendomart Apr 28, 2021
86e2ca9
Refining MediaContentTranslator and Accompanying tests
tendomart Apr 30, 2021
a8c2605
Refactoring translators
tendomart May 5, 2021
3933575
Merge branch 'master' of https://github.com/openmrs/openmrs-module-fh…
tendomart May 5, 2021
93f2f45
Rectifying project build failure
tendomart May 7, 2021
9c843e8
Doing more fixes
tendomart May 27, 2021
bb9dbdf
Dealing with FhirMediaDaoImplTest failing tests
tendomart Jun 4, 2021
b6888be
Making FhirMediaDaoImpl CRUD methods work
tendomart Jun 7, 2021
6d2e407
Merge branch 'master' of https://github.com/openmrs/openmrs-module-fh…
tendomart Jun 7, 2021
5c79a15
Removing redundant code
tendomart Jun 7, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 7 additions & 1 deletion api/pom.xml
Expand Up @@ -59,7 +59,13 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.4.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<plugins>
Expand Down
23 changes: 23 additions & 0 deletions api/src/main/java/org/openmrs/module/fhir2/FhirConstants.java
Expand Up @@ -69,6 +69,8 @@ private FhirConstants() {

public static final String ENCOUNTER_CLASS_VALUE_SET_URI = HL7_FHIR_CODE_SYSTEM_PREFIX + "/v3-ActCode";

public static final String MEDIA_CREATED_DATE_TIME = "media.created.date.time";

@Value("${project.version}")
public static String OPENMRS_FHIR_SERVER_VERSION;

Expand Down Expand Up @@ -299,4 +301,25 @@ private FhirConstants() {
public static final String REVERSE_INCLUDE_SEARCH_HANDLER = "_revinclude.search.handler";

public static final String CONDITION_OBSERVATION_CONCEPT_UUID = "1284AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";

public static final String MEDIA = "media";

public static final String MEDIA_STATUS = "media.status";

public static final String MEDIA_TYPE = "media.type";

public static final String MEDIA_SUBJECT = "media.subject";

public static final String MEDIA_ENCOUNTER_REFERENCE = "media.encounter.reference";

public static final String MEDIA_CONTENT_TYPE = "media.content.type";

public static final String CONTENT_DATA = "content.data";

public static final String CONTENT_TITLE = "content.title";

public static final String CONTENT_DATE_OF_CREATION = "content.creation";

public static final String SAVED_SUCCESSFULLY = "Saved successfully";

}
@@ -0,0 +1,30 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api;

import java.util.HashSet;

import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import org.hl7.fhir.r4.model.Media;

public interface FhirMediaService extends FhirService<Media> {

IBundleProvider searchForMedia(TokenAndListParam status, TokenAndListParam type, ReferenceAndListParam subject,
ReferenceAndListParam encounterReference, DateRangeParam createdDateTime, TokenAndListParam contentType,
TokenAndListParam id, StringAndListParam contentDataType, StringAndListParam contentTitle,
DateRangeParam contentCreated, DateRangeParam lastUpdated, HashSet<Include> includes,
HashSet<Include> revIncludes, SortSpec sort);
}
@@ -0,0 +1,39 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api.dao;

import javax.annotation.Nonnull;

import java.util.List;

import org.openmrs.Obs;
import org.openmrs.annotation.Authorized;
import org.openmrs.module.fhir2.api.search.param.SearchParameterMap;
import org.openmrs.util.PrivilegeConstants;

public interface FhirMediaDao extends FhirDao<Obs> {

@Override
@Authorized(PrivilegeConstants.GET_OBS)
Obs get(@Nonnull String uuid);

@Override
@Authorized(PrivilegeConstants.ADD_OBS)
Obs createOrUpdate(@Nonnull Obs newEntry);

@Override
@Authorized(PrivilegeConstants.DELETE_OBS)
Obs delete(@Nonnull String uuid);

@Override
@Authorized(PrivilegeConstants.GET_OBS)
List<String> getSearchResultUuids(@Nonnull SearchParameterMap theParams);

}
Expand Up @@ -156,7 +156,7 @@
* AND crt.code in (?, ?, ?)
* ) OR (
* crt.concept_source_id = (select concept_source_id from fhir_concept_source where url = ?)
* AND crt.code = ?
* AND crt.code = ?fhir_concept_source
Comment on lines 158 to +159
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right to me. Why did you change the example query?

* )) AND (
* crt.concept_source_id = (select concept_source_id from fhir_concept_source where url = ?)
* AND crt.code in (?, ?, ?)
Expand Down
@@ -0,0 +1,131 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api.dao.impl;

import static org.hibernate.criterion.Restrictions.eq;

import javax.annotation.Nonnull;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import lombok.AccessLevel;
import lombok.Setter;
import org.hibernate.Criteria;
import org.openmrs.Obs;
import org.openmrs.api.ObsService;
import org.openmrs.api.context.Context;
import org.openmrs.module.fhir2.FhirConstants;
import org.openmrs.module.fhir2.api.dao.FhirMediaDao;
import org.openmrs.module.fhir2.api.search.param.SearchParameterMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Setter(AccessLevel.PACKAGE)
public class FhirMediaDaoImpl extends BaseFhirDao<Obs> implements FhirMediaDao {

// private ObsService obsService = Context.getObsService();

@Autowired
private ObsService obsService;

@Override
public Obs get(@Nonnull String uuid) {
return obsService.getObsByUuid(uuid);
}

@Override
public Obs createOrUpdate(@Nonnull Obs newEntry) {
return obsService.saveObs(newEntry, FhirConstants.SAVED_SUCCESSFULLY);
}

@Override
public Obs delete(@Nonnull String uuid) {
return super.delete(uuid);
}

@Override
public List<Obs> getSearchResults(@Nonnull SearchParameterMap theParams, @Nonnull List<String> resourceUuids) {
return resourceUuids.stream().map(obsService::getObsByUuid).collect(Collectors.toList());
}

@Override
protected void setupSearchParams(Criteria criteria, SearchParameterMap theParams) {
theParams.getParameters().forEach(entry -> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, we'll want to ensure that we're only searching ComplexObs and not just any Obs. This looks like it could be done as something like:

if (lacksAlias(criteria, "c")) {
	criteria.createAlias("concept", "c");
}

if (lacksAlias(criteria, "cdt")) {
    criteria.createAlias("c.datatype", "cdt");
}

criteria.add(eq("cdt.hl7_abbreviation", "ED"));

switch (entry.getKey()) {
case FhirConstants.MEDIA_STATUS:
entry.getValue().forEach(status -> handleStatus(criteria, (TokenAndListParam) status.getParam()));
break;
case FhirConstants.MEDIA_TYPE:
entry.getValue().forEach(type -> handleMediaType(criteria, (TokenAndListParam) type.getParam()));
break;
case FhirConstants.MEDIA_SUBJECT:
entry.getValue()
.forEach(subject -> handleMediaSubject(criteria, (ReferenceAndListParam) subject.getParam()));
break;
case FhirConstants.MEDIA_ENCOUNTER_REFERENCE:
break;
case FhirConstants.MEDIA_CREATED_DATE_TIME:
entry.getValue().forEach(
createdTime -> handleDate(createdTime.getPropertyName(), (DateParam) createdTime.getParam())
.ifPresent(criteria::add));
break;
case FhirConstants.MEDIA_CONTENT_TYPE:
break;
case FhirConstants.CONTENT_DATA:
break;
case FhirConstants.CONTENT_TITLE:
break;
case FhirConstants.CONTENT_DATE_OF_CREATION:
entry.getValue().forEach(contentDateOfCreation -> handleDate(contentDateOfCreation.getPropertyName(),
(DateParam) contentDateOfCreation.getParam()));
break;
}
});
}

// private void handleStatus(Criteria criteria, TokenAndListParam status) {
// if(status != null){
// if(lacksAlias(criteria, "st")){
// criteria.createAlias("status", "st");
// handleAndListParam(status, (tag) -> Optional.of(eq("st.status", tag.getValue()))).ifPresent(criteria::add);
// }
// }
// }

private void handleStatus(Criteria criteria, TokenAndListParam status) {
// handleAndListParam(status, (data) -> propertyLike("status", status)).ifPresent(criteria::add);
}

private void handleMediaType(Criteria criteria, TokenAndListParam mediaType) {
if (mediaType != null) {
if (lacksAlias(criteria, "mt")) {
criteria.createAlias("mediaType", "mt");
handleAndListParam(mediaType, (tag) -> Optional.of(eq("mt.type", tag.getValue()))).ifPresent(criteria::add);
}
}
}

private void handleMediaSubject(Criteria criteria, ReferenceAndListParam mediaSubject) {
if (mediaSubject != null) {
if (lacksAlias(criteria, "ms")) {
criteria.createAlias("mediaSubject", "ms");
handleAndListParam(mediaSubject, (tag) -> Optional.of(eq("ms.subject", tag.getValue())))
.ifPresent(criteria::add);

}
}
}
}
@@ -0,0 +1,84 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.fhir2.api.impl;

import javax.annotation.Nonnull;

import java.util.HashSet;

import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import org.hl7.fhir.r4.model.Media;
import org.openmrs.Obs;
import org.openmrs.module.fhir2.FhirConstants;
import org.openmrs.module.fhir2.api.FhirMediaService;
import org.openmrs.module.fhir2.api.dao.FhirMediaDao;
import org.openmrs.module.fhir2.api.search.SearchQuery;
import org.openmrs.module.fhir2.api.search.SearchQueryInclude;
import org.openmrs.module.fhir2.api.search.param.SearchParameterMap;
import org.openmrs.module.fhir2.api.translators.MediaTranslator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
@Transactional
@Getter(AccessLevel.PROTECTED)
@Setter(AccessLevel.MODULE)
public class FhirMediaServiceImpl extends BaseFhirService<Media, Obs> implements FhirMediaService {

@Autowired
private FhirMediaDao dao;

@Autowired
private MediaTranslator translator;

@Autowired
private SearchQuery<Obs, Media, FhirMediaDao, MediaTranslator, SearchQueryInclude<Media>> searchQuery;

@Autowired
private SearchQueryInclude<Media> searchQueryInclude;

@Override
public Media get(@Nonnull String uuid) {
return super.get(uuid);
}

@Override
public IBundleProvider searchForMedia(TokenAndListParam status, TokenAndListParam type, ReferenceAndListParam subject,
ReferenceAndListParam encounterReference, DateRangeParam createdDateTime, TokenAndListParam contentType,
TokenAndListParam id, StringAndListParam contentDataType, StringAndListParam contentTitle,
DateRangeParam contentCreated, DateRangeParam lastUpdated, HashSet<Include> includes,
HashSet<Include> revIncludes, SortSpec sort) {

SearchParameterMap theParams = new SearchParameterMap().addParameter(FhirConstants.MEDIA_STATUS, status)
.addParameter(FhirConstants.MEDIA_TYPE, type).addParameter(FhirConstants.MEDIA_SUBJECT, subject)
.addParameter(FhirConstants.MEDIA_ENCOUNTER_REFERENCE, encounterReference)
.addParameter(FhirConstants.MEDIA_CREATED_DATE_TIME, createdDateTime)
.addParameter(FhirConstants.MEDIA_CONTENT_TYPE, contentType)
.addParameter(FhirConstants.CONTENT_DATA, contentDataType)
.addParameter(FhirConstants.CONTENT_TITLE, contentTitle)
.addParameter(FhirConstants.CONTENT_DATE_OF_CREATION, contentCreated)
.addParameter(FhirConstants.COMMON_SEARCH_HANDLER, FhirConstants.ID_PROPERTY, id)
tendomart marked this conversation as resolved.
Show resolved Hide resolved
.addParameter(FhirConstants.COMMON_SEARCH_HANDLER, FhirConstants.LAST_UPDATED_PROPERTY, lastUpdated)
.addParameter(FhirConstants.COMMON_SEARCH_HANDLER, includes)
.addParameter(FhirConstants.COMMON_SEARCH_HANDLER, revIncludes).setSortSpec(sort);

return searchQuery.getQueryResults(theParams, dao, translator, searchQueryInclude);
}
}
Expand Up @@ -24,17 +24,7 @@
import lombok.NoArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.AllergyIntolerance;
import org.hl7.fhir.r4.model.Condition;
import org.hl7.fhir.r4.model.DiagnosticReport;
import org.hl7.fhir.r4.model.Encounter;
import org.hl7.fhir.r4.model.Location;
import org.hl7.fhir.r4.model.MedicationRequest;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Person;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.RelatedPerson;
import org.hl7.fhir.r4.model.ServiceRequest;
import org.hl7.fhir.r4.model.*;
tendomart marked this conversation as resolved.
Show resolved Hide resolved
import org.openmrs.module.fhir2.FhirConstants;
import org.openmrs.module.fhir2.api.FhirAllergyIntoleranceService;
import org.openmrs.module.fhir2.api.FhirDiagnosticReportService;
Expand Down