adding a generalpurpose GetResourceBundle method.

adding tests for cerner.
This commit is contained in:
Jason Kulatunga 2022-09-22 22:32:20 -07:00
parent 734dac28f6
commit 270abdc7af
4 changed files with 104 additions and 26 deletions

View File

@ -6,7 +6,6 @@ import (
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/database"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/hub/internal/fhir/base"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/models"
"github.com/fastenhealth/gofhir-models/fhir401"
"github.com/sirupsen/logrus"
"net/http"
)
@ -23,17 +22,10 @@ func NewClient(ctx context.Context, appConfig config.Interface, globalLogger log
}
//Overrides
func (c AetnaClient) GetPatientBundle(patientId string) (fhir401.Bundle, error) {
bundle := fhir401.Bundle{}
err := c.GetRequest("Patient", &bundle)
return bundle, err
}
func (c AetnaClient) SyncAll(db database.DatabaseRepository) error {
bundle, err := c.GetPatientBundle(c.Source.PatientId)
bundle, err := c.GetResourceBundle("Patient")
if err != nil {
c.Logger.Infof("An error occurred while getting patient bundle %s", c.Source.PatientId)
return err

View File

@ -27,25 +27,28 @@ func NewFHIR401Client(ctx context.Context, appConfig config.Interface, globalLog
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FHIR
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func (c *FHIR401Client) GetPatientBundle(patientId string) (fhir401.Bundle, error) {
func (c *FHIR401Client) GetResourceBundle(relativeResourcePath string) (fhir401.Bundle, error) {
// https://www.hl7.org/fhir/patient-operation-everything.html
bundle := fhir401.Bundle{}
err := c.GetRequest(fmt.Sprintf("Patient/%s/$everything", patientId), &bundle)
err := c.GetRequest(relativeResourcePath, &bundle)
if err != nil {
return bundle, err
}
var next string
var prev string
var self string
for _, link := range bundle.Link {
if link.Relation == "next" {
next = link.Url
} else if link.Relation == "self" {
self = link.Url
} else if link.Relation == "previous" {
prev = link.Url
}
}
for len(next) > 0 && next != self {
for len(next) > 0 && next != self && next != prev {
c.Logger.Debugf("Paginated request => %s", next)
nextBundle := fhir401.Bundle{}
err := c.GetRequest(next, &nextBundle)
@ -54,13 +57,16 @@ func (c *FHIR401Client) GetPatientBundle(patientId string) (fhir401.Bundle, erro
}
bundle.Entry = append(bundle.Entry, nextBundle.Entry...)
next = "" //reset the next pointer
next = "" //reset the pointers
self = ""
prev = ""
for _, link := range nextBundle.Link {
if link.Relation == "next" {
next = link.Url
} else if link.Relation == "self" {
self = link.Url
} else if link.Relation == "previous" {
prev = link.Url
}
}
}
@ -69,6 +75,10 @@ func (c *FHIR401Client) GetPatientBundle(patientId string) (fhir401.Bundle, erro
}
func (c *FHIR401Client) GetPatientBundle(patientId string) (fhir401.Bundle, error) {
return c.GetResourceBundle(fmt.Sprintf("Patient/%s/$everything", patientId))
}
func (c *FHIR401Client) GetPatient(patientId string) (fhir401.Patient, error) {
patient := fhir401.Patient{}

View File

@ -2,6 +2,7 @@ package cerner
import (
"context"
"fmt"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/config"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/database"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/hub/internal/fhir/base"
@ -23,14 +24,39 @@ func NewClient(ctx context.Context, appConfig config.Interface, globalLogger log
func (c CernerClient) SyncAll(db database.DatabaseRepository) error {
bundle, err := c.GetPatientBundle(c.Source.PatientId)
if err != nil {
return err
supportedResources := []string{
"AllergyIntolerance",
"CarePlan",
"CareTeam",
"Condition",
"Consent",
"Device",
"Encounter",
"FamilyMemberHistory",
"Goal",
"Immunization",
"InsurancePlan",
"MedicationRequest",
"NutritionOrder",
"Observation",
"Person",
"Procedure",
"Provenance",
"Questionnaire",
"QuestionnaireResponse",
"RelatedPerson",
"Schedule",
"ServiceRequest",
"Slot",
}
for _, resourceType := range supportedResources {
bundle, err := c.GetResourceBundle(fmt.Sprintf("%s?patient=%s", resourceType, c.Source.PatientId))
if err != nil {
continue //TODO: skippping failures in the resource retrival
}
wrappedResourceModels, err := c.ProcessBundle(bundle)
if err != nil {
c.Logger.Infof("An error occurred while processing patient bundle %s", c.Source.PatientId)
c.Logger.Infof("An error occurred while processing %s bundle %s", resourceType, c.Source.PatientId)
return err
}
//todo, create the resources in dependency order
@ -41,5 +67,7 @@ func (c CernerClient) SyncAll(db database.DatabaseRepository) error {
return err
}
}
}
return nil
}

View File

@ -0,0 +1,48 @@
package cerner
import (
"context"
mock_config "github.com/fastenhealth/fastenhealth-onprem/backend/pkg/config/mock"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/database"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/hub/internal/fhir/base"
"github.com/fastenhealth/fastenhealth-onprem/backend/pkg/models"
"github.com/golang/mock/gomock"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"io/ioutil"
"os"
"testing"
)
func TestCernerClient_SyncAll(t *testing.T) {
t.Parallel()
//setup
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
fakeConfig := mock_config.NewMockInterface(mockCtrl)
testDatabase, err := ioutil.TempFile("testdata", "fasten.db")
require.NoError(t, err)
defer os.Remove(testDatabase.Name())
fakeConfig.EXPECT().GetString("web.database.location").AnyTimes().Return(testDatabase.Name())
testLogger := logrus.WithFields(logrus.Fields{
"type": "test",
})
httpClient := base.OAuthVcrSetup(t, false)
client, _, err := NewClient(context.Background(), fakeConfig, testLogger, models.Source{
SourceType: "cerner",
PatientId: "12724066",
ApiEndpointBaseUrl: "https://fhir-myrecord.cerner.com/r4/ec2458f2-1e24-41c8-b71b-0e701af7583d",
ClientId: "89efc22c-e879-4c02-a423-c3b98a0117a3",
}, httpClient)
db, err := database.NewRepository(fakeConfig, testLogger)
require.NoError(t, err)
//test
err = client.SyncAll(db)
require.NoError(t, err)
//assert
require.NoError(t, err)
}