AFG-Polio-Data / APMIS-Project

APMIS (Afghanistan Polio Management Information System) is an supplemental Immunization Activities management system to manage the vaccination activities in the country.
https://test.afghanistan-apmis.com
GNU General Public License v3.0
4 stars 7 forks source link

Java activated CRON-JOB for RDS (R Data Serialization) data store automatic update for R shiny app #562

Closed danieltomabba closed 6 months ago

danieltomabba commented 8 months ago

BACKGROUND The R shiny app process utilizes the .RDS file as a data store for displaying all dashboard outputs. Currently, the RDS file is manually uploaded to the Ubuntu server specified directory that the shiny app pulls its content. We have two files for this CRON-JOB.

  1. get_apmis_data.R (See file details here https://github.com/AFG-Polio-Data/R/blob/dev/get_apmis_data/get_apmis_data.R)
  2. get_apmis_data_utils.R (https://github.com/AFG-Polio-Data/R/blob/dev/get_apmis_data/get_apmis_data_utils.R) These files are utilized to generate the new data added to the database after each campaign. The get_apmis_data.R script runs the get_apmis_data_utils file which connects to the PostgreSQL database and pulls all the tables cleans the data and outputs to a new RDS file called "clean_apmis_data.Rds" which would contain all the cleaned tables with the respective data sets.

REQUEST We would like Cinotech to create a CRON-JOB service that would automatically run get_apmis_data.R every hour to update the data store and output the new RDS file in the specified directory that Shiny app pulls its resources from.

REQUIREMENTS There is no need for prior knowledge of R to be able to complete this task. We just need Java to automatically run the R script provided the correct PostgreSQL database credentials are authenticated and the result should be a new RDS file stored in the specified directory.

CODE REFERENCES Step 1: Create a Java Class to Run the R Script First, you'll need to create a Java class that can run the R script. You can use the ProcessBuilder class to execute shell commands.


import java.io.*;

public class RunRScript {
    public static void main(String[] args) {
        try {
            ProcessBuilder pb = new ProcessBuilder("Rscript", "path/to/get_apmis_data.R");
            Process p = pb.start();
            BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String s;
            while ((s = in.readLine()) != null) {
                System.out.println(s);
            }
            int status = p.waitFor();
            System.out.println("Exited with status: " + status);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Step 2: Set Up PostgreSQL DB Connection in R Script In your get_apmis_data.R script, you can use the DBI and RPostgres packages to connect to the PostgreSQL database.


library(DBI)
library(RPostgres)

con <- dbConnect(RPostgres::Postgres(),
                 dbname = "your_db_name",
                 host = "your_host",
                 port = 5432,
                 user = "your_username",
                 password = "your_password")

# Your data fetching and processing logic here

dbDisconnect(con)

Step 3: Create a CRON-JOB Service You can use the ScheduledExecutorService in Java to run the R script at regular intervals.


import java.util.concurrent.*;

public class App {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(new RunRScript(), 0, 1, TimeUnit.HOURS);
    }
}

Step 4: Compile and Run Your Java Program Compile your Java program and then run it. This will execute the R script every hour.


javac RunRScript.java App.java
java App

Step 5: Set Up Output Directory in R Script Make sure your R script outputs the RDS file to the directory from which your Shiny app reads its resources.


saveRDS(your_data, "path/to/shiny/app/resources/your_file.rds")
bnygren commented 6 months ago

Will be handled by @danieltomabba and @lbaertlein1