• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

opensrp / opensrp-client-core / #179

pending completion
#179

push

github-actions

web-flow
Merge pull request #922 from opensrp/change-sync-service-modifier

Update doSync method access

18308 of 26768 relevant lines covered (68.4%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.8
opensrp-core/src/main/java/org/smartregister/service/DocumentConfigurationService.java
1
package org.smartregister.service;
2

3
import android.content.Context;
4

5
import androidx.annotation.NonNull;
6
import androidx.annotation.VisibleForTesting;
7

8
import com.google.gson.Gson;
9
import com.google.gson.GsonBuilder;
10
import com.google.gson.reflect.TypeToken;
11

12
import org.apache.commons.lang3.StringEscapeUtils;
13
import org.json.JSONException;
14
import org.json.JSONObject;
15
import org.smartregister.CoreLibrary;
16
import org.smartregister.DristhiConfiguration;
17
import org.smartregister.client.utils.contract.ClientFormContract;
18
import org.smartregister.domain.ClientForm;
19
import org.smartregister.domain.Manifest;
20
import org.smartregister.domain.Response;
21
import org.smartregister.dto.ClientFormResponse;
22
import org.smartregister.dto.ManifestDTO;
23
import org.smartregister.exception.NoHttpResponseException;
24
import org.smartregister.repository.ClientFormRepository;
25
import org.smartregister.repository.ManifestRepository;
26
import org.smartregister.util.JsonFormUtils;
27
import org.smartregister.util.Utils;
28

29
import java.text.MessageFormat;
30
import java.util.List;
31

32
import timber.log.Timber;
33

34
public class DocumentConfigurationService {
35
    public static final String MANIFEST_FORMS_VERSION = "forms_version";
36
    public static final String FORM_VERSION = "form_version";
37
    public static final String CURRENT_FORM_VERSION = "current_form_version";
38
    public static final String IDENTIFIERS = "identifiers";
39
    private static final String MANIFEST_SYNC_URL = "/rest/manifest/";
40
    private static final String MANIFEST_SEARCH_URL = "/rest/manifest/search";
41
    private static final String CLIENT_FORM_SYNC_URL = "/rest/clientForm";
42
    private static final String FORM_IDENTIFIER = "form_identifier";
43
    private static final String APP_ID = "app_id";
44
    private static final String APP_VERSION = "app_version";
45
    private final DristhiConfiguration configuration;
46
    private HTTPAgent httpAgent;
47
    private ManifestRepository manifestRepository;
48
    private ClientFormRepository clientFormRepository;
49

50
    public DocumentConfigurationService(HTTPAgent httpAgentArg, ManifestRepository manifestRepositoryArg, ClientFormRepository clientFormRepositoryArg, DristhiConfiguration
51
            configurationArg) {
1✔
52
        httpAgent = httpAgentArg;
1✔
53
        manifestRepository = manifestRepositoryArg;
1✔
54
        clientFormRepository = clientFormRepositoryArg;
1✔
55
        configuration = configurationArg;
1✔
56
    }
1✔
57

58
    public void fetchManifest() throws NoHttpResponseException, JSONException, IllegalArgumentException {
59
        if (httpAgent == null) {
1✔
60
            throw new IllegalArgumentException(MANIFEST_SYNC_URL + " http agent is null");
×
61
        }
62

63
        Context context = CoreLibrary.getInstance().context().applicationContext();
1✔
64

65
        String baseUrl = getBaseUrl();
1✔
66
        String finalUrls = MessageFormat.format("{0}{1}",
1✔
67
                baseUrl, MANIFEST_SEARCH_URL + "?" + APP_ID + "=" + Utils.getAppId(context) +
1✔
68
                        "&" + APP_VERSION + "=" + Utils.getAppVersion(context));
1✔
69
        Response resp = httpAgent.fetch(finalUrls);
1✔
70

71
        if (resp.isFailure()) {
1✔
72
            throw new NoHttpResponseException(MANIFEST_SYNC_URL + " not returned data");
×
73
        }
74

75
        ManifestDTO receivedManifestDTO = JsonFormUtils.gson.fromJson(resp.payload().toString(), ManifestDTO.class);
1✔
76

77
        if (receivedManifestDTO != null) {
1✔
78
            Manifest receivedManifest = convertManifestDTOToManifest(receivedManifestDTO);
1✔
79
            updateActiveManifest(receivedManifest);
1✔
80
            syncClientForms(receivedManifest);
1✔
81
        }
82
    }
1✔
83

84
    protected void updateActiveManifest(Manifest receivedManifest){
85
        //Note active manifest is null for the first time synchronization of the application
86
        Manifest activeManifest = manifestRepository.getActiveManifest();
1✔
87

88
        if (activeManifest != null && !activeManifest.getFormVersion().equals(receivedManifest.getFormVersion())) {
1✔
89
            //Untaging the active manifest and saving the received manifest and tagging it as active
90
            activeManifest.setActive(false);
1✔
91
            activeManifest.setNew(false);
1✔
92
            manifestRepository.addOrUpdate(activeManifest);
1✔
93
            saveReceivedManifest(receivedManifest);
1✔
94
            saveManifestVersion(receivedManifest.getVersion());
1✔
95
            saveFormsVersion(receivedManifest.getFormVersion());
1✔
96
        } else if (activeManifest == null) {
1✔
97
            saveReceivedManifest(receivedManifest);
1✔
98
            saveManifestVersion(receivedManifest.getVersion());
1✔
99
            saveFormsVersion(receivedManifest.getFormVersion());
1✔
100
        }
101
    }
1✔
102

103
    @VisibleForTesting
104
    protected void saveManifestVersion(@NonNull String manifestVersion) {
105
        boolean manifestVersionSaved = CoreLibrary.getInstance()
1✔
106
                .context()
1✔
107
                .allSharedPreferences()
1✔
108
                .saveManifestVersion(manifestVersion);
1✔
109
        if (!manifestVersionSaved) {
1✔
110
            Timber.e(new Exception("Saving manifest version failed"));
×
111
        }
112
    }
1✔
113

114
    @VisibleForTesting
115
    protected void saveFormsVersion(@NonNull String formsVersion) {
116
        boolean manifestVersionSaved = CoreLibrary.getInstance()
1✔
117
                .context()
1✔
118
                .allSharedPreferences()
1✔
119
                .saveFormsVersion(formsVersion);
1✔
120
        if (!manifestVersionSaved) {
1✔
121
            Timber.e(new Exception("Saving manifest version failed"));
×
122
        }
123
    }
1✔
124

125
    protected void syncClientForms(Manifest activeManifest) {
126
        //Fetching Client Forms for identifiers in the manifest
127
        for (String identifier : activeManifest.getIdentifiers()) {
1✔
128
            try {
129
                ClientForm clientForm = clientFormRepository.getLatestFormByIdentifier(identifier);
1✔
130
                if (clientForm == null || !clientForm.getVersion().equals(activeManifest.getFormVersion())) {
1✔
131
                    fetchClientForm(identifier, activeManifest.getFormVersion(), clientFormRepository.getActiveClientFormByIdentifier(identifier));
1✔
132
                }
133
            } catch (Exception e) {
×
134
                Timber.e(e);
×
135
            }
1✔
136
        }
1✔
137
    }
1✔
138

139
    protected void fetchClientForm(String identifier, String formVersion, ClientForm latestClientForm) throws NoHttpResponseException {
140
        if (httpAgent == null) {
1✔
141
            throw new IllegalArgumentException(CLIENT_FORM_SYNC_URL + " http agent is null");
×
142
        }
143

144
        String baseUrl = getBaseUrl();
1✔
145
        Response resp = httpAgent.fetch(
1✔
146
                MessageFormat.format("{0}{1}{2}",
1✔
147
                        baseUrl, CLIENT_FORM_SYNC_URL,
148
                        "?" + FORM_IDENTIFIER + "=" + identifier +
149
                                "&" + FORM_VERSION + "=" + formVersion +
150
                                (latestClientForm == null ? "" : "&" + CURRENT_FORM_VERSION + "=" + latestClientForm.getVersion())));
1✔
151

152
        if (resp.isFailure()) {
1✔
153
            throw new NoHttpResponseException(CLIENT_FORM_SYNC_URL + " not returned data");
×
154
        }
155

156
        Gson gson = new GsonBuilder().setDateFormat("MMM dd, yyyy, hh:mm:ss aaa").create();
1✔
157
        ClientFormResponse clientFormResponse =
1✔
158
                gson.fromJson(resp.payload().toString(), ClientFormResponse.class);
1✔
159

160
        if (clientFormResponse == null) {
1✔
161
            throw new NoHttpResponseException(CLIENT_FORM_SYNC_URL + " not returned data");
×
162
        }
163

164
        if (latestClientForm == null || !clientFormResponse.getClientFormMetadata().getVersion().equals(latestClientForm.getVersion())) {
1✔
165
            //if the previously active client form is not null it should be untagged from being new nor active
166
            if (latestClientForm != null) {
1✔
167
                latestClientForm.setActive(false);
×
168
                latestClientForm.setNew(false);
×
169
                clientFormRepository.addOrUpdate(latestClientForm);
×
170
            }
171
            ClientForm clientForm = convertClientFormResponseToClientForm(clientFormResponse);
1✔
172
            saveReceivedClientForm(clientForm);
1✔
173
        }
174
    }
1✔
175

176
    protected ClientForm convertClientFormResponseToClientForm(ClientFormResponse clientFormResponse) {
177
        ClientForm clientForm = new ClientForm();
1✔
178
        clientForm.setId(clientFormResponse.getClientForm().getId());
1✔
179
        clientForm.setCreatedAt(clientFormResponse.getClientFormMetadata().getCreatedAt());
1✔
180
        clientForm.setIdentifier(clientFormResponse.getClientFormMetadata().getIdentifier());
1✔
181

182
        String jsonString = StringEscapeUtils.unescapeJson(clientFormResponse.getClientForm().getJson());
1✔
183
        jsonString = jsonString.substring(1, jsonString.length() - 1); //TODO DO NOT REMOVE this necessary evil; necessary because the unescaped json String still contains " at the beginning and end of the string making it not a valid json string
1✔
184

185
        clientForm.setJson(jsonString);
1✔
186
        clientForm.setVersion(clientFormResponse.getClientFormMetadata().getVersion());
1✔
187
        clientForm.setLabel(clientFormResponse.getClientFormMetadata().getLabel());
1✔
188
        clientForm.setJurisdiction(clientFormResponse.getClientFormMetadata().getJurisdiction());
1✔
189
        clientForm.setModule(clientFormResponse.getClientFormMetadata().getModule());
1✔
190

191
        return clientForm;
1✔
192
    }
193

194
    private void saveReceivedManifest(Manifest receivedManifest) {
195
        receivedManifest.setNew(true);
1✔
196
        receivedManifest.setActive(true);
1✔
197
        manifestRepository.addOrUpdate(receivedManifest);
1✔
198

199
        //deleting the third oldest manifest from the repository
200
        List<Manifest> manifestsList = manifestRepository.getAllManifests();
1✔
201
        if (manifestsList.size() > 2) {
1✔
202
            manifestRepository.delete(manifestsList.get(2).getId());
×
203
        }
204
    }
1✔
205

206
    private void saveReceivedClientForm(ClientForm clientForm) {
207
        clientForm.setNew(true);
1✔
208
        clientForm.setActive(true);
1✔
209
        clientFormRepository.addOrUpdate(clientForm);
1✔
210

211
        //deleting the third oldest client Form from the repository
212
        List<ClientFormContract.Model> clientFormList = clientFormRepository.getClientFormByIdentifier(clientForm.getIdentifier());
1✔
213
        if (clientFormList.size() > 2) {
1✔
214
            clientFormRepository.delete(clientFormList.get(2).getId());
×
215
        }
216
    }
1✔
217

218
    protected Manifest convertManifestDTOToManifest(ManifestDTO manifestDTO) throws JSONException {
219
        Manifest manifest = new Manifest();
1✔
220
        manifest.setVersion(manifestDTO.getIdentifier());
1✔
221
        manifest.setAppVersion(manifestDTO.getAppVersion());
1✔
222
        manifest.setCreatedAt(manifestDTO.getCreatedAt());
1✔
223

224
        JSONObject json = new JSONObject(manifestDTO.getJson());
1✔
225
        if (json.has(MANIFEST_FORMS_VERSION)) {
1✔
226
            manifest.setFormVersion(json.getString(MANIFEST_FORMS_VERSION));
1✔
227
        }
228

229
        if (json.has(IDENTIFIERS)) {
1✔
230
            List<String> identifiers = new Gson().fromJson(json.getJSONArray(IDENTIFIERS).toString(),
1✔
231
                    new TypeToken<List<String>>() {
1✔
232
                    }.getType());
1✔
233
            manifest.setIdentifiers(identifiers);
1✔
234
        }
235
        return manifest;
1✔
236

237
    }
238

239
    private String getBaseUrl(){
240
        String baseUrl = configuration.dristhiBaseURL();
1✔
241
        String endString = "/";
1✔
242
        if (baseUrl.endsWith(endString)) {
1✔
243
            baseUrl = baseUrl.substring(0, baseUrl.lastIndexOf(endString));
×
244
        }
245
        return baseUrl;
1✔
246
    }
247

248
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc