Skip to content

Commit

Permalink
Test run workmanager
Browse files Browse the repository at this point in the history
- SyncAllLocations
- Campaign
  • Loading branch information
LZRS committed Sep 9, 2022
1 parent 9b385bf commit b7a5006
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 0 deletions.
8 changes: 8 additions & 0 deletions opensrp-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,14 @@ dependencies {
compileOnly 'com.google.firebase:firebase-perf'
// Add the dependency for the Performance Monitoring library

// WorkManager
def work_version = "2.7.1"
implementation "androidx.work:work-runtime:$work_version"
implementation "androidx.work:work-gcm:$work_version"
implementation "androidx.work:work-multiprocess:$work_version"
implementation "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava"
testImplementation "androidx.work:work-testing:$work_version"

//Mockito
def mockitoVersion = '4.6.1'
testImplementation("org.mockito:mockito-core:$mockitoVersion")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.smartregister.sync.wm.worker

import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import org.joda.time.DateTime
import org.joda.time.LocalDate
import org.smartregister.AllConstants
import org.smartregister.CoreLibrary
import org.smartregister.domain.Campaign
import org.smartregister.domain.FetchStatus
import org.smartregister.exception.NoHttpResponseException
import org.smartregister.service.HTTPAgent
import org.smartregister.util.DateTimeTypeConverter
import org.smartregister.util.DateTypeConverter
import org.smartregister.util.Utils
import org.smartregister.util.WorkerNotificationDelegate
import timber.log.Timber

class CampaignWorker(context: Context, workerParams: WorkerParameters) :
Worker(context, workerParams) {

private val notificationDelegate = WorkerNotificationDelegate(context, TAG)

override fun doWork(): Result {
notificationDelegate.notify("Running \u8086")

val opensrpContext = CoreLibrary.getInstance().context()
val baseUrl = opensrpContext.configuration().dristhiBaseURL()
val allSharedPreferences = opensrpContext.allSharedPreferences()
val campaignRepository = opensrpContext.campaignRepository
val httpAgent = opensrpContext.httpAgent
return try {
val campaignsResponse = fetchCampaigns(httpAgent, baseUrl)
val allowedCampaigns = allSharedPreferences.getPreference(AllConstants.CAMPAIGNS).split(",")
val campaigns = gson.fromJson<List<Campaign>>(
campaignsResponse,
object : TypeToken<List<Campaign?>?>() {}.type
)
val errors = mutableListOf<Throwable>()
campaigns.filter { it.identifier != null && it.identifier in allowedCampaigns }
.forEach {
runCatching { campaignRepository.addOrUpdate(it)}.onFailure { e -> errors.add(e) }
}
if (errors.isNotEmpty()) throw Exception(errors.random())
Result.success().apply {
notificationDelegate.notify("Success!!")
}
} catch (e: Exception) {
Timber.e(e)
Result.failure().apply {
notificationDelegate.notify("Error: ${e.message}")
}
}
}

fun getUrl(baseUrl: String): String {
val endString = "/"
return "${if (baseUrl.endsWith(endString)) baseUrl.substring(0, baseUrl.lastIndexOf(endString)) else baseUrl}$CAMPAIGN_URL"
}

@Throws(NoHttpResponseException::class)
fun fetchCampaigns(httpAgent: HTTPAgent?, baseUrl: String): String {
if (httpAgent == null) {
applicationContext.sendBroadcast(Utils.completeSync(FetchStatus.noConnection))
throw IllegalArgumentException("$CAMPAIGN_URL http agent is null")
}
val resp= httpAgent.fetch(getUrl(baseUrl))
if (resp.isFailure) {
applicationContext.sendBroadcast(Utils.completeSync(FetchStatus.nothingFetched))
throw NoHttpResponseException("$CAMPAIGN_URL not returned data")
}
return resp.payload().toString()
}

companion object{
const val CAMPAIGN_URL = "/rest/campaign/"
const val TAG = "CampaignWorker"
val gson: Gson = GsonBuilder().registerTypeAdapter(
DateTime::class.java,
DateTimeTypeConverter("yyyy-MM-dd'T'HHmm")
)
.registerTypeAdapter(LocalDate::class.java, DateTypeConverter()).create()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.smartregister.sync.wm.worker

import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import org.smartregister.sync.helper.LocationServiceHelper
import org.smartregister.util.WorkerNotificationDelegate
import timber.log.Timber

class SyncAllLocationsWorker(context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {

private val notificationDelegate = WorkerNotificationDelegate(context, TAG)

override fun doWork(): Result {
val locationServiceHelper = LocationServiceHelper.getInstance()

return try {
notificationDelegate.notify("Running \u8086")
locationServiceHelper.fetchAllLocations().runCatching { }
Result.success().apply {
notificationDelegate.notify("Success!!")
}
} catch (e: Exception) {
Timber.e(e)
Result.failure().apply {
notificationDelegate.notify("Error: ${e.message}")
}
}
}

companion object{
const val TAG = "SyncAllLocationsWorker"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.smartregister.sync.wm.workerrequest

import android.content.Context
import android.os.Build
import androidx.work.Constraints
import androidx.work.Data
import androidx.work.ListenableWorker
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import org.smartregister.sync.wm.worker.SyncAllLocationsWorker


object OneTimeWorkRequest {

fun runTask(context: Context, workerClass: Class<out ListenableWorker>) {
val inputData: Data = Data.Builder()
.putString("key", "value")
.build()
val constraintsBuilder = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.setRequiresBatteryNotLow(false)
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M){
constraintsBuilder.setRequiresDeviceIdle(false)
}
val constraints: Constraints = constraintsBuilder.build()
val request = OneTimeWorkRequest.Builder(workerClass)
.setInputData(inputData)
.setConstraints(constraints)
.build()
WorkManager.getInstance(context).enqueue(request)
}

}
53 changes: 53 additions & 0 deletions opensrp-core/src/main/java/org/smartregister/util/WorkerUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.smartregister.util

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import org.smartregister.R
import kotlin.random.Random


object WorkerUtils {
private const val CHANNEL_ID = "org.smartregisterx"
private const val CHANNEL_NAME = "OpenSRP"
private const val CHANNEL_DESC = "OpenSRP Client"

fun makeStatusNotification(
context: Context,
notificationId: Int,
title: String?,
message: String?
) {
val notificationManager = NotificationManagerCompat.from(context)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_LOW
)
channel.description = CHANNEL_DESC
notificationManager.createNotificationChannel(channel)
}
val builder: NotificationCompat.Builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.drawable.ic_opensrp_logo)
.setPriority(NotificationCompat.PRIORITY_LOW)
notificationManager.notify(notificationId, builder.build())
}

fun dismissNotification(context: Context, notificationId: Int){
NotificationManagerCompat.from(context).cancel(notificationId)
}
}

class WorkerNotificationDelegate(private val context: Context,
private val title: String?){
private val notificationId: Int = Random.nextInt()
fun notify(message: String){
WorkerUtils.makeStatusNotification(context, notificationId, title, message)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.joda.time.LocalDate;
import org.smartregister.cursoradapter.SmartRegisterQueryBuilder;
import org.smartregister.sample.fragment.ReportFragment;
import org.smartregister.sync.wm.worker.SyncAllLocationsWorker;
import org.smartregister.sync.wm.workerrequest.OneTimeWorkRequest;
import org.smartregister.util.AppHealthUtils;
import org.smartregister.util.DateUtil;
import org.smartregister.util.LangUtils;
Expand Down Expand Up @@ -140,6 +142,11 @@ public void onNothingSelected(AdapterView<?> parent) {
((TextView) findViewById(R.id.time)).setText(DateUtil.getDuration(new DateTime().minusYears(4).minusMonths(3).minusWeeks(2).minusDays(1)));

new AppHealthUtils(findViewById(R.id.show_sync_stats));
findViewById(R.id.wmSync).setOnClickListener(v -> {
v.setVisibility(View.INVISIBLE);
OneTimeWorkRequest.INSTANCE
.runTask(getApplicationContext(), SyncAllLocationsWorker.class);
});
}

@Override
Expand Down
8 changes: 8 additions & 0 deletions sample/src/main/res/layout-v17/content_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,12 @@

</LinearLayout>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/sync_stats_layout"
android:layout_centerHorizontal="true"
android:id="@+id/wmSync"
android:text="Run Sync locations" />

</RelativeLayout>
8 changes: 8 additions & 0 deletions sample/src/main/res/layout/content_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,12 @@

</LinearLayout>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/sync_stats_layout"
android:layout_centerHorizontal="true"
android:id="@+id/wmSync"
android:text="Run Sync locations" />

</RelativeLayout>

0 comments on commit b7a5006

Please sign in to comment.