From 19c60683bb61bb60d8a5f40b9857b221f6977140 Mon Sep 17 00:00:00 2001 From: melad Date: Tue, 23 Jul 2024 13:28:55 +0300 Subject: [PATCH] [MS-589] add migration from old to new face config --- .../infra/config/store/ConfigStoreModule.kt | 7 +- .../ProjectConfigFaceBioSdkMigration.kt | 46 +++++++++++ .../ProjectConfigFaceBioSdkMigrationTest.kt | 80 +++++++++++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 infra/config-store/src/main/java/com/simprints/infra/config/store/local/migrations/ProjectConfigFaceBioSdkMigration.kt create mode 100644 infra/config-store/src/test/java/com/simprints/infra/config/store/local/migrations/ProjectConfigFaceBioSdkMigrationTest.kt diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigStoreModule.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigStoreModule.kt index d89c981636..f5ab71096f 100644 --- a/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigStoreModule.kt +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/ConfigStoreModule.kt @@ -7,6 +7,7 @@ import androidx.datastore.dataStoreFile import com.simprints.infra.config.store.local.ConfigLocalDataSource import com.simprints.infra.config.store.local.ConfigLocalDataSourceImpl import com.simprints.infra.config.store.local.migrations.DeviceConfigSharedPrefsMigration +import com.simprints.infra.config.store.local.migrations.ProjectConfigFaceBioSdkMigration import com.simprints.infra.config.store.local.migrations.ProjectConfigFingerprintBioSdkMigration import com.simprints.infra.config.store.local.migrations.ProjectConfigQualityThresholdMigration import com.simprints.infra.config.store.local.migrations.ProjectConfigSharedPrefsMigration @@ -70,7 +71,8 @@ object DataStoreModule { @ApplicationContext appContext: Context, projectConfigSharedPrefsMigration: ProjectConfigSharedPrefsMigration, projectConfigQualityThresholdMigration: ProjectConfigQualityThresholdMigration, - projectConfigFingerprintBioSdkMigration: ProjectConfigFingerprintBioSdkMigration + projectConfigFingerprintBioSdkMigration: ProjectConfigFingerprintBioSdkMigration, + projectConfigFaceBioSdkMigration: ProjectConfigFaceBioSdkMigration, ): DataStore { return DataStoreFactory.create( serializer = ProjectConfigurationSerializer, @@ -78,7 +80,8 @@ object DataStoreModule { migrations = listOf( projectConfigSharedPrefsMigration, projectConfigQualityThresholdMigration, - projectConfigFingerprintBioSdkMigration + projectConfigFingerprintBioSdkMigration, + projectConfigFaceBioSdkMigration ) ) } diff --git a/infra/config-store/src/main/java/com/simprints/infra/config/store/local/migrations/ProjectConfigFaceBioSdkMigration.kt b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/migrations/ProjectConfigFaceBioSdkMigration.kt new file mode 100644 index 0000000000..985e5066fb --- /dev/null +++ b/infra/config-store/src/main/java/com/simprints/infra/config/store/local/migrations/ProjectConfigFaceBioSdkMigration.kt @@ -0,0 +1,46 @@ +package com.simprints.infra.config.store.local.migrations + +import androidx.datastore.core.DataMigration +import com.simprints.infra.config.store.local.models.ProtoFaceConfiguration +import com.simprints.infra.config.store.local.models.ProtoProjectConfiguration +import com.simprints.infra.logging.Simber +import javax.inject.Inject + +/** + * Can be removed once all the devices have been updated to 2024.2.0 + */ +class ProjectConfigFaceBioSdkMigration @Inject constructor() : + DataMigration { + override suspend fun cleanUp() { + Simber.i("Migration of project configuration face bio sdk is done") + } + + override suspend fun shouldMigrate(currentData: ProtoProjectConfiguration) = + with(currentData.face) { + !hasRankOne() || allowedSdksCount == 0 + } + + override suspend fun migrate(currentData: ProtoProjectConfiguration): ProtoProjectConfiguration { + Simber.i("Start migration of project configuration face bio sdk to Datastore") + + val faceProto = currentData.face.toBuilder() + + // 1- add RANK_ONE to allowedSdks + faceProto.addAllowedSdks(ProtoFaceConfiguration.ProtoBioSdk.RANK_ONE) + + // 2- move face config to face.rankOne + faceProto.setRankOne( + ProtoFaceConfiguration.ProtoFaceSdkConfiguration + .newBuilder() + .setNbOfImagesToCapture(faceProto.nbOfImagesToCapture) + .setQualityThreshold(faceProto.qualityThreshold) + .setImageSavingStrategy(faceProto.imageSavingStrategy) + .setDecisionPolicy(faceProto.decisionPolicy) + .setVersion("") // Empty version will be treated as 1.23 + // allowed age range and verification match threshold will be null as they are not present in the old face configuration + + .build() + ) + return currentData.toBuilder().setFace(faceProto).build() + } +} diff --git a/infra/config-store/src/test/java/com/simprints/infra/config/store/local/migrations/ProjectConfigFaceBioSdkMigrationTest.kt b/infra/config-store/src/test/java/com/simprints/infra/config/store/local/migrations/ProjectConfigFaceBioSdkMigrationTest.kt new file mode 100644 index 0000000000..e8b36ba534 --- /dev/null +++ b/infra/config-store/src/test/java/com/simprints/infra/config/store/local/migrations/ProjectConfigFaceBioSdkMigrationTest.kt @@ -0,0 +1,80 @@ +package com.simprints.infra.config.store.local.migrations + +import com.google.common.truth.Truth.assertThat +import com.simprints.infra.config.store.local.models.ProtoAllowedAgeRange +import com.simprints.infra.config.store.local.models.ProtoFaceConfiguration +import com.simprints.infra.config.store.local.models.ProtoProjectConfiguration +import com.simprints.infra.config.store.testtools.protoDecisionPolicy +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class ProjectConfigFaceBioSdkMigrationTest { + @Test + fun `should migrate if face has no rankone config`() = runTest { + val currentData = ProtoProjectConfiguration.newBuilder().setFace( + ProtoFaceConfiguration.newBuilder() + .addAllowedSdks(ProtoFaceConfiguration.ProtoBioSdk.RANK_ONE).build() + ).build() + + val shouldMigrate = ProjectConfigFaceBioSdkMigration().shouldMigrate(currentData) + + assertThat(shouldMigrate).isTrue() + } + + @Test + fun `should migrate if face allowedSdks is empty `() = runTest { + val currentData = ProtoProjectConfiguration.newBuilder().setFace( + ProtoFaceConfiguration.newBuilder().setRankOne( + ProtoFaceConfiguration.ProtoFaceSdkConfiguration.newBuilder() + .setNbOfImagesToCapture(5).setQualityThreshold(1) + .setImageSavingStrategy(ProtoFaceConfiguration.ImageSavingStrategy.NEVER) + .setDecisionPolicy(protoDecisionPolicy).build() + ).build() + ).build() + + val shouldMigrate = ProjectConfigFaceBioSdkMigration().shouldMigrate(currentData) + + assertThat(shouldMigrate).isTrue() + } + + @Test + fun `should not migrate if face has rankone config and allowedSdks is not empty`() = runTest { + val currentData = ProtoProjectConfiguration.newBuilder().setFace( + ProtoFaceConfiguration.newBuilder().setRankOne( + ProtoFaceConfiguration.ProtoFaceSdkConfiguration.newBuilder().build() + ).addAllowedSdks(ProtoFaceConfiguration.ProtoBioSdk.RANK_ONE) + .build() + ).build() + val shouldMigrate = ProjectConfigFaceBioSdkMigration().shouldMigrate(currentData) + + assertThat(shouldMigrate).isFalse() + } + + + @Test + fun `should create rankone with value of the old face configuration`() = runTest { + val imageSavingStrategy = ProtoFaceConfiguration.ImageSavingStrategy.NEVER + val nbOfImagesToCapture = 2 + val qualityThreshold = 1 + val decisionPolicy = protoDecisionPolicy + val currentData = ProtoProjectConfiguration.newBuilder().setFace( + ProtoFaceConfiguration.newBuilder().setNbOfImagesToCapture(nbOfImagesToCapture) + .setQualityThreshold(qualityThreshold) + .setImageSavingStrategy(imageSavingStrategy) + .setDecisionPolicy(decisionPolicy) + .build() + ).build() + + val migratedData = + ProjectConfigFaceBioSdkMigration().migrate(currentData).face.rankOne + + assertThat(migratedData.decisionPolicy).isEqualTo(decisionPolicy) + assertThat(migratedData.imageSavingStrategy).isEqualTo(imageSavingStrategy) + assertThat(migratedData.nbOfImagesToCapture).isEqualTo(nbOfImagesToCapture) + assertThat(migratedData.qualityThreshold).isEqualTo(qualityThreshold) + assertThat(migratedData.version).isEmpty() + assertThat(migratedData.allowedAgeRange).isEqualTo(ProtoAllowedAgeRange.getDefaultInstance()) + + + } +}