Skip to content

Commit

Permalink
add support for Support FHIR Pagination when Pulling results (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
mozzy11 authored Aug 24, 2023
1 parent 41fac66 commit 6201727
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import java.util.List;

import org.hibernate.criterion.Restrictions;
import org.openmrs.api.APIException;
import org.openmrs.api.db.hibernate.DbSession;
import org.openmrs.api.db.hibernate.DbSessionFactory;
import org.openmrs.module.labonfhir.api.model.FailedTask;
import org.openmrs.module.labonfhir.api.model.TaskRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

Expand Down Expand Up @@ -35,5 +37,17 @@ public List<FailedTask> getAllFailedTasks(Boolean isSent) {
return getSession().createCriteria(FailedTask.class).list();
}
}


public TaskRequest saveOrUpdateTaskRequest(TaskRequest taskRequest) throws APIException {
getSession().saveOrUpdate(taskRequest);
return taskRequest;
}

public TaskRequest getLastTaskRequest() throws APIException {
String hql = "FROM TaskRequest tr WHERE tr.requestDate = (SELECT MAX(t.requestDate) FROM TaskRequest t)";
return (TaskRequest)getSession().createQuery(hql).uniqueResult();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public Integer getId() {
}
@Override
public void setId(Integer id) {
this.id = id;
}

public String getError() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.openmrs.module.labonfhir.api.model;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.openmrs.BaseOpenmrsData;

@Entity
@Table(name = "task_request")
public class TaskRequest extends BaseOpenmrsData {

@Id
@GeneratedValue
@Column(name = "id")
private Integer id;

@Column(name = "request_date")
private Date requestDate;

@Override
public Integer getId() {
return id;
}

@Override
public void setId(Integer id) {
this.id = id;
}

public Date getRequestDate() {
return requestDate;
}

public void setRequestDate(Date requestDate) {
this.requestDate = requestDate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@
import static org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.gclient.TokenClientParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import lombok.AccessLevel;
import lombok.Setter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.SessionFactory;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.DiagnosticReport;
Expand All @@ -28,13 +32,16 @@
import org.openmrs.module.fhir2.api.dao.FhirObservationDao;
import org.openmrs.module.fhir2.api.translators.ObservationReferenceTranslator;
import org.openmrs.module.labonfhir.LabOnFhirConfig;
import org.openmrs.module.labonfhir.api.model.TaskRequest;
import org.openmrs.module.labonfhir.api.service.LabOnFhirService;
import org.openmrs.scheduler.tasks.AbstractTask;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;

@Component
@Setter(AccessLevel.PACKAGE)
Expand Down Expand Up @@ -72,29 +79,63 @@ public class FetchTaskUpdates extends AbstractTask implements ApplicationContext
@Qualifier("sessionFactory")
SessionFactory sessionFactory;

@Autowired
private LabOnFhirService labOnFhirService;

@Override
public void execute() {

try {
applicationContext.getAutowireCapableBeanFactory().autowireBean(this);
} catch (Exception e) {
}
catch (Exception e) {
// return;
}

if (!config.isLisEnabled()) {
return;
}

try {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date newDate = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(newDate);
calendar.add(Calendar.YEAR, -5);
Date fiveYearsAgo = calendar.getTime();

TaskRequest lastRequest = labOnFhirService.getLastTaskRequest();
String lastRequstDate = dateFormat.format(fiveYearsAgo);
if (lastRequest != null) {
lastRequstDate = dateFormat.format(lastRequest.getRequestDate());
}

String currentTime = dateFormat.format(newDate);
DateRangeParam lastUpdated = new DateRangeParam().setLowerBound(lastRequstDate).setUpperBound(currentTime);

// Get List of Tasks that belong to this instance and update them
updateTasksInBundle(client.search().forResource(Task.class)
.where(Task.IDENTIFIER.hasSystemWithAnyCode(FhirConstants.OPENMRS_FHIR_EXT_TASK_IDENTIFIER))
.where(Task.STATUS.exactly().code(TaskStatus.COMPLETED.toCode())).returnBundle(Bundle.class)
.execute());
} catch (Exception e) {
Bundle taskBundle = client.search().forResource(Task.class)
.where(Task.IDENTIFIER.hasSystemWithAnyCode(FhirConstants.OPENMRS_FHIR_EXT_TASK_IDENTIFIER))
.where(Task.STATUS.exactly().code(TaskStatus.COMPLETED.toCode())).lastUpdated(lastUpdated)
.returnBundle(Bundle.class).execute();

List<Bundle> taskBundles = new ArrayList<>();
taskBundles.add(taskBundle);
//Support FHIR Server Pagination
while (taskBundle.getLink(IBaseBundle.LINK_NEXT) != null) {
taskBundle = client.loadPage().next(taskBundle).execute();
taskBundles.add(taskBundle);
}
updateTasksInBundle(taskBundles);

TaskRequest request = new TaskRequest();
request.setRequestDate(newDate);
labOnFhirService.saveOrUpdateTaskRequest(request);
}
catch (Exception e) {
log.error("ERROR executing FetchTaskUpdates : " + e.toString() + getStackTrace(e));
}

super.startExecuting();
}

Expand All @@ -105,35 +146,36 @@ public void shutdown() {
this.stopExecuting();
}

private void updateTasksInBundle(Bundle taskBundle) {

for (Iterator tasks = taskBundle.getEntry().iterator(); tasks.hasNext();) {
String openmrsTaskUuid = null;

try {
// Read incoming LIS Task
Task openelisTask = (Task) ((Bundle.BundleEntryComponent) tasks.next()).getResource();
openmrsTaskUuid = openelisTask.getIdentifierFirstRep().getValue();

// Find original openmrs task using Identifier
Task openmrsTask = taskService.get(openmrsTaskUuid);

// Only update if matching OpenMRS Task found
if (openmrsTask != null) {
// Handle status
openmrsTask.setStatus(openelisTask.getStatus());

Boolean taskOutPutUpdated = false;
if (openelisTask.hasOutput()) {
// openmrsTask.setOutput(openelisTask.getOutput());
taskOutPutUpdated = updateOutput(openelisTask.getOutput(), openmrsTask);
}
if (taskOutPutUpdated) {
taskService.update(openmrsTaskUuid, openmrsTask);
private void updateTasksInBundle(List<Bundle> taskBundles) {
for (Bundle bundle : taskBundles) {
for (Iterator tasks = bundle.getEntry().iterator(); tasks.hasNext();) {
String openmrsTaskUuid = null;
try {
// Read incoming LIS Task
Task openelisTask = (Task) ((Bundle.BundleEntryComponent) tasks.next()).getResource();
openmrsTaskUuid = openelisTask.getIdentifierFirstRep().getValue();
// Find original openmrs task using Identifier
Task openmrsTask = taskService.get(openmrsTaskUuid);
// Only update if matching OpenMRS Task found
if (openmrsTask != null) {
// Handle status
openmrsTask.setStatus(openelisTask.getStatus());
Boolean taskOutPutUpdated = false;
if (openelisTask.hasOutput()) {
// openmrsTask.setOutput(openelisTask.getOutput());
taskOutPutUpdated = updateOutput(openelisTask.getOutput(), openmrsTask);
}
if (taskOutPutUpdated) {
taskService.update(openmrsTaskUuid, openmrsTask);
}
}
}
} catch (Exception e) {
log.error("Could not save task " + openmrsTaskUuid + ":" + e.toString() + getStackTrace(e));
catch (Exception e) {
log.error("Could not save task " + openmrsTaskUuid + ":" + e.toString() + getStackTrace(e));
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.openmrs.api.OpenmrsService;
import org.openmrs.module.labonfhir.api.model.FailedTask;
import org.openmrs.module.labonfhir.api.model.TaskRequest;

import java.util.List;
import org.openmrs.api.APIException;
Expand Down Expand Up @@ -40,5 +41,23 @@ public interface LabOnFhirService extends OpenmrsService{
@Transactional
List<FailedTask> getAllFailedTasks(Boolean isSent) throws APIException;


/**
* Saves an TaskRequest
*
* @param taskRequest
* @return TaskRequest
* @throws APIException
*/
@Transactional
TaskRequest saveOrUpdateTaskRequest(TaskRequest taskRequest) throws APIException;


/**
* Returns the Last Task Request
* @throws APIException
*/
@Transactional(readOnly = true)
TaskRequest getLastTaskRequest() throws APIException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.openmrs.api.APIException;
import org.openmrs.module.labonfhir.api.dao.LabOnFhirDao;
import org.openmrs.module.labonfhir.api.model.FailedTask;
import org.openmrs.module.labonfhir.api.model.TaskRequest;
import org.openmrs.module.labonfhir.api.service.LabOnFhirService;
import org.springframework.beans.factory.annotation.Autowired;

Expand Down Expand Up @@ -43,5 +44,15 @@ public void onStartup() {
public void onShutdown() {

}

@Override
public TaskRequest getLastTaskRequest() throws APIException {
return dao.getLastTaskRequest();
}

@Override
public TaskRequest saveOrUpdateTaskRequest(TaskRequest taskRequest) throws APIException {
return dao.saveOrUpdateTaskRequest(taskRequest);
}

}
25 changes: 25 additions & 0 deletions api/src/main/resources/liquibase.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,31 @@
<column name="uuid" value="ae35121c-41e6-46f1-b2a2-0d9d2fa63e74" />
</insert>
</changeSet>
<changeSet id="create-task-request-table-2023-08-24" author="mozzymutesa" dbms="mysql">
<preConditions onFail="MARK_RAN">
<not><tableExists tableName="task_request"/></not>
</preConditions>
<comment>
Creating the task_request table
</comment>
<createTable tableName="task_request">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="request_date" type="DATETIME"/>
<column name="uuid" type="char(38)">
<constraints nullable="false" unique="true"></constraints>
</column>
<column name="date_voided" type="DATETIME"/>
<column name="date_changed" type="DATETIME"/>
<column name="date_created" type="DATETIME"/>
<column name="void_reason" type="varchar(255)" />
<column name="changed_by" type="int" />
<column name="voided_by" type="int" />
<column name="creator" type="int" />
<column defaultValueBoolean="false" name="voided" type="BOOLEAN"/>
</createTable>
</changeSet>
</databaseChangeLog>


0 comments on commit 6201727

Please sign in to comment.