Skip to content

Commit

Permalink
Merge pull request #1855 from opensrp/fix-sync
Browse files Browse the repository at this point in the history
WCARO Sync fixes and improvements
  • Loading branch information
allan-on authored Sep 16, 2021
2 parents 5774fce + 2ba9736 commit 96f6b6a
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 17 deletions.
3 changes: 1 addition & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ allprojects {
maven { url "https://cloudant.github.io/cloudant-sync-eap/repository" }
maven { url 'https://maven.fabric.io/public' }
maven { url "https://s3.amazonaws.com/repo.commonsware.com" }
maven { url "https://dl.bintray.com/ona/rdt-capture" }
maven { url 'https://nexus.pentaho.org/content/groups/omni/' }
maven { url 'https://dl.bintray.com/ibm-watson-health/ibm-fhir-server-releases' }
maven { url "https://dl.bintray.com/ona/kujaku" }
}
}

Expand Down
22 changes: 14 additions & 8 deletions opensrp-chw/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ android {
buildConfigField "boolean", "IS_SYNC_SETTINGS", "false"
buildConfigField "String", "THINKMD_BASE_URL", '"https://app.africa.thinkmd.tech"'
buildConfigField "String", "THINKMD_END_POINT", '"/#/start"'
buildConfigField "int", "MAX_CONNECTION_TIMEOUT", '1'
buildConfigField "int", "MAX_READ_TIMEOUT", '1'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
javaCompileOptions {
annotationProcessorOptions {
Expand Down Expand Up @@ -235,8 +237,8 @@ android {
chad {
dimension = 'baseDimension'
applicationIdSuffix ".chad"
versionCode 1
versionName "1.0.1"
versionCode 2
versionName "1.0.2"
buildConfigField "String", 'opensrp_url', '"https://wcaro-td.smartregister.org/opensrp/"'
buildConfigField "String", 'guidebooks_url', '"https://opensrp.s3.amazonaws.com/media/chad/"'
buildConfigField "String", 'opensrp_url_debug', '"https://wcaro-stage.smartregister.org/opensrp/"'
Expand All @@ -246,13 +248,15 @@ android {
buildConfigField "String", 'DEFAULT_LOCATION', '"Village"'
buildConfigField "String", 'DEFAULT_LOCATION_DEBUG', '"CHA"'
buildConfigField "int", "DATABASE_VERSION", '14'
buildConfigField "int", "MAX_CONNECTION_TIMEOUT", '5'
buildConfigField "int", "MAX_READ_TIMEOUT", '5'
}
drc {
resConfigs "en", "fr"
dimension = 'baseDimension'
applicationIdSuffix ".drc"
versionCode 6
versionName "1.0.11"
versionCode 10
versionName "1.0.15"
buildConfigField "String", 'opensrp_url', '"https://wcaro-cd.smartregister.org/opensrp/"'
buildConfigField "String", 'guidebooks_url', '"https://opensrp.s3.amazonaws.com/media/drc/"'
buildConfigField "String", 'opensrp_url_preview', '"https://wcaro-cd-preview.smartregister.org/opensrp/"'
Expand All @@ -262,6 +266,8 @@ android {
buildConfigField "String[]", "ALLOWED_LOCATION_LEVELS_DEBUG", '{"Pays" , "Province(DPS)" , "Zone de Sante","Aire de Sante" , "CAC" ,"VILLAGE/COMMUNAUTE"}'
buildConfigField "String", 'DEFAULT_LOCATION_DEBUG', '"VILLAGE/COMMUNAUTE"'
buildConfigField "String", 'DEFAULT_LOCATION', '"VILLAGE/COMMUNAUTE"'
buildConfigField "int", "MAX_CONNECTION_TIMEOUT", '5'
buildConfigField "int", "MAX_READ_TIMEOUT", '5'
buildConfigField "int", "DATABASE_VERSION", '11'
}
guinea {
Expand All @@ -287,13 +293,13 @@ android {
togo {
dimension = 'baseDimension'
applicationIdSuffix ".togo"
versionCode 22
versionName "1.2.4"
versionCode 23
versionName "1.2.5"
buildConfigField "int", "OPENMRS_UNIQUE_ID_INITIAL_BATCH_SIZE", '1000'
buildConfigField "int", "OPENMRS_UNIQUE_ID_BATCH_SIZE", '500'
buildConfigField "String", 'opensrp_url', '"https://wcaro-tg.smartregister.org/opensrp/"'
buildConfigField "String", 'guidebooks_url', '"https://opensrp.s3.amazonaws.com/media/togo/"'
buildConfigField "String", 'opensrp_url_debug', '"https://wcaro-togo-preview.smartregister.org/opensrp/"'
buildConfigField "String", 'opensrp_url_debug', '"https://wcaro-stage.smartregister.org/opensrp/"'
buildConfigField "String[]", "LOCATION_HIERACHY", '{"National", "Regional" , "District" , "Formation sanitaire", "Supervisor", "Village" }'
buildConfigField "String[]", "ALLOWED_LOCATION_LEVELS_DEBUG", '{"National", "Regional" , "District" , "Formation sanitaire", "Supervisor", "Village"}'
buildConfigField "String[]", "ALLOWED_LOCATION_LEVELS", '{"National", "Regional" , "District" , "Formation sanitaire", "Supervisor", "Village"}'
Expand Down Expand Up @@ -338,7 +344,7 @@ android {
}

dependencies {
implementation('org.smartregister:opensrp-client-chw-core:2.1.2-SNAPSHOT@aar') {
implementation('org.smartregister:opensrp-client-chw-core:2.1.3-SNAPSHOT@aar') {
transitive = true
exclude group: 'com.android.support', module: 'appcompat-v7'
exclude group: 'androidx.legacy', module: 'legacy-support-v4'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ public boolean hasCommunityResponders() {
return true;
}

@Override
public boolean hasSyncStatusProgressBar() {
return false;
}

@Override
public Intent getStockReportIntent(Activity activity) {
return new Intent(activity, CoreStockInventoryReportActivity.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.smartregister.chw.BuildConfig;
import org.smartregister.chw.activity.LoginActivity;
import org.smartregister.location.helper.LocationHelper;
import org.smartregister.repository.AllSharedPreferences;
import org.smartregister.view.activity.BaseLoginActivity;

import java.util.List;
Expand All @@ -30,15 +31,21 @@ public SyncFilter getSyncFilterParam() {

@Override
public String getSyncFilterValue() {
String providerId = org.smartregister.Context.getInstance().allSharedPreferences().fetchRegisteredANM();
String userLocationId = org.smartregister.Context.getInstance().allSharedPreferences().fetchUserLocalityId(providerId);
String providerId = allSharedPreferences().fetchRegisteredANM();
String locationId = allSharedPreferences().fetchDefaultLocalityId(providerId);
if(StringUtils.isBlank(locationId)) locationId = allSharedPreferences().fetchUserLocalityId(providerId);

List<String> locationIds = LocationHelper.getInstance().locationsFromHierarchy(true, null);
if (!isEmptyCollection(locationIds)) {
int index = locationIds.indexOf(userLocationId);
int index = locationIds.indexOf(locationId);
List<String> subLocationIds = locationIds.subList(index, locationIds.size());
return StringUtils.join(subLocationIds, ",");
}
return userLocationId;
return locationId;
}

private AllSharedPreferences allSharedPreferences(){
return org.smartregister.Context.getInstance().allSharedPreferences();
}

@Override
Expand Down Expand Up @@ -73,7 +80,7 @@ public boolean updateClientDetailsTable() {

@Override
public boolean isSyncUsingPost() {
return !BuildConfig.DEBUG && ChwApplication.getApplicationFlavor().syncUsingPost();
return ChwApplication.getApplicationFlavor().syncUsingPost();
}

@Override
Expand Down Expand Up @@ -106,8 +113,23 @@ public String getOauthClientSecret() {
return BuildConfig.OAUTH_CLIENT_SECRET;
}

@Override
public int getConnectTimeout() {
return BuildConfig.MAX_CONNECTION_TIMEOUT * 60000;
}

@Override
public int getReadTimeout() {
return BuildConfig.MAX_READ_TIMEOUT * 60000;
}

@Override
public Class<? extends BaseLoginActivity> getAuthenticationActivity() {
return LoginActivity.class;
}

@Override
public boolean validateUserAssignments() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public List<Pair<String, Locale>> getSupportedLanguages() {
return Arrays.asList(Pair.of("English", Locale.ENGLISH), Pair.of("Français", Locale.FRENCH));
}

@Override
public boolean hasSyncStatusProgressBar() {
return true;
}

@Override
public HashMap<String, String> getTableMapValues() {
return new HashMap<>();
Expand Down
23 changes: 23 additions & 0 deletions opensrp-chw/src/main/java/org/smartregister/chw/dao/EventDao.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.smartregister.chw.application.ChwApplication;
import org.smartregister.clientandeventmodel.Event;
import org.smartregister.dao.AbstractDao;
import org.smartregister.repository.BaseRepository;
import org.smartregister.sync.helper.ECSyncHelper;

import java.util.ArrayList;
Expand All @@ -15,6 +16,28 @@

public class EventDao extends AbstractDao {

/***
* This method forces the device to resync all the data without an event id
* NB: Critical bug detected on Sync
*/
public static void markEventsForReUpload() {
updateDB("update client set syncStatus = '" + BaseRepository.TYPE_Unsynced + "' where baseEntityId in (select baseEntityId from event where ifnull(eventId,'') = '') ");
updateDB("update ImageList set syncStatus = '" + BaseRepository.TYPE_Unsynced + "' where entityId in (select baseEntityId from event where ifnull(eventId,'') = '') ");
updateDB("update event set syncStatus = '" + BaseRepository.TYPE_Unsynced + "' where ifnull(eventId,'') = '' ");
}

/***
* Computes the minimum server Id before any possibly unsynced event found in the database.
* This method should return a NULL value if all events are synced.
* @return
*/
public static Long getMinimumVerifiedServerVersion() {
String sql = "select max(serverVersion) serverVersion from event where dateCreated <= (select min(dateCreated) minDate from event where ifnull(eventId,'') = '' and syncStatus = 'Synced') ";
DataMap<Long> dataMap = c -> {
return getCursorLongValue(c, "serverVersion");
};
return AbstractDao.readSingleValue(sql, dataMap);
}

public static List<Event> getEvents(String baseEntityID, String eventType, int limit) {
String sql = "select json from event where baseEntityId = '" + baseEntityID + "' COLLATE NOCASE and eventType = '" + eventType + "' COLLATE NOCASE order by updatedAt desc limit " + limit;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
package org.smartregister.chw.sync;

import org.smartregister.chw.dao.EventDao;
import org.smartregister.sync.intent.SyncIntentService;

public class ChwSyncIntentService extends SyncIntentService {

@Override
protected void handleSync() {
// fetch the last downloaded serverVersion before any unsyced data
Long serverVersion = EventDao.getMinimumVerifiedServerVersion();
if (serverVersion != null)
org.smartregister.util.Utils.getAllSharedPreferences().saveLastSyncDate(serverVersion);

// flag all contentious events as unsynced
EventDao.markEventsForReUpload();
super.handleSync();
}

@Override
public int getEventPullLimit() {
return 1000;
}


@Override
protected Integer getEventBatchSize(){
return 250;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.robolectric.RobolectricTestRunner;
import org.smartregister.clientandeventmodel.Event;
import org.smartregister.dao.AbstractDao;
import org.smartregister.repository.BaseRepository;
import org.smartregister.repository.Repository;

import java.util.Arrays;
Expand All @@ -37,7 +38,7 @@ public void setUp() {
}

@Test
public void getEvents() {
public void getEventsReturnsCorrectEvents() {
MatrixCursor matrixCursor = new MatrixCursor(new String[]{"json"});
matrixCursor.addRow(new Object[]{eventJson});
Mockito.doReturn(matrixCursor).when(database).rawQuery(Mockito.any(), Mockito.any());
Expand All @@ -48,13 +49,31 @@ public void getEvents() {
}

@Test
public void getLatestEvent() {
public void getLatestEventReturnsCorrectEvent() {
MatrixCursor matrixCursor = new MatrixCursor(new String[]{"json"});
matrixCursor.addRow(new Object[]{eventJson});
Mockito.doReturn(matrixCursor).when(database).rawQuery(Mockito.any(), Mockito.any());
Event event = EventDao.getLatestEvent("some-base-entity-id", Arrays.asList("some-event-type", "another-event-type"));
Assert.assertNotNull(event);
}

@Test
public void markEventsForReUploadExecutesCorrectUpdateQueries() {
Mockito.doReturn(database).when(repository).getWritableDatabase();
EventDao.markEventsForReUpload();
Mockito.verify(database).rawExecSQL("update client set syncStatus = '" + BaseRepository.TYPE_Unsynced + "' where baseEntityId in (select baseEntityId from event where ifnull(eventId,'') = '') ");
Mockito.verify(database).rawExecSQL("update ImageList set syncStatus = '" + BaseRepository.TYPE_Unsynced + "' where entityId in (select baseEntityId from event where ifnull(eventId,'') = '') ");
Mockito.verify(database).rawExecSQL("update event set syncStatus = '" + BaseRepository.TYPE_Unsynced + "' where ifnull(eventId,'') = '' ");
}

@Test
public void getMinimumVerifiedServerVersionReturnsCorrectVersion() {
MatrixCursor matrixCursor = new MatrixCursor(new String[]{"serverVersion"});
matrixCursor.addRow(new Object[]{12324567L});
Mockito.doReturn(matrixCursor).when(database).rawQuery(Mockito.any(), Mockito.any());
Long serverVersion = EventDao.getMinimumVerifiedServerVersion();
Assert.assertNotNull(serverVersion);
Assert.assertTrue(serverVersion.equals(12324567L));
}

}

0 comments on commit 96f6b6a

Please sign in to comment.