Starting with Flex 2021.3.0, Flex has new JEF-based scripting actions, which should be used instead of the legacy ones.
The following Quickstart guide is designed to get an administrator setup and running with simple scripting in Dalet Flex.
Note: This guide has been created with the assumption that users already have some familiarity with Groovy or Java, Maven, an IDE such as IntelliJ or Eclipse, and the Dalet Flex User Interface.
Prerequisites to Install
The instructions below are for development on Mac or Linux; for Windows, the same components
(Java, Maven, Groovy) are required, but the installation process will differ.
- Homebrew (Mac or Linux package manager): Instructions can be found here
- Java (install via homebrew): brew cask install java
- Maven (install via homebrew): brew install maven
- Groovy (install via homebrew): brew install groovy
For reference:
- Learn about Groovy here.
- Learn about Maven here.
- Flex SDK javadocs can be found here.
- It is sometimes useful when debugging, to refer to the Dalet Flex REST API documentation. This can be found here.
IDE Setup
Install Local Maven Dependencies
The latest SDKs can be found in the Flex Nexus repository. If you do not have access to the Dalet Flex artifactory, please request the files from flex-solutions@ooyala.com. You must download the JAR and POM for your specific version of Flex, and then import them into your local maven repository.
Example: mio-api-sdk-2020.6.2.jar
Use the following command to import (absolute paths):
mvn install:install-file -Dfile=<path-to-file> -DgroupId=tv.nativ.mio -DartifactId=mio-api-sdk -Dversion=2020.6.2 -Dpackaging=jar
Maven Dependencies (pom.xml)
<dependency>
<groupId>tv.nativ.mio</groupId>
<artifactId>mio-api-sdk</artifactId>
<version>2020.6.2</version>
<dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.20</version>
<dependency>
Complete Maven pom.xml Example
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.ooyala.flex</groupId>
<artifactId>sdk-sample</artifactId>
<version>1.9</version>
<packaging>jar</packaging> <name>Sample Use of SDK</name>
<description>Demonstrating use of the Flex Enterprise SDK</description> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <build>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.2-01</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.4.20-01</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build> <dependencies>
<dependency>
<groupId>tv.nativ.mio</groupId>
<artifactId>mio-api-sdk</artifactId>
<version>2020.6.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.20</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.28.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies> </project>
Groovy Script Class Structure
The Flex SDK includes the PluginCommand class, which contains context and services fields to be referenced in your scripts. We’ll use these fields to interact with Dalet Flex.
package com.ooyala.flex.example import tv.nativ.mio.api.plugin.command.PluginCommand class MySample extends PluginCommand {
def execute() {
context.logInfo("Hello World!")
}
}
Deployment
Option 1: Reference Scripts in an External JAR File
Step1: Add Maven Build target (pom.xml)
Ensure that the following maven build configuration is in your pom.xml file.
<packaging>jar</packaging> <build>
<defaultGoal>package</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.2-01</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.4.20-01</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
You can then run the maven package command (mvn package) from the command line, or use your IDE to run the build and generate an external JAR file:
Step 2: Configure Flex Scripting Action
The following steps outline the configuration for Dalet Flex to execute custom scripts in an external JAR file:
- Upload a JAR file containing the above class, to a shared storage accessible by the Dalet Flex Job nodes (HTTP(S) also supported)
- Create a new action
- Action Type: Script
- Plugin: External Script Action - Configure the action to point to the JAR file and PluginCommand subclass.
4. Set the Flex system property to automatically reload JAR file changes:
Option 2: Copy and Paste Scripts to Flex Action
- Create a new action.
- Action Type: Script.
- Plugin: Groovy Script Action. - Copy the def execute() method into the script action:
Samples
Log to Job History
def myVar = 'some_value'
context.logInfo("This is a log statement. My variable is: $myVar")
Interact with Workflow Variables
def asset = context.asset context.setMioObjectVariable("myAsset", asset)
def assetLink = context.getMioObjectVariable("myAsset") def myVar = 'some_value'
context.setStringVariable("myVar", myVar)
def myStringVar = context.getStringVariable("myVar") def now = new Date()
context.setDateVariable('myDateVar', now)
def myDateVar = context.getDateVariable('myDateVar')
Note that Context::getMioObjectVariable() method returns an object of type ObjectLink. If you want to exchange this for a “real” object (e.g. an asset), you can use the appropriate service to do so:
def asset = context.asset context.setMioObjectVariable("myAsset", asset)
def assetLink = context.getMioObjectVariable("myAsset") def assetService = services.assetService
def storedAsset = assetService.getAsset(assetLink.id)
Store Asset on the Workflow Context
// Get asset from context
def asset = context.asset // Store another asset
context.setAsset(1234) // Remove asset from
contextcontext.removeAsset()
Get Asset Metadata
def asset = context.asset def assetService = services.assetService
def metadata = assetService.getAssetMetadata(asset) def directorField = metadata.getField('director')
if (directorField.hasValue()) {
def director = directorField.value as String
context.logInfo("The director is: $director")
}
Update Asset Metadata
def asset = context.asset def assetService = services.assetService
def metadata = assetService.getAssetMetadata(asset.id) def directorField = metadata.getField('director')
directorField.setValue('Michael Bay')
assetService.setAssetMetadata(asset.id, directorField)
Note: You must call setAssetMetadata() after updating your fields.
Set asset metadata by JSON
def asset = context.asset def metadataStructure = [
'myField1': 'value 1',
'myField2': 'value 2',
'myComplexField': [
'subField1': 'value 1',
'subField2': 'value 2'
]
]
def metadataJson = groovy.json.JsonOutput.toJson(metadataStructure) def assetService = services.assetService
def metadata = assetService.getAssetMetadata(asset) metadata.fromJson(metadataJson) assetService.setAssetMetadata(asset, metadata)
Find Asset by Metadata Value
def assetService = services.assetService // Build query
def assetStatus = 'FINISHED'
String metadata = "status:$assetStatus"
def query = new AssetAPIQuery(
metadataDefinitionId: 1234,
metadata: [metadata]
) // Run query
def finishedAssets = assetService.getAssets(query) if (finishedAssets.totalCount > 0) {
// Print all asset names
finishedAssets.assets.each { asset ->
context.logInfo("Found finished asset: $asset.name")
}
}
Unit Testing Framework
IDE Setup
Maven Dependencies (pom.xml)
The following dependencies must be added to your pom.xml file in addition to those listed in the Samples section:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.28.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
A Simple Script Example
Consider our metadata update script. This simple script will retrieve our asset's metadata fields, update one of the field values, then set the metadata back on the asset.
package com.ooyala.flex.example import tv.nativ.mio.api.plugin.command.PluginCommand class UpdateAssetMetadata extends PluginCommand {
def execute() {
def asset = context.asset
def assetService = services.assetService
def metadata = assetService.getAssetMetadata(asset.id)
def directorField = metadata.getField('director')
directorField.setValue('Michael Bay')
assetService.setAssetMetadata(asset.id, directorField)
}
}
A Simple Test Example
The unit test below will verify that our update metadata script is updating our metadata field correctly. Most unit tests for scripts which manipulate assets consist of similar steps:
- Create an asset object
- Add some information to the asset (in this case, create a metadata instance)
- Associate the information with the asset using a service mock
- Run the method under test
- Assert that the script took effect
package com.ooyala.flex.example import tv.nativ.mio.api.context.MockContext
import tv.nativ.mio.api.model.asset.Asset
import tv.nativ.mio.api.model.internal.metadata.MockMetadata
import tv.nativ.mio.api.model.internal.metadata.MockSingleField
import tv.nativ.mio.api.services.asset.AssetService
import tv.nativ.mio.api.services.factory.MioServiceFactory import static org.mockito.Matchers.eq
import static org.mockito.Mockito.doReturn
import static org.mockito.Mockito.mock
class UpdateAssetMetadataTest extends GroovyTestCase { MockContext context
MioServiceFactory services @Override
void setUp() {
// Instantiate our context and service
context = new MockContext()
services = mock(MioServiceFactory.class)
} void testExecute_DirectorExists() {
// Set an asset object on the context
def asset = new Asset(id: 123)
context.setAsset(asset)
// Create an initial metadata instance
def metadata = new MockMetadata([
new MockSingleField('director', '')
])
// Tell the assetService mock to return our metadata instance
def assetService = mock(AssetService.class)
doReturn(metadata).when(assetService).getAssetMetadata(eq(asset.id))
// Tell the services mock to return our assetService mock
doReturn(assetService).when(services).getAssetService()
// Run the method being tested
def command = new UpdateAssetMetadata(context: context, services: services)
command.execute()
// Verify that our script changed the metadata field
assertEquals('Michael Bay', metadata.getField('director').value)
}
}
Comments
0 comments
Please sign in to leave a comment.