-
Notifications
You must be signed in to change notification settings - Fork 7
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
RN-403 Clean up data services configuration #3783
Conversation
fb18438
to
ba2f6a2
Compare
@@ -94,8 +94,8 @@ const SURVEY_COLUMNS = [ | |||
editConfig: { | |||
options: SERVICE_TYPES, | |||
setFieldsOnChange: (newValue, currentRecord) => { | |||
const { isDataRegional = true } = currentRecord['data_source.config']; | |||
const config = newValue === 'dhis' ? { isDataRegional } : {}; | |||
const { dhisInstanceCode = 'regional' } = currentRecord['data_source.config']; |
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.
Throughout the codebase we hardcode which Dhis Instance should be the default. I have not cleaned this up, the PR was already getting too big, will leave for a separate PR in the future.
@@ -0,0 +1,8 @@ | |||
/** |
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.
The existence of this file in __mocks__
tells jest to auto mock the utils package. The alternative of doing it in the test file itself doesn't work due to a limitation of jest.
|
||
return dhisApi; | ||
export const stubGetDhisApi = mockDhisApi => { |
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.
Split this into two functions because we don't always need to stub as well as mock this import.
]; | ||
|
||
/** | ||
* DataSources and Entities are linked to a specific DHIS server in many ways: |
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.
This is the main explainer for how things work... FYI
packages/database/src/migrations/20220513014400-AddDhisInstances-modifies-data.js
Outdated
Show resolved
Hide resolved
packages/central-server/src/database/utilities/assertCanAddDataElementInGroup.js
Show resolved
Hide resolved
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.
It's looking really good man! Thanks so much for doing this!
Just a few comments, I might give this one a second pass. But first I was hoping we could have a bit of a high level chat? You've added dhis_instance
s here as a concept, but I had maybe thought we'd be adding data_services
as a concept, where a data service could be:
- A specific dhis2 instance
- A data-lake instance
- The internal data-api instance
- etc.
Basically where we currently have data sources attached to a 'service type', they'd instead be linked to a specific service instance, which we could have many of.
Now all that wouldn't necessarily be in scope here, and we'd still need to use a lot of this cleanup code you've written anyway. Either way lets chat about it on Thursday and share thoughts?
* class model. We link data_source to dhis_instance via config option `data_source.config.dhisInstanceCode: <string>`. | ||
* | ||
* For entity based resolution, where previously we had isDataRegional = false, we now leave dhisInstanceCode | ||
* not set, which indicates no specific dhisInstance, and that we need to resolve it from the entity. |
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.
Would be keen to chat on how we think we might wanna resolve this one in the long run? It's a bit of an awkward practice, and one that I think we've really moved away from. But there's still a lot of data elements that are present in multiple DHIS2 instances...
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.
Discussed, have created https://linear.app/bes/issue/RN-537/one-data-element-per-dhis-server
Replaced with https://linear.app/bes/issue/RN-558/specify-dhis-server-explicitly
const allDhisInstanceCodes = new Set(); | ||
const allDhisInstances = []; | ||
for (const entityCode of entityCodes) { | ||
const dhisInstance = await this.resolveSingleEntityCode(entityCode); | ||
allDhisInstanceCodes.add(dhisInstance.code); | ||
allDhisInstances.push(dhisInstance); | ||
} | ||
if (allDhisInstanceCodes.size > 1) { | ||
throw new Error( | ||
`All entities must use the same DHIS2 instance (got [${[...allDhisInstanceCodes].join( | ||
',', | ||
)}])`, | ||
); | ||
} | ||
return allDhisInstances[0]; |
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.
const allDhisInstanceCodes = new Set(); | |
const allDhisInstances = []; | |
for (const entityCode of entityCodes) { | |
const dhisInstance = await this.resolveSingleEntityCode(entityCode); | |
allDhisInstanceCodes.add(dhisInstance.code); | |
allDhisInstances.push(dhisInstance); | |
} | |
if (allDhisInstanceCodes.size > 1) { | |
throw new Error( | |
`All entities must use the same DHIS2 instance (got [${[...allDhisInstanceCodes].join( | |
',', | |
)}])`, | |
); | |
} | |
return allDhisInstances[0]; | |
const serverName = await legacy_getDhisServerName({ | |
isDataRegional: false, | |
entityCodes, | |
}); | |
return this.getFromServerName(serverName); |
Would this work? Just cos legacy_getDhisServerName()
takes entityCodes
and already does the validation to ensure they all use the same serverName..?
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.
I left this as multiple single calls to legacy_getDhisServerName to make mocking easier. This way we can have a test in data-broker to make sure an error gets thrown if it resolves to multiple dhis servers. I thought about having this test in utils, on the legacy_getDhisServerName function, but I thought it might make more sense to have it on the non-legacy side of the codebase rather than the legacy side. I think the reason was that the legacy side is really hard to write tests for because mocking is hard. As this class should disappear once the data is cleaned up, are you happy to leave as is?
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.
Yup that sounds reasonable to me 👍
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.
Nice work @IgorNadj this is a great step forward! Hopefully we can pick up and carry on with phase 2 before too long.
A small comment from the first pass, but overall really happy and approving. Really appreciate the tests and comments btw (this is all becoming rather arcane knowledge)
Thoughts around testing on this? What's the regression risk looking like? Obviously there's a bunch of vizes... Does this break older survey import files too?
fieldName: 'dhisInstanceCode', | ||
optionsEndpoint: 'dhisInstances', | ||
optionLabelKey: 'dhisInstances.code', | ||
optionValueKey: 'dhisInstances.code', |
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.
Reckon it's a tad awkward to leave this field empty if using country specific server? The code kinda forces us in this direction tho huh? Might be nice if we could have a 'Country specific server' option in the UI which sets it as undefined in the backend...
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.
Yeah I don't love it either. Were you thinking something like this? https://linear.app/bes/issue/RN-403#comment-deae01b8
I have set this field label to "DHIS Server", and this should encourage people to fill it out.
As we don't need the entity based resolution functionality (In this investigation I confirmed we don't have any data elements that are stored on multiple DHIS Servers, so there is a 1:1 map), after changing all of these from null to a specific DHIS Server, I will create a new PR to set this column to NOT NULL.
Here is the new card for this cleanup: https://linear.app/bes/issue/RN-558/specify-dhis-server-explicitly
const areDifferentAllowingNull = (a, b) => { | ||
if (a === null && b === null) return false; | ||
if (a === null && b !== null) return true; | ||
if (a !== null && b === null) return true; | ||
return a !== b; | ||
}; |
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.
Out of curiousity, how is this different to a !== b
? null !== null => false
right?
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.
Ah good catch, updated.
packages/database/src/migrations/20220512232924-CreateDhisInstanceTable-modifies-schema.js
Show resolved
Hide resolved
Discussed, data_service was the plan originally, but it wound up being harder than expected because doing so would mean removing data_source.service_type which would mean lots of changes throughout the codebase to find the service type for a data source, converting sync code to async for the lookup etc. We still want to do this, I just reduced the scope of this PR to get a chewable bite out of the problem. |
Have created a cleanup card, after which I will create a new PR to not allow null. |
ef6e5f0
to
c5ee57b
Compare
Have rebased on dev, fixed up PR from feedback. |
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.
Great stuff @IgorNadj really appreciate all this work!
merge in latest dev for testing
merge in latest dev for testing
merge latest dev in for testing
db491d7
to
f6413a5
Compare
RN-403
Background:
#3783 (comment)
This is phase 1 of refactoring isDataRegional style config values.
Phase 1: data_element & data_group
Phase 2+: entity based resolution, detectDataServices, dhis_sync_queue, legacy report configs, legacy map overlay configs
Changes:
Phase 1 changes:
isDataRegional: bool
->dhisInstanceCode: string|null
DhisInstance
as a first class model