Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ MasterDataSyncApi getSyncResponseApi(
AuditManagerService auditManagerService,
MasterDataService masterDataService,
PacketService packetService,
GlobalParamDao globalParamDao, FileSignatureDao fileSignatureDao,PreRegistrationDataSyncService preRegistrationDataSyncService) {
GlobalParamDao globalParamDao, FileSignatureDao fileSignatureDao,PreRegistrationDataSyncService preRegistrationDataSyncService, LocalConfigService localConfigService) {
return new MasterDataSyncApi(clientCryptoManagerService,
machineRepository, registrationCenterRepository,
syncRestService, certificateManagerService,
Expand All @@ -209,7 +209,7 @@ MasterDataSyncApi getSyncResponseApi(
templateRepository, dynamicFieldRepository,
locationRepository, blocklistedWordRepository,
syncJobDefRepository, languageRepository, jobManagerService,
auditManagerService, masterDataService, packetService, globalParamDao, fileSignatureDao, preRegistrationDataSyncService
auditManagerService, masterDataService, packetService, globalParamDao, fileSignatureDao, preRegistrationDataSyncService, localConfigService
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,27 @@ public void onReceive(Context context, Intent intent) {
}
};

private BroadcastReceiver rescheduleReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String jobApiName = intent.getStringExtra(UploadBackgroundService.EXTRA_JOB_API_NAME);
if (jobApiName != null) {
Log.d(getClass().getSimpleName(), "Rescheduling job due to cron change: " + jobApiName);
createBackgroundTask(jobApiName);
}
}
};

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// createBackgroundTask("registrationPacketUploadJob");
IntentFilter intentFilterUpload = new IntentFilter("SYNC_JOB_TRIGGER");
registerReceiver(broadcastReceiver, intentFilterUpload);

// Register receiver for rescheduling jobs when cron expression changes
IntentFilter rescheduleFilter = new IntentFilter("RESCHEDULE_JOB");
registerReceiver(rescheduleReceiver, rescheduleFilter);
}

private void initializeAutoSync() {
Expand Down Expand Up @@ -264,6 +279,11 @@ void scheduleAllActiveJobs() {
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
try {
unregisterReceiver(rescheduleReceiver);
} catch (Exception e) {
// Receiver might not be registered, ignore
}
}

public void createBackgroundTask(String api){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,12 @@
import io.mosip.registration.clientmanager.service.JobManagerServiceImpl;
import io.mosip.registration.clientmanager.spi.AuditManagerService;
import io.mosip.registration.clientmanager.spi.JobManagerService;
import io.mosip.registration.clientmanager.spi.LocalConfigService;
import io.mosip.registration.clientmanager.spi.MasterDataService;
import io.mosip.registration.clientmanager.spi.PacketService;
import io.mosip.registration.clientmanager.spi.PreRegistrationDataSyncService;
import io.mosip.registration.clientmanager.spi.SyncRestService;
import io.mosip.registration.clientmanager.util.CronExpressionParser;
import io.mosip.registration.keymanager.spi.CertificateManagerService;
import io.mosip.registration.keymanager.spi.ClientCryptoManagerService;
import io.mosip.registration_client.utils.BatchJob;
Expand Down Expand Up @@ -100,6 +102,7 @@ public class MasterDataSyncApi implements MasterDataSyncPigeon.SyncApi {
GlobalParamDao globalParamDao;
FileSignatureDao fileSignatureDao;
PreRegistrationDataSyncService preRegistrationDataSyncService;
LocalConfigService localConfigService;
Context context;
private String regCenterId;

Expand All @@ -120,7 +123,7 @@ public MasterDataSyncApi(ClientCryptoManagerService clientCryptoManagerService,
AuditManagerService auditManagerService,
MasterDataService masterDataService,
PacketService packetService,
GlobalParamDao globalParamDao, FileSignatureDao fileSignatureDao, PreRegistrationDataSyncService preRegistrationDataSyncService) {
GlobalParamDao globalParamDao, FileSignatureDao fileSignatureDao, PreRegistrationDataSyncService preRegistrationDataSyncService, LocalConfigService localConfigService) {
this.clientCryptoManagerService = clientCryptoManagerService;
this.machineRepository = machineRepository;
this.registrationCenterRepository = registrationCenterRepository;
Expand All @@ -146,6 +149,7 @@ public MasterDataSyncApi(ClientCryptoManagerService clientCryptoManagerService,
this.globalParamDao = globalParamDao;
this.fileSignatureDao = fileSignatureDao;
this.preRegistrationDataSyncService = preRegistrationDataSyncService;
this.localConfigService = localConfigService;
}

public void setCallbackActivity(MainActivity mainActivity, BatchJob batchJob) {
Expand Down Expand Up @@ -432,6 +436,70 @@ public void getActiveSyncJobs(@NonNull MasterDataSyncPigeon.Result<List<String>>
result.success(value);
}

@Override
public void getPermittedJobs(@NonNull MasterDataSyncPigeon.Result<List<String>> result) {
try {
List<String> permittedJobs = localConfigService.getPermittedJobs();
result.success(permittedJobs != null ? permittedJobs : new ArrayList<>());
} catch (Exception e) {
Log.e(TAG, "Failed to get permitted jobs", e);
result.error(e);
}
}

@Override
public void isValidCronExpression(@NonNull String cronExpression, @NonNull MasterDataSyncPigeon.Result<Boolean> result) {
try {
boolean isValid = CronExpressionParser.isValidCronExpression(cronExpression);
result.success(isValid);
} catch (Exception e) {
Log.e(TAG, "Error validating cron expression", e);
result.success(false);
}
}

@Override
public void modifyJobCronExpression(@NonNull String jobId, @NonNull String cronExpression, @NonNull MasterDataSyncPigeon.Result<Boolean> result) {
try {
localConfigService.modifyJob(jobId, cronExpression);

// Fetch specific sync job definition by jobId
SyncJobDef jobDef = syncJobDefRepository.getSyncJobDefById(jobId);

if (jobDef != null) {
// Refresh job status to apply new cron expression
// This will reschedule JobScheduler jobs with new cron
jobManagerService.refreshJobStatus(jobDef);

// For AlarmManager-based jobs (like batch jobs), reschedule immediately
if (jobDef.getApiName() != null && activity != null) {
// Reschedule using MainActivity's createBackgroundTask via broadcast
Intent rescheduleIntent = new Intent("RESCHEDULE_JOB");
rescheduleIntent.putExtra(UploadBackgroundService.EXTRA_JOB_API_NAME, jobDef.getApiName());
context.sendBroadcast(rescheduleIntent);
Log.d(TAG, "Sent reschedule broadcast for job: " + jobDef.getApiName());
}
}

result.success(true);
} catch (Exception e) {
Log.e(TAG, "Failed to modify job cron expression", e);
result.error(e);
}
}

@Override
public void getValue(@NonNull String name, @NonNull MasterDataSyncPigeon.Result<String> result) {
try {
// getValue is used for retrieving job cron expressions, so use PERMITTED_JOB_TYPE
String value = localConfigService.getValue(name, RegistrationConstants.PERMITTED_JOB_TYPE);
result.success(value);
} catch (Exception e) {
Log.e(TAG, "Failed to get value for: " + name, e);
result.error(e);
}
}

// Execute job based on API name
public void executeJobByApiName(String jobApiName, Context context) {
new Thread(() -> {
Expand Down Expand Up @@ -518,11 +586,9 @@ public void executeJobByApiName(String jobApiName, Context context) {

private String getJobIdByApiName(String apiName) {
try {
List<SyncJobDef> jobs = syncJobDefRepository.getAllSyncJobDefList();
for (SyncJobDef job : jobs) {
if (apiName.equals(job.getApiName())) {
return job.getId();
}
SyncJobDef job = syncJobDefRepository.getSyncJobDefByApiName(apiName);
if (job != null) {
return job.getId();
}
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error getting job ID for: " + apiName, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
import io.mosip.registration.clientmanager.constant.Components;
import io.mosip.registration.clientmanager.constant.PacketClientStatus;
import io.mosip.registration.clientmanager.constant.PacketTaskStatus;
import io.mosip.registration.clientmanager.constant.RegistrationConstants;
import io.mosip.registration.clientmanager.dao.GlobalParamDao;
import io.mosip.registration.clientmanager.entity.GlobalParam;
import io.mosip.registration.clientmanager.entity.Registration;
import io.mosip.registration.clientmanager.entity.SyncJobDef;
import io.mosip.registration.clientmanager.repository.SyncJobDefRepository;
import io.mosip.registration.clientmanager.spi.AsyncPacketTaskCallBack;
import io.mosip.registration.clientmanager.spi.AuditManagerService;
import io.mosip.registration.clientmanager.spi.LocalConfigService;
import io.mosip.registration.clientmanager.spi.PacketService;
import io.mosip.registration_client.MainActivity;
import io.mosip.registration_client.R;
Expand All @@ -33,16 +35,19 @@ public class BatchJob {
AuditManagerService auditManagerService;
GlobalParamDao globalParamDao;
SyncJobDefRepository syncJobDefRepository;
LocalConfigService localConfigService;
Activity activity;
boolean syncAndUploadInProgressStatus = false;

@Inject
public BatchJob(PacketService packetService, AuditManagerService auditManagerService,
GlobalParamDao globalParamDao, SyncJobDefRepository syncJobDefRepository) {
GlobalParamDao globalParamDao, SyncJobDefRepository syncJobDefRepository,
LocalConfigService localConfigService) {
this.packetService = packetService;
this.auditManagerService = auditManagerService;
this.globalParamDao = globalParamDao;
this.syncJobDefRepository = syncJobDefRepository;
this.localConfigService = localConfigService;
}

public void setCallbackActivity(MainActivity mainActivity) {
Expand Down Expand Up @@ -203,12 +208,19 @@ public Integer getBatchSize() {
public long getIntervalMillis(String api) {
// Default everyday at Noon - 12pm
String cronExp = ClientManagerConstant.DEFAULT_UPLOAD_CRON;
List<SyncJobDef> syncJobs = syncJobDefRepository.getAllSyncJobDefList();
for (SyncJobDef value : syncJobs) {
if (Objects.equals(value.getApiName(), api)) {
Log.d(getClass().getSimpleName(), api + " Cron Expression : " + String.valueOf(value.getSyncFreq()));
cronExp = String.valueOf(value.getSyncFreq());
break;
SyncJobDef syncJob = syncJobDefRepository.getSyncJobDefByApiName(api);
if (syncJob != null) {
// Use default from DB first
cronExp = String.valueOf(syncJob.getSyncFreq());
Log.d(getClass().getSimpleName(), api + " Default Cron Expression : " + cronExp);

// Check for custom cron expression and override if available
if (localConfigService != null) {
String customCron = localConfigService.getValue(syncJob.getId(), RegistrationConstants.PERMITTED_JOB_TYPE);
if (customCron != null && !customCron.trim().isEmpty()) {
cronExp = customCron; // Use custom cron expression
Log.d(getClass().getSimpleName(), api + " Custom Cron Expression : " + cronExp);
}
}
}
long nextExecution = CronParserUtil.getNextExecutionTimeInMillis(cronExp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import io.mosip.registration.clientmanager.service.external.PreRegZipHandlingService;
import io.mosip.registration.clientmanager.service.external.impl.PreRegZipHandlingServiceImpl;
import io.mosip.registration.clientmanager.spi.AuditManagerService;
import io.mosip.registration.clientmanager.spi.LocalConfigService;
import io.mosip.registration.clientmanager.spi.JobManagerService;
import io.mosip.registration.clientmanager.spi.JobTransactionService;
import io.mosip.registration.clientmanager.spi.LocationValidationService;
Expand Down Expand Up @@ -259,8 +260,8 @@ DateUtil provideDateUtil() {

@Provides
@Singleton
JobManagerService provideJobManagerService(SyncJobDefRepository syncJobDefRepository, JobTransactionService jobTransactionService, DateUtil dateUtil) {
return new JobManagerServiceImpl(appContext, syncJobDefRepository, jobTransactionService, dateUtil);
JobManagerService provideJobManagerService(SyncJobDefRepository syncJobDefRepository, JobTransactionService jobTransactionService, DateUtil dateUtil, LocalConfigService localConfigService) {
return new JobManagerServiceImpl(appContext, syncJobDefRepository, jobTransactionService, dateUtil, localConfigService);
}

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,20 @@ public interface LocalConfigDAO {
*/
void modifyConfigurations(Map<String, String> localPreferences);

/**
* Get value for a specific local preference by name and config type
* @param name Preference name
* @param configType Configuration type (PERMITTED_JOB_TYPE or PERMITTED_CONFIG_TYPE)
* @return Preference value or null if not found
*/
String getValue(String name, String configType);

/**
* Modify job cron expression
* @param name Job ID
* @param value Cron expression value
*/
void modifyJob(String name, String value);

void cleanUpLocalPreferences();
}
Loading