-
-
Notifications
You must be signed in to change notification settings - Fork 10
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
Allow legacy deduplication #741
base: master
Are you sure you want to change the base?
Changes from all commits
235c05c
fc353cb
0e6783e
2d2ecb5
bef257e
8dcb33a
1b52af2
649bcf5
c70e95d
7011293
9a0548c
c27671a
c46998b
4f6c7cf
9115b92
9c87b14
329af8c
4915b2e
b41fbdf
f7334c5
4a0fe93
56816a7
8912a52
204ff7e
ace6538
203427e
87a97df
da9bbe9
5941ddc
fb540b9
222cc52
7094887
d0c9e35
7e54587
85b1514
94eafcb
5456c14
b075de8
3f97d79
d44dd31
f02369d
9d7a0e5
8661d31
fa9d7b9
86087d5
ca18a36
db165bd
03aaf80
314f53b
57b99b0
bba5b9f
6474069
fb10961
1ede9ee
b858997
e4ff330
88eeba9
53f0321
b35d332
f8a5fb3
189441f
5cb3cba
4249efb
cc5c310
81dd29d
015a574
03b7482
3fbb935
c5b5ddc
06b4f6d
e4b3806
8e8c99a
130f4b2
a993085
ad5bb24
bc7fff8
c23f149
9b6e227
beecdc5
5b0b505
821637c
69af971
f067e66
2fe84d9
eb44639
659bc2d
1fffd0a
8855e7e
0d0ea1d
b8f45f5
57ba478
4db4699
40a2ce2
5ab390b
eab3f8d
c107334
1729d97
eef58bd
e85a447
0cc6b64
af0214d
54d6e16
52226ec
329a62c
8b4bcd8
0bafed4
5e72371
5a4a210
d43e44c
582b55f
8ebb807
5dcb098
b34056d
cbf581a
f6770c0
cbc0f1e
45b4a57
b34ec12
e1c1e65
1f5a00f
be287f9
31d4d6b
ee8050b
b7d579e
176ba64
0ba107e
a50175b
fb425d0
1597c04
b5ff5d0
59e50d3
3c8d3e6
4db0383
1f63fc7
8d15dc8
0f7dda1
acd4869
ba2b664
5b4d580
23f946b
2bbde7c
2ccdb24
b6c4ea1
2929216
aaf274b
5151712
03778dd
7a625c4
412154a
3b93bb6
ae89fca
7a16063
1991df4
0886a7c
5d75629
72521ae
54583a0
6a74788
14d9ee8
46a84dc
ae8d571
75c5cab
dd87ea2
1ed373e
d4e573c
c3725de
0ab37ed
361b697
6cb3072
36ca339
e354180
6b74c8e
033e3a0
092dead
9206307
2828e2f
8a63758
4218656
5b63d5e
c6ac9ad
16fdcb8
387299a
452362e
f2307df
f5a2190
cfbaffd
7aaced7
db52ff6
eb023c1
aadfec3
b32d1b9
ef7c733
db10afe
8fcba34
6d0cd04
755103a
8205240
f7960eb
f1e15a6
4ac6f5c
f67d41c
8872788
275cf7a
5f6398c
ed43af9
0a5c1cc
fe8a85a
5ddf7ec
8a20208
e6dce6c
4541d0d
5279675
d51f3ca
74290b3
c9ed224
7588edf
1412b4c
079b214
6a71e3d
3a32367
4ede27e
4876b11
390fce1
8d2c0ff
135f3e9
f75d16c
5eb1d3b
e6c765d
7f84ab8
5c6b8fd
04aac95
5007049
cabab88
5ddf372
5dbfcab
d52e9d6
e4d88ab
5d39959
8328218
f87f048
086b4fd
7492d22
1c6731f
f0cc214
0209295
6d84df2
adbd24f
77ffcca
1a090b0
f715153
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 |
---|---|---|
@@ -1,10 +1,31 @@ | ||
package test | ||
|
||
import ( | ||
"github.com/onsi/gomega" | ||
|
||
dataBloodGlucose "github.com/tidepool-org/platform/data/blood/glucose" | ||
"github.com/tidepool-org/platform/metadata" | ||
"github.com/tidepool-org/platform/test" | ||
) | ||
|
||
func RandomUnits() string { | ||
return test.RandomStringFromArray(dataBloodGlucose.Units()) | ||
} | ||
|
||
func ExpectRaw(raw *metadata.Metadata, expectedRaw *metadata.Metadata) { | ||
if expectedRaw != nil { | ||
gomega.Expect(raw).ToNot(gomega.BeNil()) | ||
if units := expectedRaw.Get("units"); units == nil { | ||
gomega.Expect(raw.Get("units")).To(gomega.BeNil()) | ||
} else { | ||
gomega.Expect(raw.Get("units")).To(gomega.Equal(units)) | ||
} | ||
if value := expectedRaw.Get("value"); value == nil { | ||
gomega.Expect(raw.Get("value")).To(gomega.BeNil()) | ||
} else { | ||
gomega.Expect(raw.Get("value")).To(gomega.Equal(value)) | ||
} | ||
} else { | ||
gomega.Expect(raw).To(gomega.BeNil()) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,8 +5,17 @@ import ( | |
|
||
"github.com/tidepool-org/platform/data" | ||
dataStore "github.com/tidepool-org/platform/data/store" | ||
"github.com/tidepool-org/platform/data/types" | ||
dataTypesUpload "github.com/tidepool-org/platform/data/types/upload" | ||
"github.com/tidepool-org/platform/errors" | ||
"github.com/tidepool-org/platform/page" | ||
"github.com/tidepool-org/platform/pointer" | ||
) | ||
|
||
const ( | ||
DeviceDeactivateHashVersionUnknown = "unknown-hash" | ||
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. Sorry, I think we have a disconnect. I may not have explained myself very well. These version strings need to remain the same. There need to be two separate version groups. First, the version of the DeviceDeactivationHash deduplicator. That would be "0.0.0" (for Jellyfish) and "1.1.0" (for current Platform). Second, the version of the identity fields, that would be, for simplicity, "0" (for legacy) and "1" (for current). This is what is passed into the datum.IdentityFields function. The hash function and HashOptions, since it is not specific to the DeviceDeactivateHash deduplicator, should use the identity fields version. Or, for complete separation of concerns, you could add a third version, the hash version, either "0" or "1". So, then the code maps from deduplicator version to hash version to identity fields version. The DeviceDeactivateHash code looks at its version, maps its version to a hash version and creates the HashOptions with that version. Then, the hash code looks at its version, maps its version to an identity field versions and calls IdentityFields with that identity field version. Then, you've completely isolated the DeviceDeactivationHash deduplicator from the hash functionality from the identity fields functionality. In practice, we definitely have to do the first step (deduplicator version to hash version) because there will be another duplicator for continuous data sets that is not based off the device id, but the data set id, and doesn't deactivate, but deletes. Technically, we don't actually need the hash version and could just use the identity fields version for both hash function and IdentityFields function. Does that make sense? Let's chat about this tomorrow. |
||
DeviceDeactivateHashVersionLegacy = "legacy-hash" | ||
DeviceDeactivateHashVersionCurrent = "current-hash" | ||
) | ||
|
||
const DeviceDeactivateHashName = "org.tidepool.deduplicator.device.deactivate.hash" | ||
|
@@ -18,12 +27,36 @@ var DeviceDeactivateHashDeviceManufacturerDeviceModels = map[string][]string{ | |
"Trividia Health": {"TRUE METRIX", "TRUE METRIX AIR", "TRUE METRIX GO"}, | ||
} | ||
|
||
var DeviceDeactivateLegacyHashManufacturerDeviceModels = map[string][]string{ | ||
"Arkray": {"GlucocardExpression"}, | ||
"Bayer": {"Contour Next Link", "Contour Next Link 2.4", "Contour Next", "Contour USB", "Contour Next USB", "Contour Next One", "Contour", "Contour Next EZ", "Contour Plus", "Contour Plus Blue"}, | ||
"Dexcom": {"G5 touchscreen receiver", "G6 touchscreen receiver"}, | ||
"GlucoRx": {"Nexus", "HCT", "Nexus Mini Ultra", "Go"}, | ||
"i-SENS": {"CareSens"}, | ||
"MicroTech": {"Equil"}, | ||
"Roche": {"Aviva Connect", "Performa Connect", "Guide", "Instant (single-button)", "Guide Me", "Instant (two-button)", "Instant S (single-button)", "ReliOn Platinum"}, | ||
|
||
"Insulet": {"Dash", "Eros", "OmniPod"}, | ||
"Tandem": {"1002717", "5602", "5448004", "5448003", "5448001", "5448", "4628003", "4628", "10037177", "1001357", "1000354", "1000096"}, | ||
} | ||
|
||
type DeviceDeactivateHash struct { | ||
*Base | ||
} | ||
|
||
func NewDeviceDeactivateLegacyHash() (*DeviceDeactivateHash, error) { | ||
base, err := NewBase(DeviceDeactivateHashName, DeviceDeactivateHashVersionLegacy) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &DeviceDeactivateHash{ | ||
Base: base, | ||
}, nil | ||
} | ||
|
||
func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { | ||
base, err := NewBase(DeviceDeactivateHashName, "1.1.0") | ||
base, err := NewBase(DeviceDeactivateHashName, DeviceDeactivateHashVersionCurrent) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
@@ -33,44 +66,70 @@ func NewDeviceDeactivateHash() (*DeviceDeactivateHash, error) { | |
}, nil | ||
} | ||
|
||
func getDeduplicatorVersion(dataSet *dataTypesUpload.Upload) string { | ||
if dataSet.Deduplicator != nil { | ||
if dataSet.Deduplicator.Name != nil && dataSet.Deduplicator.Version != nil { | ||
if *dataSet.Deduplicator.Name == DeviceDeactivateHashName { | ||
if types.LegacyIdentityFieldsVersion == *dataSet.Deduplicator.Version { | ||
return DeviceDeactivateHashVersionLegacy | ||
} else if types.IdentityFieldsVersion == *dataSet.Deduplicator.Version { | ||
return DeviceDeactivateHashVersionCurrent | ||
} | ||
} | ||
} | ||
} | ||
if dataSet.DeviceManufacturers != nil && dataSet.DeviceModel != nil { | ||
for _, deviceManufacturer := range *dataSet.DeviceManufacturers { | ||
if allowedDeviceModels, found := DeviceDeactivateLegacyHashManufacturerDeviceModels[deviceManufacturer]; found { | ||
for _, allowedDeviceModel := range allowedDeviceModels { | ||
if allowedDeviceModel == *dataSet.DeviceModel { | ||
return DeviceDeactivateHashVersionLegacy | ||
} | ||
} | ||
} | ||
} | ||
for _, deviceManufacturer := range *dataSet.DeviceManufacturers { | ||
if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { | ||
for _, allowedDeviceModel := range allowedDeviceModels { | ||
if allowedDeviceModel == *dataSet.DeviceModel { | ||
return DeviceDeactivateHashVersionCurrent | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return DeviceDeactivateHashVersionUnknown | ||
} | ||
|
||
func (d *DeviceDeactivateHash) New(ctx context.Context, dataSet *dataTypesUpload.Upload) (bool, error) { | ||
if dataSet == nil { | ||
return false, errors.New("data set is missing") | ||
} | ||
|
||
if !dataSet.HasDataSetTypeNormal() { | ||
return false, nil | ||
} | ||
if dataSet.DeviceID == nil { | ||
return false, nil | ||
} | ||
|
||
if dataSet.HasDeduplicatorName() { | ||
return d.Get(ctx, dataSet) | ||
} | ||
return getDeduplicatorVersion(dataSet) != DeviceDeactivateHashVersionUnknown, nil | ||
} | ||
|
||
if dataSet.DeviceManufacturers == nil || dataSet.DeviceModel == nil { | ||
return false, nil | ||
func (d *DeviceDeactivateHash) Get(ctx context.Context, dataSet *dataTypesUpload.Upload) (bool, error) { | ||
// NOTE: check legacy first then fallback to other matches | ||
if dataSet == nil { | ||
return false, errors.New("data set is missing") | ||
} | ||
|
||
for _, deviceManufacturer := range *dataSet.DeviceManufacturers { | ||
if allowedDeviceModels, found := DeviceDeactivateHashDeviceManufacturerDeviceModels[deviceManufacturer]; found { | ||
for _, allowedDeviceModel := range allowedDeviceModels { | ||
if allowedDeviceModel == *dataSet.DeviceModel { | ||
return true, nil | ||
} | ||
} | ||
} | ||
if getDeduplicatorVersion(dataSet) == DeviceDeactivateHashVersionLegacy { | ||
return true, nil | ||
} | ||
|
||
return false, nil | ||
} | ||
|
||
func (d *DeviceDeactivateHash) Get(ctx context.Context, dataSet *dataTypesUpload.Upload) (bool, error) { | ||
if found, err := d.Base.Get(ctx, dataSet); err != nil || found { | ||
return found, err | ||
} | ||
|
||
return dataSet.HasDeduplicatorNameMatch("org.tidepool.hash-deactivate-old"), nil // TODO: DEPRECATED | ||
} | ||
|
||
|
@@ -88,10 +147,27 @@ func (d *DeviceDeactivateHash) AddData(ctx context.Context, repository dataStore | |
return errors.New("data set data is missing") | ||
} | ||
|
||
if err := AssignDataSetDataIdentityHashes(dataSetData); err != nil { | ||
return err | ||
options := NewDefaultDeviceDeactivateHashOptions() | ||
|
||
if getDeduplicatorVersion(dataSet) == DeviceDeactivateHashVersionLegacy { | ||
filter := &data.DataSetFilter{LegacyOnly: pointer.FromBool(true), DeviceID: dataSet.DeviceID} | ||
pagination := &page.Pagination{Page: 1, Size: 1} | ||
|
||
uploads, err := repository.ListUserDataSets(ctx, *dataSet.UserID, filter, pagination) | ||
if err != nil { | ||
return errors.Wrap(err, "error getting datasets for user") | ||
} | ||
if len(uploads) != 0 { | ||
if uploads[0].LegacyGroupID == nil { | ||
return errors.New("missing required legacy groupId for the device deactive hash legacy version") | ||
} | ||
options = NewLegacyHashOptions(*uploads[0].LegacyGroupID) | ||
} | ||
} | ||
|
||
if err := AssignDataSetDataIdentityHashes(dataSetData, options); err != nil { | ||
return err | ||
} | ||
return d.Base.AddData(ctx, repository, dataSet, dataSetData) | ||
} | ||
|
||
|
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.
Why removed?