-
Notifications
You must be signed in to change notification settings - Fork 3
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
feat(#138): move polling to openhim channel config #139
base: openmrs-mediator
Are you sure you want to change the base?
Changes from 4 commits
97b1348
07094b5
61e26eb
928e931
1c7dc2b
5cc6525
c9c30c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,15 +3,15 @@ import { mediatorConfig } from './config/mediator'; | |
import { openMRSMediatorConfig } from './config/openmrs_mediator'; | ||
import { logger } from './logger'; | ||
import bodyParser from 'body-parser'; | ||
import {PORT, OPENHIM, SYNC_INTERVAL, OPENMRS} from './config'; | ||
import {PORT, OPENHIM, OPENMRS} from './config'; | ||
import patientRoutes from './src/routes/patient'; | ||
import serviceRequestRoutes from './src/routes/service-request'; | ||
import encounterRoutes from './src/routes/encounter'; | ||
import organizationRoutes from './src/routes/organization'; | ||
import endpointRoutes from './src/routes/endpoint'; | ||
import chtRoutes from './src/routes/cht'; | ||
import openMRSRoutes from './src/routes/openmrs'; | ||
import { registerMediatorCallback } from './src/utils/openhim'; | ||
import { syncPatients, syncEncounters } from './src/utils/openmrs_sync' | ||
import os from 'os'; | ||
|
||
const {registerMediator} = require('openhim-mediator-utils'); | ||
|
@@ -21,11 +21,12 @@ const app = express(); | |
app.use(bodyParser.json()); | ||
app.use(bodyParser.urlencoded({extended: true})); | ||
|
||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this code rather than commenting it out. |
||
app.get('*', (_: Request, res: Response) => { | ||
const osUptime = os.uptime(); | ||
const processUptime = process.uptime(); | ||
res.send({status: 'success', osuptime: osUptime, processuptime: processUptime}); | ||
}); | ||
});*/ | ||
|
||
// routes for valid fhir resources | ||
app.use('/patient', patientRoutes); | ||
|
@@ -34,30 +35,21 @@ app.use('/encounter', encounterRoutes); | |
app.use('/organization', organizationRoutes); | ||
app.use('/endpoint', endpointRoutes); | ||
|
||
// routes for cht docs | ||
// routes for CHT docs | ||
app.use('/cht', chtRoutes); | ||
|
||
// routes for OpenMRS | ||
app.use('/openmrs', openMRSRoutes); | ||
|
||
if (process.env.NODE_ENV !== 'test') { | ||
app.listen(PORT, () => logger.info(`Server listening on port ${PORT}`)); | ||
|
||
// TODO => inject the 'port' and 'http scheme' into 'mediatorConfig' | ||
registerMediator(OPENHIM, mediatorConfig, registerMediatorCallback); | ||
|
||
// if OPENMRS is specified, register its mediator | ||
// and start the sync background task | ||
if (OPENMRS.url) { | ||
registerMediator(OPENHIM, openMRSMediatorConfig, registerMediatorCallback); | ||
// start patient and ecnounter sync in the background | ||
setInterval(async () => { | ||
try { | ||
const startTime = new Date(); | ||
startTime.setHours(startTime.getHours() - 1); | ||
await syncPatients(startTime); | ||
await syncEncounters(startTime); | ||
} catch (error: any) { | ||
logger.error(error); | ||
} | ||
}, Number(SYNC_INTERVAL)); | ||
} | ||
} | ||
|
||
|
witash marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { logger } from '../../logger'; | ||
import { syncPatients, syncEncounters } from '../utils/openmrs_sync' | ||
import { SYNC_PERIOD } from '../../config' | ||
|
||
export async function sync() { | ||
try { | ||
let now = Date.now(); | ||
let syncPeriod = parseInt(SYNC_PERIOD, 10); | ||
let startTime = new Date(now - syncPeriod); | ||
|
||
await syncPatients(startTime); | ||
await syncEncounters(startTime); | ||
witash marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return { status: 200, data: { message: `OpenMRS sync completed successfully`} }; | ||
} catch(error: any) { | ||
logger.error(error); | ||
return { status: 500, data: { message: `Error during OpenMRS Sync`} }; | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think about adding GET /sync route unit tests? While the code is simple, ensuring the route behaves as expected in both success and failure scenarios is a good idea. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added src/routes/test/openmrs.sync.test with simple success and failure tests, if/when the sync returns more data, we can add more test conditions. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { Router } from 'express'; | ||
import { requestHandler } from '../utils/request'; | ||
import { sync } from '../controllers/openmrs' | ||
|
||
const router = Router(); | ||
|
||
router.get( | ||
'/sync', | ||
requestHandler((req) => sync()) | ||
); | ||
|
||
export default router; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import request from 'supertest'; | ||
import app from '../../..'; | ||
import * as openmrs_sync from '../../utils/openmrs_sync'; | ||
import axios from 'axios'; | ||
|
||
jest.mock('axios'); | ||
|
||
describe('GET /openmrs/sync', () => { | ||
it('calls syncPatients and syncEncouners', async () => { | ||
jest.spyOn(openmrs_sync, 'syncPatients').mockImplementation(async (startTime) => { | ||
}); | ||
|
||
jest.spyOn(openmrs_sync, 'syncEncounters').mockImplementation(async (startTime) => { | ||
}); | ||
|
||
const res = await request(app).get('/openmrs/sync').send(); | ||
|
||
expect(res.status).toBe(200); | ||
|
||
expect(openmrs_sync.syncPatients).toHaveBeenCalled(); | ||
expect(openmrs_sync.syncEncounters).toHaveBeenCalled(); | ||
}); | ||
|
||
it('returns 500 if syncPatients throws an error', async () => { | ||
jest.spyOn(openmrs_sync, 'syncPatients').mockImplementation(async (startTime) => { | ||
throw new Error('Sync Failed'); | ||
}); | ||
|
||
const res = await request(app).get('/openmrs/sync').send(); | ||
|
||
expect(res.status).toBe(500); | ||
|
||
expect(openmrs_sync.syncPatients).toHaveBeenCalled(); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding the default sync period to the comment in a human-readable manner would be helpful. e.g.
How far back should the sync look for new resources. Defaults to 1 hour.