Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
*.iml
target/
.mvn/wrapper/maven-wrapper.jar
.idea/*
*.DS_Store
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ server.port=9081
liquibase.change-log=classpath:db/changelog/liquibase.xml

enable.scheduling=true

create.imagingstudy.enabled=${CREATE_IMAGING_STUDY_ENABLED:false}
1 change: 1 addition & 0 deletions package/helm/templates/configMap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ data:
DB_NAME: "{{ .Values.config.PACS_INTEGRATION_DB_NAME }}"
OPENMRS_HOST: "{{ .Values.config.OPENMRS_HOST }}"
OPENMRS_PORT: "{{ .Values.config.OPENMRS_PORT }}"
CREATE_IMAGING_STUDY_ENABLED: "{{ .Values.config.CREATE_IMAGING_STUDY_ENABLED }}"


1 change: 1 addition & 0 deletions package/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ config:
PACS_INTEGRATION_DB_NAME: ""
OPENMRS_HOST: ""
OPENMRS_PORT: ""
CREATE_IMAGING_STUDY_ENABLED: false

secrets:
PACS_INTEGRATION_DB_USERNAME: ""
Expand Down
2 changes: 1 addition & 1 deletion pacs-integration-webapp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<maven.compiler.target>1.8</maven.compiler.target>
<atomfeed.version>1.10.1</atomfeed.version>
<hapi-base.version>2.2</hapi-base.version>
<web-clients.version>1.0.0</web-clients.version>
<web-clients.version>1.1.0-SNAPSHOT</web-clients.version>
<log4j.version>2.17.1</log4j.version>
</properties>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.bahmni.module.pacsintegration.atomfeed.contract.fhir;

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class FhirIdentifier {

private String system;
private String value;

public FhirIdentifier() {
}

public FhirIdentifier(String system, String value) {
this.system = system;
this.value = value;
}

public String getSystem() {
return system;
}

public void setSystem(String system) {
this.system = system;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.bahmni.module.pacsintegration.atomfeed.contract.fhir;

import com.fasterxml.jackson.annotation.JsonInclude;

import java.util.List;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class FhirImagingStudy {

private String resourceType = "ImagingStudy";
private List<FhirIdentifier> identifier;
private String status;
private FhirReference subject;
private List<FhirReference> basedOn;
private FhirReference location;
private String description;

public FhirImagingStudy() {
}

public String getResourceType() {
return resourceType;
}

public void setResourceType(String resourceType) {
this.resourceType = resourceType;
}

public List<FhirIdentifier> getIdentifier() {
return identifier;
}

public void setIdentifier(List<FhirIdentifier> identifier) {
this.identifier = identifier;
}

public String getStatus() {
return status;
}

public void setStatus(String status) {
this.status = status;
}

public FhirReference getSubject() {
return subject;
}

public void setSubject(FhirReference subject) {
this.subject = subject;
}

public List<FhirReference> getBasedOn() {
return basedOn;
}

public void setBasedOn(List<FhirReference> basedOn) {
this.basedOn = basedOn;
}

public FhirReference getLocation() {
return location;
}

public void setLocation(FhirReference location) {
this.location = location;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.bahmni.module.pacsintegration.atomfeed.contract.fhir;

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class FhirReference {

private String reference;

public FhirReference() {
}

public FhirReference(String reference) {
this.reference = reference;
}

public String getReference() {
return reference;
}

public void setReference(String reference) {
this.reference = reference;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.bahmni.module.pacsintegration.atomfeed.mappers;

import org.apache.commons.lang.StringUtils;
import org.bahmni.module.pacsintegration.atomfeed.contract.fhir.FhirIdentifier;
import org.bahmni.module.pacsintegration.atomfeed.contract.fhir.FhirImagingStudy;
import org.bahmni.module.pacsintegration.atomfeed.contract.fhir.FhirReference;
import org.springframework.stereotype.Component;

import java.util.Collections;

@Component
public class ImagingStudyMapper {
private static final String RESOURCE_TYPE = "ImagingStudy";
private static final String IDENTIFIER_SYSTEM = "urn:dicom:uid";
private static final String STATUS = "unknown";
private static final String PATIENT_REFERENCE_PREFIX = "Patient/";
private static final String SERVICE_REQUEST_REFERENCE_PREFIX = "ServiceRequest/";
private static final String LOCATION_REFERENCE_PREFIX = "Location/";

public FhirImagingStudy buildFhirPayload(
String orderUuid,
String patientUuid,
String locationUuid,
String studyInstanceUID,
String description) {

FhirImagingStudy imagingStudy = new FhirImagingStudy();

imagingStudy.setResourceType(RESOURCE_TYPE);

FhirIdentifier identifier = new FhirIdentifier(IDENTIFIER_SYSTEM, studyInstanceUID);
imagingStudy.setIdentifier(Collections.singletonList(identifier));

imagingStudy.setStatus(STATUS);

FhirReference subject = new FhirReference(PATIENT_REFERENCE_PREFIX + patientUuid);
imagingStudy.setSubject(subject);

FhirReference basedOnReference = new FhirReference(SERVICE_REQUEST_REFERENCE_PREFIX + orderUuid);
imagingStudy.setBasedOn(Collections.singletonList(basedOnReference));

if (StringUtils.isNotBlank(locationUuid)) {
FhirReference location = new FhirReference(LOCATION_REFERENCE_PREFIX + locationUuid);
imagingStudy.setLocation(location);
}

if (StringUtils.isNotBlank(description)) {
imagingStudy.setDescription(description);
}

return imagingStudy;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.bahmni.module.pacsintegration.services;

import org.springframework.stereotype.Service;

@Service
public interface ImagingStudyService {

void createImagingStudy(
String orderUuid,
String patientUuid,
String locationUuid,
String studyInstanceUID,
String description);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.bahmni.module.pacsintegration.atomfeed.contract.order.OpenMRSOrderDetails;
import org.bahmni.module.pacsintegration.atomfeed.contract.order.OpenMRSOrderQueryBuilder;
import org.bahmni.module.pacsintegration.atomfeed.contract.order.OrderLocation;
import org.bahmni.module.pacsintegration.atomfeed.contract.fhir.FhirImagingStudy;
import org.bahmni.module.pacsintegration.atomfeed.contract.patient.OpenMRSPatient;
import org.bahmni.module.pacsintegration.atomfeed.mappers.OpenMRSEncounterMapper;
import org.bahmni.module.pacsintegration.atomfeed.mappers.OpenMRSPatientMapper;
Expand All @@ -29,6 +30,8 @@ public class OpenMRSService {
String visitLocationRestUrl = "/openmrs/ws/rest/v1/bahmnicore/visitLocation/";
String locationRestUrl = "/openmrs/ws/rest/v1/location/";

String createImagingStudyRestUrl = "/openmrs/ws/fhir2/R4/ImagingStudy";

public OpenMRSEncounter getEncounter(String encounterUrl) throws IOException {
HttpClient webClient = WebClientFactory.getClient();
String urlPrefix = getURLPrefix();
Expand Down Expand Up @@ -90,6 +93,13 @@ public OrderLocation getLocation(String locationUuid) throws IOException {
return webClient.get(url, OrderLocation.class);
}

public void createFhirImagingStudy(FhirImagingStudy payload) throws IOException {
HttpClient webClient = WebClientFactory.getClient();
String urlPrefix = getURLPrefix();
String url = urlPrefix + createImagingStudyRestUrl;
webClient.post(url, payload, Object.class);
}

private String getURLPrefix() {
org.bahmni.webclients.ConnectionDetails connectionDetails = ConnectionDetails.get();
String authenticationURI = connectionDetails.getAuthUrl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import ca.uhn.hl7v2.model.AbstractMessage;
import org.bahmni.module.pacsintegration.atomfeed.contract.encounter.OpenMRSEncounter;
import org.bahmni.module.pacsintegration.atomfeed.contract.encounter.OpenMRSOrder;
import org.bahmni.module.pacsintegration.atomfeed.contract.order.OpenMRSOrderDetails;
import org.bahmni.module.pacsintegration.atomfeed.contract.order.OrderLocationInfo;
import org.bahmni.module.pacsintegration.atomfeed.contract.patient.OpenMRSPatient;
import org.bahmni.module.pacsintegration.atomfeed.mappers.OpenMRSEncounterToOrderMapper;
import org.bahmni.module.pacsintegration.model.Order;
Expand All @@ -13,7 +15,10 @@
import org.bahmni.module.pacsintegration.repository.OrderDetailsRepository;
import org.bahmni.module.pacsintegration.repository.OrderRepository;
import org.bahmni.module.pacsintegration.repository.OrderTypeRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
Expand All @@ -23,6 +28,10 @@

@Component
public class PacsIntegrationService {
private static final Logger logger = LoggerFactory.getLogger(PacsIntegrationService.class);

@Value("${create.imagingstudy.enabled}")
private boolean imagingStudyEnabled;

@Autowired
private OpenMRSEncounterToOrderMapper openMRSEncounterToOrderMapper;
Expand All @@ -33,6 +42,9 @@ public class PacsIntegrationService {
@Autowired
private HL7Service hl7Service;

@Autowired
private StudyInstanceUIDGenerator studyInstanceUIDGenerator;

@Autowired
private OrderTypeRepository orderTypeRepository;

Expand All @@ -45,6 +57,12 @@ public class PacsIntegrationService {
@Autowired
private ModalityService modalityService;

@Autowired
private ImagingStudyService imagingStudyService;

@Autowired
private LocationResolver locationResolver;

public void processEncounter(OpenMRSEncounter openMRSEncounter) throws IOException, ParseException, HL7Exception, LLPException {
OpenMRSPatient patient = openMRSService.getPatient(openMRSEncounter.getPatientUuid());
List<OrderType> acceptableOrderTypes = orderTypeRepository.findAll();
Expand All @@ -59,6 +77,24 @@ public void processEncounter(OpenMRSEncounter openMRSEncounter) throws IOExcepti

orderRepository.save(order);
orderDetailsRepository.save(new OrderDetails(order, request.encode(),response));

logger.info("Imagining study creation enabled: {}", imagingStudyEnabled);

if (imagingStudyEnabled) {
OpenMRSOrderDetails orderDetails = openMRSService.getOrderDetails(openMRSOrder.getUuid());
OrderLocationInfo orderLocationInfo = locationResolver.resolveLocations(orderDetails);
String studyInstanceUID = studyInstanceUIDGenerator.generateStudyInstanceUID(openMRSOrder.getOrderNumber());

logger.info("Creating ImagingStudy for Order: {} with StudyInstanceUID: {}", openMRSOrder.getUuid(), studyInstanceUID);
imagingStudyService.createImagingStudy(
openMRSOrder.getUuid(),
openMRSEncounter.getPatientUuid(),
orderLocationInfo.getSourceLocation().getUuid(),
studyInstanceUID,
"Imaging Study for " + openMRSOrder.getTestName()
);
}

}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.bahmni.module.pacsintegration.services.impl;

import org.apache.commons.lang.StringUtils;
import org.bahmni.module.pacsintegration.atomfeed.contract.fhir.FhirImagingStudy;
import org.bahmni.module.pacsintegration.atomfeed.mappers.ImagingStudyMapper;
import org.bahmni.module.pacsintegration.services.ImagingStudyService;
import org.bahmni.module.pacsintegration.services.OpenMRSService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ImagingStudyServiceImpl implements ImagingStudyService {

private static final Logger logger = LoggerFactory.getLogger(ImagingStudyServiceImpl.class);

@Autowired
private OpenMRSService openMRSService;

@Autowired
private ImagingStudyMapper imagingStudyMapper;

@Override
public void createImagingStudy(
String orderUuid,
String patientUuid,
String locationUuid,
String studyInstanceUID,
String description) {

if (StringUtils.isBlank(studyInstanceUID)) {
logger.warn("Cannot create ImagingStudy for order {} - StudyInstanceUID is null or empty", orderUuid);
return;
}

try {
FhirImagingStudy payload = imagingStudyMapper.buildFhirPayload(orderUuid, patientUuid, locationUuid, studyInstanceUID, description);
openMRSService.createFhirImagingStudy(payload);
logger.info("Successfully created ImagingStudy for order: {} with StudyInstanceUID: {}", orderUuid, studyInstanceUID);
} catch (Exception e) {
logger.error("Failed to create ImagingStudy for order: {}", orderUuid, e);
}
}
}
Loading