Skip to content

Commit

Permalink
Merge pull request #270 from OpenSRP/issue/269-syncprocessor-reproces…
Browse files Browse the repository at this point in the history
…sing

Added an intermediate state during sync of locally processed events
  • Loading branch information
rkodev authored Jul 18, 2019
2 parents 53740b2 + 5758458 commit 0a35c0f
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class BaseRepository {
public static String TYPE_Valid = "Valid";
public static String TYPE_InValid = "Invalid";
public static String TYPE_Task_Unprocessed = "task_unprocessed";
public static String TYPE_Unprocessed = "unprocessed";
public static String TYPE_Created = "Created";
protected static final String ORDER_BY = " order by ";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import timber.log.Timber;

import static org.smartregister.AllConstants.ROWID;

/**
Expand Down Expand Up @@ -795,15 +798,15 @@ public Map<String, Object> getUnSyncedEvents(int limit) {
+ Table.event.name()
+ " where "
+ event_column.syncStatus
+ " = ? and length("
+ " in (? , ?) and length("
+ event_column.json
+ ")>2 order by "
+ event_column.updatedAt
+ " asc limit "
+ limit;
Cursor cursor = null;
try {
cursor = getWritableDatabase().rawQuery(query, new String[]{BaseRepository.TYPE_Unsynced});
cursor = getWritableDatabase().rawQuery(query, new String[]{BaseRepository.TYPE_Unsynced, BaseRepository.TYPE_Unprocessed});

while (cursor.moveToNext()) {
String jsonEventStr = (cursor.getString(0));
Expand Down Expand Up @@ -1262,7 +1265,7 @@ public List<EventClient> getEventsByBaseEntityIdsAndSyncStatus(String syncStatus
*
* @param lastRowId
* @return JsonData which contains a {@link JSONArray} and the maximum row id in the array
* of {@link Event}s returned. This enables this method to be called again for the consequent batches
* of {@link Event}s returned. This enables this method to be called again for the consequent batches
*/
@Nullable
public JsonData getEvents(long lastRowId, int limit) {
Expand Down Expand Up @@ -1337,8 +1340,8 @@ private JSONObject getEventObject(Cursor cursor, long rowId) throws JSONExceptio
*
* @param lastRowId
* @return JsonData which contains a {@link JSONArray} and the maximum row id in the array
* of {@link Client}s returned or {@code null} if no records match the conditions or an exception occurred.
* This enables this method to be called again for the consequent batches
* of {@link Client}s returned or {@code null} if no records match the conditions or an exception occurred.
* This enables this method to be called again for the consequent batches
*/
@Nullable
public JsonData getClients(long lastRowId, int limit) {
Expand Down Expand Up @@ -1418,7 +1421,7 @@ public void addorUpdateClient(String baseEntityId, JSONObject jsonObject, String
}

public void addEvent(String baseEntityId, JSONObject jsonObject) {//Backward compatibility
addEvent(baseEntityId, jsonObject, BaseRepository.TYPE_Unsynced);
addEvent(baseEntityId, jsonObject, BaseRepository.TYPE_Unprocessed);
}

public void addEvent(String baseEntityId, JSONObject jsonObject, String syncStatus) {
Expand Down Expand Up @@ -1464,16 +1467,36 @@ public void addEvent(String baseEntityId, JSONObject jsonObject, String syncStat
}

} catch (Exception e) {
Log.e(getClass().getName(), "Exception", e);
Timber.e(e);
}
}

/**
* Flag an event as locally processed.
* This method only updates locally created and processed events and prevents reprocessing locally
* @param formSubmissionId
*/
public void markEventAsProcessed(String formSubmissionId) {
try {

ContentValues values = new ContentValues();
values.put(event_column.syncStatus.name(), BaseRepository.TYPE_Unsynced);
values.put(ROWID, getMaxRowId(Table.event) + 1);

getWritableDatabase().update(Table.event.name(),
values,
event_column.formSubmissionId.name() + " = ? and " + event_column.syncStatus.name() + " = ? ",
new String[]{formSubmissionId, BaseRepository.TYPE_Unprocessed});

} catch (Exception e) {
Timber.e(e);
}
}

public void markEventAsSynced(String formSubmissionId) {
try {

ContentValues values = new ContentValues();
values.put(event_column.formSubmissionId.name(), formSubmissionId);
values.put(event_column.syncStatus.name(), BaseRepository.TYPE_Synced);
values.put(ROWID, getMaxRowId(Table.event) + 1);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,24 @@ public synchronized void processClient(List<EventClient> eventClientList) throws
}
}

/**
* Call this method to flag the event as processed in the local repository.
* All events valid or otherwise must be flagged to avoid re-processing
* @param event
*/
public void completeProcessing(Event event) {
if (event == null)
return;

CoreLibrary.getInstance().context()
.getEventClientRepository().markEventAsProcessed(event.getFormSubmissionId());
}

public Boolean processEvent(Event event, Client client, ClientClassification clientClassification) throws Exception {
try {
// mark event as processed regardless of any errors
completeProcessing(event);

if (event.getCreator() != null) {
Log.i(TAG, "EVENT from openmrs");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ public void fetchEventClientsByRowId() throws Exception {
MatrixCursor matrixCursor = new MatrixCursor(new String[]{"rowid", "json"});
JSONArray eventArray = new JSONArray(ClientData.eventJsonArray);
for (int i = 0; i < eventArray.length(); i++) {
matrixCursor.addRow(new String[]{(i+1) + "", eventArray.getJSONObject(i).toString()});
matrixCursor.addRow(new String[]{(i + 1) + "", eventArray.getJSONObject(i).toString()});
}

Mockito.when(sqliteDatabase.rawQuery(org.mockito.ArgumentMatchers.anyString(), org.mockito.ArgumentMatchers.any(Object[].class))).thenReturn(matrixCursor);
Expand Down Expand Up @@ -318,4 +318,17 @@ public void assertcreateTableCallsExecSql() {
Mockito.verify(sqliteDatabase, Mockito.times(count)).execSQL(Mockito.anyString());
}

/**
* Events manually saved should always have an unprocessed status
*/
@Test
public void testAddEventDefaultStatus() {
EventClientRepository eventClientRepository = Mockito.spy(new EventClientRepository(repository));
String baseEntityId = "12345";
JSONObject jsonObject = Mockito.mock(JSONObject.class);

eventClientRepository.addEvent(baseEntityId, jsonObject);

Mockito.verify(eventClientRepository).addEvent(baseEntityId, jsonObject, BaseRepository.TYPE_Unprocessed);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.smartregister.sync;

import android.content.Context;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.smartregister.BaseUnitTest;
import org.smartregister.domain.db.Event;

public class ClientProcessorForJavaTest extends BaseUnitTest {

@Mock
private Context context;


@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}

@Test
public void testProcessEventMarksItSaved() throws Exception {
ClientProcessorForJava clientProcessorForJava = Mockito.spy(new ClientProcessorForJava(context));
Event mockEvent = Mockito.mock(Event.class);
clientProcessorForJava.processEvent(mockEvent, null, null);

Mockito.verify(clientProcessorForJava).completeProcessing(mockEvent);
}
}

0 comments on commit 0a35c0f

Please sign in to comment.