JEF: Getting Started

This is a beginners guide to the Job Execution Framework.

We have provided the flex-jefexecutorexample-service project as a simple example of the possible scenarios available for the JEF Executor implementation. For more information on how to access this project in BitBucket, please contact your Ooyala representative.

What is JEF?

The Job Execution Framework (JEF) lets you extend the Ooyala Flex platform, by allowing you to create your own action and resource plugins and then run them in their own microservices.

Once an action plugin has been deployed, it appears in the list of existing actions in the Ooyala Flex console, ready for people to make use of.

Step 1: Setting up the Framework

To set up the framework for JEF, you must do the following:

1) Install Docker: guides for installing Docker can be found here:

2) Acquire a login to the docker registry. Please contact the Ooyala Flex DevOps team at the following address: flex-ops@ooyala.com to acquire this information. Once you have obtained this information, you can use the docker login registry.ooflex.net command to log in.

3) Clone the following repo: ssh://git@git.corp.ooyala.com:7999/flex/flex-jefexampleexecutor-service.git

In this repo you will find an example JEF project. You can use this example as a basis for your own JEF project.

4) Configure the dynamic FLEX_IP value by running the bash_profile (in MAC), after setting the FLEX_IP property: export FLEX_IP= `ifconfig | grep -Eo 'inet (addr:)?([0-9].){3}[0-9]' | grep -Eo '([0-9].){3}[0-9]' | grep -v '127.0.0.1' | grep -v '192.168.1'

5) Add the following entries in your host file, in order to run the Consul and Enterprise services:

127.0.0.1 localhost
Note: Additionally you will need a similar configuration to connect to the Enterprise site: mysqlworkflowengine masteraccount.local.nativ.tv newaccount.local.nativ.tv account01.local.nativ.tv mio-proft account02.local.nativ.tv mysqlhost dockermachine consul

Step 2: Creating the Action Configuration

In this section you will learn how to create configuration fields for action plugins.

The majority of the plugins found in Ooyala Flex require you to populate configuration fields. In most cases, there are mandatory fields that must be filled out in order for the plugin to function correctly. These are found under the Configuration tab when you view a plugin in the Ooyala Flex UI.

Example: Clicking the Configuration tab for a Send Email action in Ooyala Flex reveals a number of fields that are essential to the running of the plugin.

Defining the Action Configuration

Below we will look at what is required for each configuration field you wish to create.

To begin creating the configuration for the plugin, you must create a class that implements the following:

com.ooyala.flex.jobexecutor.model.action.ActionConfiguration.java

Example: You could create a “Send Email” action. This action could contain the following fields: Recipient's Email, Subject, and Message.

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor

@JsonInclude(JsonInclude.Include.ALWAYS)
@ActionPluginConfiguration(async = true, description = "Email details needed by the Notification-Email-Action")
public class EmailActionConfiguration implements ActionConfiguration {

    @ConfigField(
            displayName = "Recipent's Email",
            description = "Person to receive email",
            required = true)
    private String recipientEmail;

    @ConfigField(
            displayName = "Subject",
            description = "Email subject line",
            required = true)
    private String subject;

    @ConfigField(
            displayName = "Message",
            description = "Email's body",
            required = true)
    private String body;

}	

You can design the configuration of a plugin using the metadata annotations provided as part of JEF (these are effectively Ooyala Flex metadata definitions). These annotations provide solutions to define native, primitive, and complex fields.

Example: In a transcode plugin you might see a complex called “Destination”. Within the “Destination” complex you would find destination related fields such as: Folder Resource, VFS Location, Protocol, Hostname, and so on.

Step 3: Creating an Action Executor

In this section you will learn how to create an action executor. An action executor is an abstract class that must be extended in order to process the action request. It takes an instance of the ActionConfiguration as a parameter, in order to expose the configuration of the action plugin at the moment of execution.

Note: The logic that is executed by the action executor must be written within the execute method.

Example:

@Override
    public ActionExecutorResponse execute() {

        log.info("JEF Example external email action started execution for job");
        EmailExternalActionConfiguration emailActionConfiguration = (EmailExternalActionConfiguration) actionConfiguration;

        ...

        // Sends email
        emailUtils.sendEmail(emailActionConfiguration.getRecipientEmail(), emailActionConfiguration.getSubject(),
                emailActionConfiguration.getBody());

        // Create instance to send job progress
        EmailActionProgress emailExternalActionProgress = new EmailActionProgress( this, emailJobService);

        // Add observer for progress notification
        emailExternalActionProgress.addObserver(this);

        CompletableFuture<Void> completableFuture = actionProgressService.poll(emailExternalActionProgress, this);

        try {
            // Wait for completing action, Later in future, we won't wait here to job get completed.
            completableFuture.get();
        }
        catch (Exception e) {
            throw new ActionExecutorException(e);
        }

        // As we have got the response by now, just delete it from observer list
        emailExternalActionProgress.deleteObserver(this);

        log.info("JEF Example external email action done");

        return new ActionExecutorResponse();
    }

Step 3.1: ActionProgressService and EmailActionProgress

Note: This is a purely a suggestion for how progress could be handled, in order to report updates back to Enterprise and track execution until the job completes. You (as the developer) are free to choose an implementation that suits your needs.

In order to update a job’s status, you must implement the ActionProgress class. In this class there are two methods:

  • execute
  • isJobCompleted

execute(): the execute() method retrieves a progress update from a running job, and notifies the Job Async Executor service provider with the progress.

isJobCompleted: the criteria is called from the ActionProgressService class in order to define when the async job has been completed.

Note: You must invoke the Observable method in the setChanged superclass at the end of the execute method. You must then call notifyObservers. This takes the ActionExecutorUpdate, wraps it in the message queue, and sends the update back to Enterprise or any other client using JEF.

Example:

setChanged(); notifyObservers(actionExecutorUpdate);
Note: In the example above, the observers have been notified with a ActionExecutorUpdate instance. This class contains a field called “status” You can set the status field to have any status you wish, depending on the progress of the job.
https://help.ooyala.com/sites/all/libraries/dita/en/media-logistics/flex/dev/70/jef_programming_guide_getting_started.html

Was this article helpful?