Component interface

After selecting the component type, we design the external interface of a component. The interface is the visible part of a component, whereas the implementation is hidden. The interface also hides the type of the component (atomic or composite) and the implementation language of atomic components.

The interface consists of the following elements:

The interface is specified using an XML file named component.xml in the component folder. There is a template XML file under doc/templates/components/component.xml and the XML format is also formally specified using XML Schema under core/src/main/resources/component.xsd.

Example interface

Continuing to specify the CSV filter component for the demo bundle, here is its interface as an XML file. The file is located in ~/my-bundles/demo/components/SimpleCSVFilter/component.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<component>
    <name>SimpleCSVFilter</name>
    <version>1.0</version>
    <doc>
        Filter columns from CSV file by name using inclusion or exclusion.
    </doc>
    <author email="author.email@example.com">Author Name</author>
    <launcher type="R">
        <argument name="file" value="SimpleCSVFilter.r" />
    </launcher>
    <requires URL="http://www.r-project.org/" type="manual">R</requires>
    <inputs>
        <input name="in" type="CSV">
            <doc>Input CSV file.</doc>
        </input>
        <input name="columnNames" type="IDList" optional="true">
            <doc>Column names to be included / excluded.</doc>
        </input>
    </inputs>
    <outputs>
        <output name="out" type="CSV">
            <doc>Filtered CSV file.</doc>
        </output>
    </outputs>
    <parameters>
        <parameter name="include" type="boolean" default="true">
            <doc>
                If true, the output contains only columns that are present in columnNames.
                If false, the output contains only columns that are not present in columnNames.
            </doc>
        </parameter>
    </parameters>
</component>

Basic metadata

The name (SimpleCSVFilter) is used in Scala workflow code, so it should be recognizable and unique. Version number is used for dependency tracking; if you increase the version to 1.1, workflows using this component are subject to re-execution.

Launcher

We chose to use R to implement our component, and we specify this in the <launcher> section. It indicates that Anduril should use R facilities (specifically, Rscript) to execute this component. The file argument is the source file.

For implementing components in other languages, all supported launchers are:

Launcher Arguments
bash file, source
java class, extraClasspath, source
lua file, source
matlab file, source
octave file, source
python file, source
r file, source
scala class, extraClasspath, source

The source argument is an additional source file for including in the component documentation. For Java and Scala components, the entry point is specified using class (a fully qualified JVM class name).

Inputs, outputs and parameters

The <inputs>, <outputs> and <parameters> sections define the external interface. Port types refer to types declared in datatypes.xml files, either the current bundle or dependency bundles. Array ports are specified by adding the attribute array="true". Input ports can be optional, marked by optional="true". We chose the make the columnNames port of CSVFilter optional so that the component passes CSV files through unfiltered if the second input is missing.

Parameters can have default values, in which case specified them in the workflow is not mandatory. If the default is omitted, it must be provided in the workflow. Parameter types are as follows:

Parameter type Description
boolean true or false
float 64-bit double precision floating point number
int 32-bit signed integer
string Unicode string

Building component manual page

We can generate HTML documentation for the component using anduril build-doc --component doc-dir -b demo. This results in the following page (note that it includes features we haven’t yet introduced):