Skip to content

Commit 3871340

Browse files
committed
skip server error when fetching diagn.serv.items
1 parent e530891 commit 3871340

3 files changed

Lines changed: 178 additions & 5 deletions

File tree

claimManagement/src/main/java/org/openimis/imisclaims/MainActivity.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,8 @@ public void DownLoadDiagnosesServicesItems(@Nullable final String officerCode) {
619619
Thread thread = new Thread() {
620620
public void run() {
621621
try {
622-
DiagnosesServicesMedications diagnosesServicesMedications = new FetchDiagnosesServicesItems().execute();
622+
FetchDiagnosesServicesItems fetchDiagnosesServicesItems = new FetchDiagnosesServicesItems();
623+
DiagnosesServicesMedications diagnosesServicesMedications = fetchDiagnosesServicesItems.execute();
623624
saveLastUpdateDate(diagnosesServicesMedications.getLastUpdated());
624625
sqlHandler.ClearAll("tblReferences");
625626
sqlHandler.ClearAll("tblHealthFacilities");
@@ -688,6 +689,14 @@ public void run() {
688689

689690
runOnUiThread(() -> {
690691
progressDialog.dismiss();
692+
if (!fetchDiagnosesServicesItems.getSkippedMedicationPages().isEmpty()) {
693+
Toast.makeText(
694+
MainActivity.this,
695+
"Master data synced with partial medications. Skipped pages: "
696+
+ fetchDiagnosesServicesItems.getSkippedMedicationPages(),
697+
Toast.LENGTH_LONG
698+
).show();
699+
}
691700
if (officerCode != null) {
692701
DownLoadServicesItemsPriceList(officerCode);
693702
}

claimManagement/src/main/java/org/openimis/imisclaims/network/util/PaginatedResponseUtils.java

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
import androidx.annotation.Nullable;
55
import androidx.annotation.WorkerThread;
66

7+
import org.openimis.imisclaims.network.exception.HttpException;
78
import org.openimis.imisclaims.network.request.BaseFHIRGetPaginatedRequest;
89
import org.openimis.imisclaims.network.response.PaginatedResponse;
10+
import org.openimis.imisclaims.tools.Log;
911

1012
import java.util.ArrayList;
1113
import java.util.Collection;
14+
import java.util.Collections;
1215
import java.util.List;
1316

1417
public class PaginatedResponseUtils {
18+
private static final String LOG_TAG = "FHIR_SYNC_TOLERANCE";
1519

1620
private PaginatedResponseUtils() {
1721
throw new IllegalAccessError("This constructor is private");
@@ -50,10 +54,153 @@ public static <T, U> List<U> downloadAll(
5054
return list;
5155
}
5256

57+
@NonNull
58+
@WorkerThread
59+
public static <T, U> DownloadResult<U> downloadAllSkipFailedPages(
60+
@NonNull String endpoint,
61+
@NonNull RequestExecutor<T> executor,
62+
@Nullable Mapper.Transformer<T, U> transformer,
63+
int maxPages,
64+
int maxConsecutiveFailures
65+
) throws Exception {
66+
int page = 0;
67+
int consecutiveFailures = 0;
68+
boolean hasMore = true;
69+
boolean hasSkippedPages = false;
70+
List<U> list = new ArrayList<>();
71+
List<Integer> skippedPages = new ArrayList<>();
72+
List<Integer> recoveredPages = new ArrayList<>();
73+
Mapper<T, U> mapper = transformer != null ? new Mapper<>(transformer) : null;
74+
75+
while (hasMore && page < maxPages) {
76+
try {
77+
PaginatedResponse<T> response = executor.download(page);
78+
if (mapper != null) {
79+
list.addAll(mapper.map(response.getValue()));
80+
} else {
81+
list.addAll((Collection<? extends U>) response.getValue());
82+
}
83+
hasMore = response.hasMore();
84+
consecutiveFailures = 0;
85+
if (hasSkippedPages) {
86+
recoveredPages.add(page);
87+
}
88+
} catch (Exception exception) {
89+
skippedPages.add(page);
90+
hasSkippedPages = true;
91+
consecutiveFailures++;
92+
logSkippedPage(endpoint, page, exception);
93+
if (consecutiveFailures >= maxConsecutiveFailures) {
94+
Log.w(
95+
LOG_TAG,
96+
String.format(
97+
"endpoint=%s action=stop reason=maxConsecutiveFailures reached skippedPages=%s",
98+
endpoint,
99+
skippedPages
100+
)
101+
);
102+
break;
103+
}
104+
}
105+
page++;
106+
}
107+
108+
if (page >= maxPages && hasMore) {
109+
Log.w(
110+
LOG_TAG,
111+
String.format(
112+
"endpoint=%s action=stop reason=maxPages reached maxPages=%s skippedPages=%s",
113+
endpoint,
114+
maxPages,
115+
skippedPages
116+
)
117+
);
118+
}
119+
120+
Log.i(
121+
LOG_TAG,
122+
String.format(
123+
"endpoint=%s summary skippedPages=%s recoveredPages=%s totalItems=%s",
124+
endpoint,
125+
skippedPages,
126+
recoveredPages,
127+
list.size()
128+
)
129+
);
130+
return new DownloadResult<>(list, skippedPages, recoveredPages);
131+
}
132+
133+
private static void logSkippedPage(@NonNull String endpoint, int page, @NonNull Exception exception) {
134+
String errorType = exception.getClass().getSimpleName();
135+
if (exception instanceof HttpException) {
136+
HttpException httpException = (HttpException) exception;
137+
Log.w(
138+
LOG_TAG,
139+
String.format(
140+
"endpoint=%s page=%s action=skip errorType=%s code=%s message=%s",
141+
endpoint,
142+
page,
143+
errorType,
144+
httpException.getCode(),
145+
exception.getMessage()
146+
)
147+
);
148+
} else {
149+
Log.w(
150+
LOG_TAG,
151+
String.format(
152+
"endpoint=%s page=%s action=skip errorType=%s message=%s",
153+
endpoint,
154+
page,
155+
errorType,
156+
exception.getMessage()
157+
)
158+
);
159+
}
160+
}
161+
53162
public interface RequestExecutor<T> {
54163

55164
@NonNull
56165
@WorkerThread
57166
PaginatedResponse<T> download(int page) throws Exception;
58167
}
168+
169+
public static class DownloadResult<U> {
170+
@NonNull
171+
private final List<U> items;
172+
@NonNull
173+
private final List<Integer> skippedPages;
174+
@NonNull
175+
private final List<Integer> recoveredPages;
176+
177+
public DownloadResult(
178+
@NonNull List<U> items,
179+
@NonNull List<Integer> skippedPages,
180+
@NonNull List<Integer> recoveredPages
181+
) {
182+
this.items = items;
183+
this.skippedPages = skippedPages;
184+
this.recoveredPages = recoveredPages;
185+
}
186+
187+
@NonNull
188+
public List<U> getItems() {
189+
return items;
190+
}
191+
192+
@NonNull
193+
public List<Integer> getSkippedPages() {
194+
return Collections.unmodifiableList(skippedPages);
195+
}
196+
197+
@NonNull
198+
public List<Integer> getRecoveredPages() {
199+
return Collections.unmodifiableList(recoveredPages);
200+
}
201+
202+
public boolean hasSkippedPages() {
203+
return !skippedPages.isEmpty();
204+
}
205+
}
59206
}

claimManagement/src/main/java/org/openimis/imisclaims/usecase/FetchDiagnosesServicesItems.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,20 @@
1919
import org.openimis.imisclaims.util.DateUtils;
2020

2121
import java.util.Date;
22+
import java.util.List;
2223

2324
public class FetchDiagnosesServicesItems {
25+
private static final int MAX_PAGES = 1000;
26+
private static final int MAX_CONSECUTIVE_FAILURES = 3;
2427

2528
@NonNull
2629
private final GetActivityDefinitionsRequest getActivityDefinitionsRequest;
2730
@NonNull
2831
private final GetDiagnosesRequest getDiagnosesRequest;
2932
@NonNull
3033
private final GetMedicationsRequest getMedicationsRequest;
34+
@NonNull
35+
private List<Integer> skippedMedicationPages = java.util.Collections.emptyList();
3136

3237
public FetchDiagnosesServicesItems() {
3338
this(
@@ -50,6 +55,16 @@ public FetchDiagnosesServicesItems(
5055
@NonNull
5156
@WorkerThread
5257
public DiagnosesServicesMedications execute() throws Exception {
58+
PaginatedResponseUtils.DownloadResult<Medication> medicationDownloadResult =
59+
PaginatedResponseUtils.downloadAllSkipFailedPages(
60+
"Medication",
61+
getMedicationsRequest::get,
62+
this::toMedication,
63+
MAX_PAGES,
64+
MAX_CONSECUTIVE_FAILURES
65+
);
66+
skippedMedicationPages = medicationDownloadResult.getSkippedPages();
67+
5368
// previous code was passing sometimes a `last_updated_date` but it was either empty or
5469
// `new Date(0)`. I'm still returning the last updated date in case it's one day used
5570
// again.¯\_(ツ)_/¯
@@ -60,13 +75,15 @@ public DiagnosesServicesMedications execute() throws Exception {
6075
getActivityDefinitionsRequest::get,
6176
this::toService
6277
),
63-
/* medications = */ PaginatedResponseUtils.downloadAll(
64-
getMedicationsRequest::get,
65-
this::toMedication
66-
)
78+
/* medications = */ medicationDownloadResult.getItems()
6779
);
6880
}
6981

82+
@NonNull
83+
public List<Integer> getSkippedMedicationPages() {
84+
return skippedMedicationPages;
85+
}
86+
7087
@NonNull
7188
private Diagnosis toDiagnosis(@NonNull DiagnosisDto dto) {
7289
return new Diagnosis(

0 commit comments

Comments
 (0)