0

I am trying to configure an Apache Oozie workflow to execute different actions depending on the day of the week. After reading https://stackoverflow.com/questions/71422257/oozie-coordinator-get-day-of-the-week, I am trying to develop a solution on my own.

I started by compiling this simple java source code:

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;

public class DatetimeProcessor {
    public static void main(String[] args) {
        String inputDate = args.length > 0 ? args[0] : "";
        String day = "";
        try {
            day = getDayOfWeek(inputDate);
        } catch (Exception e) {
            System.out.println("Invalid date format. Please enter a valid date in the format 'yyyy-MM-dd'T'HH:mm'Z'.");
        }
        System.out.println("dayOfWeek=" + day);
    }

    public static String getDayOfWeek(String date) {
        LocalDateTime dateTime = LocalDateTime.parse(date, DateTimeFormatter.ISO_DATE_TIME);
        DayOfWeek dayOfWeek = dateTime.atOffset(ZoneOffset.UTC).getDayOfWeek();
        return dayOfWeek.toString().substring(0, 3);
    }
}

After building the jar file, I wrote this Oozie coordinator:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<coordinator-app xmlns="uri:oozie:coordinator:0.5" name="mail-test" frequency="* * * * *" start="2024-11-11T00:00Z" end="2024-11-11T00:02Z" timezone="UTC">
    <action>
        <workflow>
            <app-path>/user/my.user.name</app-path>
            <configuration>
                <property>
                    <name>nominalTime</name>
                    <value>${coord:nominalTime()}</value>
                </property>
            </configuration>
        </workflow>
    </action>
</coordinator-app>

However, when I launch the following workflow:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workflow-app xmlns="uri:oozie:workflow:0.5" name="workflow-test">
    <parameters>
        <property>
            <name>nominalTime</name>
        </property>
    </parameters>
    <start to="process-date-action"/>

<action name="process-date-action">
    <java>
        <job-tracker>${jobTracker}</job-tracker>
        <name-node>${nameNode}</name-node>
        <main-class>DatetimeProcessor</main-class>
        <arg>${nominalTime}</arg>
        <file>${wf:appPath()}/DatetimeProcessor.jar</file>
        <capture-output/>
    </java>
    <ok to="mail-action"/>
    <error to="fail"/>
</action>

    <action name="mail-action">
        <email xmlns="uri:oozie:email-action:0.2">
            <to>[email protected]</to>
            <subject>Mail Test</subject>
            <body>
        Workflow id: ${wf:id()}
        Workflow usr: ${wf:user()}
        Timestamp: ${timestamp()}
        Coordinator nominalTime: ${nominalTime}
        Coordinator Day of the Week: ${wf:actionData("process-date-action")["dayOfWeek"]}
            </body>
        </email>
        <ok to="end"/>
        <error to="fail"/>
    </action>
    <kill name="fail">
        <message>Workflow failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
    </kill>
    <end name="end"/>
</workflow-app>

I do not see any output on the final e-mail after "Coordinator Day of the Week:". Did I badly use the capture output tag? Thank you in advance.

1
  • Unless you have to use Hadoop, I'd recommend Nifi or Airflow for something similar, but more modern Commented Nov 21 at 2:56

1 Answer 1

0

I found the solution by reading this topic:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Properties;

public class DatetimeProcessor {
    public static void main(String[] args) {
        String inputDate = args.length > 0 ? args[0] : "";
        String day = "";
        try {
            day = getDayOfWeek(inputDate);
        } catch (Exception e) {
            System.out.println("Invalid date format. Please enter a valid date in the format 'yyyy-MM-dd'T'HH:mm'Z'.");
        }
        System.out.println("dayOfWeek=" + day);
        
        // Write output to Oozie properties file
        try {
            File outputFile = new File(System.getProperty("oozie.action.output.properties"));
            FileOutputStream fos = new FileOutputStream(outputFile);
            Properties props = new Properties();
            props.setProperty("dayOfWeek", day);
            props.store(fos, "");
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getDayOfWeek(String date) {
        LocalDateTime dateTime = LocalDateTime.parse(date, DateTimeFormatter.ISO_DATE_TIME);
        DayOfWeek dayOfWeek = dateTime.atOffset(ZoneOffset.UTC).getDayOfWeek();
        return dayOfWeek.toString().substring(0, 3);
    }
}
1
  • 1
    It’s better to use try(FileOutputStream fos = new FileOutputStream(System.getProperty("oozie.action.output.properties"))) { Properties props = new Properties(); props.setProperty("dayOfWeek", day); props.store(fos, ""); } catch (IOException e) { e.printStackTrace(); } It’s simpler and closes the resource in the exceptional case. And I’m wondering if you really need a timezone conversion. You could call .getDayOfWeek() on the LocalDateTime directly or parse to DayOfWeek in the first place, DayOfWeek dayOfWeek = DateTimeFormatter.ISO_DATE_TIME.parse(date, DayOfWeek::from);
    – Holger
    Commented Nov 14 at 16:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.