Configure the Job Function

Next, we’ll begin coding the news application by configuring the job function component.

The function’s directory, in this case functions/NewsFetch, contains:

  • The FetchNews.java main function file
  • The catalyst-config.json configuration file
  • Java library files in the lib folder
  • .classpath and .project dependency files

We will be adding code in the FetchNews.java file. You will not be modifying the code of the configuration and dependency files.

As mentioned in the introduction, the job function performs two tasks: making the API calls to the NewsAPI to fetch news, populating the news in Catalyst Data Store. The API calls are made using an API key provided by NewsAPI.

Register with NewsAPI

Before you code the job function, you must register for a free developer subscription with NewsAPI and obtain the API key in the following way:

  1. Visit https://newsapi.org/register.

  2. Provide the required details and click Submit. register-api-key

After your registration is complete, NewsAPI will provide you with an API key. You must use this in your cron function, as instructed after the code section.

api-key

Add Function Code

You can copy the code below and paste it in FetchNews.java located in the functions/NewsFetch directory of your project and save the file. You can use any IDE to work with the application’s files.

Note: Please go through the code given in this section to make sure you fully understand it.
FetchNews.java
copy
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.catalyst.Context;
import com.catalyst.job.JOB_STATUS;
import com.catalyst.job.JobRequest;
import com.catalyst.job.CatalystJobHandler;
import com.zc.common.ZCProject;
import com.zc.component.object.ZCObject;
import com.zc.component.object.ZCRowObject;
import com.zc.component.object.ZCTable;
import com.zc.component.zcql.ZCQL;
import org.json.JSONArray;
import org.json.JSONObject;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class FetchNews implements CatalystJobHandler {
    private static final Logger LOGGER = Logger.getLogger(FetchNews.class.getName());
    // Table names for each category
    static String[] TABLENAME = { "HEADLINES", "BUSINESS", "ENTERTAINMENT", "HEALTH", "SCIENCE", "SPORTS", "TECHNOLOGY" };
    static String COUNTRY = "US"; 
    static String APIKEY = "cc30ddcae1684e848f08ed474f6aaf0e"; // Provide the API key you obtained from NewsAPI inside the quotations
    @Override
    public JOB_STATUS handleJobExecute(JobRequest request, Context context) throws Exception {
        try {
            ZCProject.initProject();
            OkHttpClient client = new OkHttpClient();
            // Fetch news for each category
            for (int i = 0; i < TABLENAME.length; i++) {
                HttpUrl.Builder urlBuilder = HttpUrl.parse("http://newsapi.org/v2/top-headlines").newBuilder();
                urlBuilder.addQueryParameter("country", COUNTRY);
                urlBuilder.addQueryParameter("apiKey", APIKEY);
                if (!TABLENAME[i].equals("HEADLINES")) {
                    urlBuilder.addQueryParameter("category", TABLENAME[i]);
                }
                String url = urlBuilder.build().toString();
                Request requests = new Request.Builder().url(url).build();
                Response response = client.newCall(requests).execute();
                if (response.code() == 200) {
                    JSONObject responseObject = new JSONObject(response.body().string());
                    JSONArray responseArray = responseObject.getJSONArray("articles");
                    pushNewstoDatastore(responseArray, i);
                } else {
                    LOGGER.log(Level.SEVERE, "Error fetching data from News API for " + TABLENAME[i]);
                }
                LOGGER.log(Level.INFO, "News updated for " + TABLENAME[i]);
            }
        } catch (Exception e) {
            LOGGER.log(Level.SEVERE, "Exception in Job Function", e);
            return JOB_STATUS.FAILURE;
        }
        return JOB_STATUS.SUCCESS;
    }
    private void pushNewstoDatastore(JSONArray responseArray, int length) throws Exception {
        String action = null;
        String query = "select ROWID from " + TABLENAME[length];
        ArrayList<ZCRowObject> rowList = ZCQL.getInstance().executeQuery(query);
        ZCObject object = ZCObject.getInstance();
        ZCTable table = object.getTable(TABLENAME[length]);
        // Loop safely through available articles (max 15)
        for (int i = 0; i < responseArray.length() && i < 15; i++) {
            JSONObject response = responseArray.getJSONObject(i);
            String title = response.optString("title", "No Title").replaceAll("'", "");
            String url = response.optString("url", "No URL");
            ZCRowObject row = ZCRowObject.getInstance();
            row.set("title", title);
            row.set("url", url);
            if (rowList.size() > i) {
                String rowid = rowList.get(i).get("ROWID").toString();
                Long ID = Long.parseLong(rowid);
                row.set("ROWID", ID);
                String upd = "Update " + TABLENAME[length] +
                             " set title = '" + title + "', url = '" + url + "' where ROWID = " + rowid;
                ZCQL.getInstance().executeQuery(upd);
                action = "Update";
            } else {
                table.insertRow(row);
                action = "Insert";
            }
        }
        if ("Update".equals(action)) {
            LOGGER.log(Level.INFO, TABLENAME[length] + " table updated with latest news");
        } else if ("Insert".equals(action)) {
            LOGGER.log(Level.INFO, TABLENAME[length] + " table inserted with new news");
        }
    }
}

View more

Note: After you copy and paste this code in your function file, ensure that you replace value of APIKEY in the line 26 with the API key you obtained from NewsAPI.

The job function is now configured. We will discuss the application’s architecture after we configure the client.

Last Updated 2025-10-21 12:04:01 +0530 IST