Running an All-In-One Operation (Using JSON)

Problem

You want to run an All-In-One operation to produce either a Data Set, Content Sets, a Job Set or print output using one of the available process and input combinations.

Solution

The solution is to make a series of requests using the following URIs and method types to submit, monitor progress and ultimately retrieve the result of the All-In-One operation. There is also the option of cancelling an operation during processing if required. These requests can be submitted via the All-In-One REST service:

Process All-In-One (JSON) /rest/serverengine/workflow/print/submit POST
Get Progress of Operation /rest/serverengine/workflow/print/getProgress/{operationId} GET
Get Result of Operation /rest/serverengine/workflow/print/getResult/{operationId} POST
Get Result of Operation (as Text) /rest/serverengine/workflow/print/getResultTxt/{operationId} POST
Cancel an Operation /rest/serverengine/workflow/print/cancel/{operationId} POST

Example

HTML5

aio-process-json.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Process All-In-One (JSON) Example</title>
        <script src="../../common/lib/js/jquery-3.4.1.min.js"></script>
        <script src="../../common/js/common.js"></script>
        <script src="js/aio-process-json.js"></script>
        <link rel="stylesheet" href="../../common/css/styles.css">
    </head>
    <body>
        <h2>All-In-One Service - Process All-In-One (JSON) Example</h2>
        <form>
            <fieldset id="inputs">
                <legend>Inputs</legend>
                <div>
                    <label for="datamining">Data Mapping:</label>
                    <input id="datamining" type="checkbox">
                </div>
                <div>
                    <label for="contentcreation">Content Creation:</label>
                    <input id="contentcreation" type="checkbox">
                </div>
                <div>
                    <label for="jobcreation">Job Creation:</label>
                    <input id="jobcreation" type="checkbox">
                </div>
                <div>
                    <label for="outputcreation">Output Creation:</label>
                    <input id="outputcreation" type="checkbox">
                </div>
            </fieldset>
            <fieldset id="datamining-inputs" disabled>
                <legend>Data Mapping</legend>
                <div>
                    <label for="datafile">Data File ID/Name:</label>
                    <input id="datafile" type="text" placeholder="1234 or Filename" required>
                </div>
                <div>
                    <label for="datamapper">Data Mapping Configuration ID/Name:</label>
                    <input id="datamapper" type="text" placeholder="1234 or Filename" required>
                </div>
            </fieldset>
            <fieldset id="contentcreation-inputs" disabled>
                <legend>Content Creation</legend>
                <div>
                    <label for="datarecords">Data Record ID(s):</label>
                    <input id="datarecords" type="text" placeholder="1234, 2345, 3456, ..." required>
                </div>
                <div>
                    <label for="template">Template ID/Name:</label>
                    <input id="template" type="text" placeholder="1234 or Filename" required>
                </div>
            </fieldset>
            <fieldset id="jobcreation-inputs" disabled>
                <legend>Job Creation</legend>
                <div>
                    <label for="jcpreset">Job Creation Preset ID/Name:</label>
                    <input id="jcpreset" type="text" placeholder="1234 or Filename" disabled>
                </div>
                <div>
                    <label for="parameters">Runtime Parameters:</label>
                    <table id="parameters" class="name-value parameters">
                        <tbody>
                            <tr>
                                <th></th>
                                <th>Name</th>
                                <th>Type</th>
                                <th>Value</th>
                            </tr>
                            <tr class="placeholder" hidden>
                                <td></td>
                                <td>
                                    <input type="text" disabled>
                                </td>
                                <td>
                                    <select disabled>
                                        <option value="string">String</option>
                                    </select>
                                </td>
                                <td>
                                    <input type="text" disabled>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
                <div>
                    <input class="remove-parameter" type="button" value="Remove Selected" disabled>
                    <input class="add-parameter" type="button" value="Add Parameter">
                </div>
            </fieldset>
            <fieldset id="outputcreation-inputs" disabled>
                <legend>Output Creation</legend>
                <div>
                    <label for="jobs">Job ID(s):</label>
                    <input id="jobs" type="text" placeholder="1234, 2345, 3456, ..." required>
                </div>
                <div>
                    <label for="ocpreset">Output Creation Preset ID/Name:</label>
                    <input id="ocpreset" type="text" placeholder="1234 or Filename" required>
                </div>
            </fieldset>
            <fieldset>
                <legend>Options</legend>
                <div>
                    <label for="persistdres">Persist Data Records:</label>
                    <input id="persistdres" type="checkbox" disabled checked>
                </div>
                <div>
                    <label for="createonly">Create Only:</label>
                    <input id="createonly" type="checkbox" disabled>
                </div>
                <div>
                    <label for="resultastxt">Get Result as Text:</label>
                    <input id="resultastxt" type="checkbox" disabled>
                </div>
                <div>
                    <label for="printrange">Print Range:</label>
                    <input id="printrange" type="text" placeholder="1, 2, 3-5, 6" disabled>
                </div>
            </fieldset>
            <fieldset>
                <legend>Progress &amp; Actions</legend>
                <div>
                    <progress value="0" max="100"></progress>
                </div>
                <div>
                    <input id="cancel" type="button" value="Cancel" disabled>
                    <input id="submit" type="submit" value="Submit">
                </div>
            </fieldset>
        </form>
    </body>
</html>

markup.html

<!-- OL Connect REST API Cookbook - Working Examples [Markup HTML Snippet] -->
<div id="input-name-type-value-pair-row">
    <table>
        <tr class="root">
            <td>
                <input class="use-option" type="checkbox">
            </td>
            <td class="name">
                <input type="text" placeholder="Name" required>
            </td>
            <td class="type">
                <select id="type" class="options-selector">
                    <option value="string">String</option>
                    <option value="number">Number</option>
                    <option value="boolean">Boolean</option>
                    <option value="date">Date</option>
                </select>
            </td>
            <td class="option type-string value">
                <input type="text" placeholder="Value" required>
            </td>
            <td class="option type-number value">
                <input type="number" step="0.001" placeholder="Value" required />
            </td>
            <td class="option type-boolean value">
                <input type="checkbox" />
            </td>
            <td class="option type-date value">
                <input id="value1" type="date" required />
            </td>
        </tr>
    </table>
</div>

JavaScript/jQuery

aio-process-json.js

/* All-In-One Service - Process All-In-One (JSON) Example */
(function ($, c) {
    "use strict";
    $(function () {

        c.setupExample();

        var $form =     $("form"),
            $inputs =   $("#inputs input"),

            $datafile =     $("#datafile"),
            $datamapper =   $("#datamapper"),
            $datarecords =  $("#datarecords"),
            $template =     $("#template"),
            $parameters =   $("#parameters"),
            $jcpreset =     $("#jcpreset"),
            $jobs =         $("#jobs"),
            $ocpreset =     $("#ocpreset"),
            $persistdres =  $("#persistdres"),
            $createonly =   $("#createonly"),
            $resultastxt =  $("#resultastxt"),
            $printrange =   $("#printrange"),

            AIOConfig =     null,
            outputDesc =    null,
            operationId =   null,

            $submitButton = $("#submit"),
            $cancelButton = $("#cancel"),
            $progressBar =  $("progress");

        c.setupRuntimeParametersTableInput($parameters);

        $printrange
            .on("change", function (event) {
                c.setCustomInputValidity(event.target, c.validateNumericRange,
                    "Invalid Print Range value entered");
            })
            .trigger("change");

        $cancelButton.on("click", function () {
            if (operationId !== null) {

                /* Cancel an Operation */
                $.ajax({
                    type: "POST",
                    url:  "/rest/serverengine/workflow/print/cancel/" + operationId
                })
                    .done(function (response) {
                        c.displayInfo("Operation Cancelled!");
                        operationId = null;
                        setTimeout(function () {
                            $progressBar.attr("value", 0);
                            $submitButton.prop("disabled", false);
                            $cancelButton.prop("disabled", true);
                        }, 100);
                    })
                    .fail(c.displayDefaultFailure);
            }
        });

        /**
         * @function generateAIOConfig
         * @description Validates the workflow selected by the user
         * and constructs and an All-In-One Configuration using the relevant
         * input fields in the HTML Form.
         * Any invalid inputs or workflow selections will be red-flagged in
         * the HTML Form. Null can also be returned if no workflow selections
         * are made or if the workflow selections made are of an invalid sequence.
         * @private
         * @returns {Object} The All-In-One Configuration Object or Null
         */
        function generateAIOConfig() {

            var config = {},
                required = [],
                i = null,

                /* Parse Input Value to JSON Identifier List (Helper Function) */
                jsonIDListValue = function ($input) {
                    return (c.plainIDListToJson($input.val())).identifiers;
                },

                /* Parse Input Value to JSON Runtime Parameters (Helper Function) */
                jsonRuntimeParametersValue = function ($input) {
                    return (c.tableToJsonRuntimeParameters($input)).parameters;
                },

                /* Parse Input Value to Boolean (Helper Function) */
                booleanValue = function ($input) {
                    return $input.prop("checked");
                };

            /* Get Input Value and add it to the Configuration (Helper Function) */
            function getInputValue($input, process, field, parser) {
                var value = $input.val().trim();
                if (value) {
                    if (parser)
                        value = parser($input);
                    if (config[process] === undefined)
                        config[process] = {};
                    config[process][field] = value;
                }
            }

            /* Get Table Input Value and add it to the Configuration (Helper Function) */
            function getTableInputValue($table, process, field, parser) {
                if ($table.find("tr:has(td)").not(".placeholder").length) {
                    if (config[process] === undefined)
                        config[process] = {};
                    config[process][field] = parser($table);
                }
            }

            /* Get Required & Actual Workflow Selections */
            $inputs.each(function () {
                if ($(this).prop("checked"))
                    config[this.id] = {};
                $(this).prop("required", false);
                required.push(this.id);
            });
            var selections = (Object.keys(config)).length;

            /* Verify the Workflow Selections and note any omissions */
            var matches = 0,
                missing = [];
            for (i = 0; i < required.length; i += 1) {
                var step = required[i];
                if (config[step]) {
                    if (!matches && step === "jobcreation")
                        missing.push("contentcreation");
                    matches += 1;
                } else {
                    if (matches !== 0) missing.push(step);
                }
                if (matches === selections) break;
            }

            /* Add the inputs to the Workflow Selections to Create the All-In-One Configuration */
            if (config.datamining) {
                getInputValue($datafile, "datamining", "identifier");
                getInputValue($datamapper, "datamining", "config");
                outputDesc = "Data Set ID";
            }
            if (config.contentcreation) {
                getInputValue($template, "contentcreation", "config");
                if (!config.datamining) {
                    getInputValue($datarecords, "contentcreation", "identifiers", jsonIDListValue);
                    $datarecords.prop("disabled", false);
                } else {
                    $datarecords.prop("disabled", true);
                }
                outputDesc = "Content Set ID(s)";
            }
            if (config.jobcreation) {
                getInputValue($jcpreset, "jobcreation", "config");
                getTableInputValue($parameters, "jobcreation", "parameters",
                    jsonRuntimeParametersValue);
                $jcpreset.prop("disabled", false);
                outputDesc = "Job Set ID";
            } else {
                $jcpreset.prop("disabled", true);
            }
            if (config.outputcreation) {
                getInputValue($ocpreset, "outputcreation", "config");
                getInputValue($createonly, "outputcreation", "createOnly", booleanValue);
                if (!config.contentcreation) {
                    getInputValue($jobs, "outputcreation", "identifiers", jsonIDListValue);
                    $jobs.prop("disabled", false);
                } else {
                    $jobs.prop("disabled", true);
                }
                $createonly.prop("disabled", false);
                $resultastxt.prop("disabled", false);
                outputDesc = "Output";
            } else {
                $createonly.prop("disabled", true);
                $resultastxt.prop({ "disabled": true, "checked": true });
            }

            if (config.datamining) {
                if (config.jobcreation && config.jobcreation.config) {
                    $persistdres.prop({ "disabled": true, "checked": true });
                } else {
                    getInputValue($persistdres, "datamining", "persistDataset", booleanValue);
                    $persistdres.prop("disabled", false);
                }
            } else {
                $persistdres.prop({ "disabled": true });
            }

            if (config.datamining && config.contentcreation &&
                    config.jobcreation && config.outputcreation) {
                getInputValue($printrange, "printRange", "printRange");
                $printrange.prop("disabled", false);
            } else {
                $printrange.prop("disabled", true);
            }

            if (config.jobcreation && !config.jobcreation.config &&
                    config.jobcreation.parameters) {
                $jcpreset.prop("required", true);
            } else {
                $jcpreset.prop("required", false);
            }

            /* Red-flag any omissions in Workflow Selections */
            if (!selections || missing.length) {
                for (i = 0; i < missing.length; i += 1)
                    $("#" + missing[i]).prop("required", true);
                return null;
            }
            return config;
        }

        $inputs
            .on("change", function (event) {
                var input = event.target;
                var process = $("#" + input.id + "-inputs");
                process.prop("disabled", !($(input).prop("checked")));
            })
            .trigger("change");

        $form
            .on("change", function (event) {
                AIOConfig = generateAIOConfig();
            })
            .on("submit", function (event) {

                event.preventDefault();
                if (!c.checkSessionValid()) return;

                if (!AIOConfig) {
                    alert("Invalid All-In-One Configuration!\n\nPlease enter a valid " +
                        "combination of input fields, and try again.");
                    return;
                }

                var getFinalResult = function () {

                    var resultastxt = $resultastxt.prop("checked"),
                        result = (resultastxt) ? "getResultTxt" : "getResult";

                    /* Get Result of Operation */
                    var settings = {
                        type:   "POST",
                        url:    "/rest/serverengine/workflow/print/" + result + "/" + operationId
                    };
                    if (!resultastxt) settings.dataType = "file";
                    $.ajax(settings)
                        .done(function (response, status, request) {
                            c.displayHeading("Operation Result");
                            if (!resultastxt) {
                                c.displaySubResult(outputDesc, c.dataToFileLink(response, "Output File"), false);
                            } else {
                                c.displaySubResult(outputDesc, response);
                            }
                        })
                        .fail(c.displayDefaultFailure);
                };

                /* Process All-In-One (JSON) */
                $.ajax({
                    type:        "POST",
                    url:         "/rest/serverengine/workflow/print/submit",
                    data:        JSON.stringify(AIOConfig),
                    contentType: "application/json"
                })
                    .done(function (response, status, request) {

                        var progress = null;
                        operationId = request.getResponseHeader("operationId");

                        $submitButton.prop("disabled", true);
                        $cancelButton.prop("disabled", false);

                        c.displayStatus("All-In-One Operation Successfully Submitted");
                        c.displayHeading("Input Configuration");
                        c.displaySubResult("JSON All-In-One Configuration", c.jsonPrettyPrint(AIOConfig));
                        c.displayResult("Operation ID", operationId);

                        var getProgress = function () {
                            if (operationId !== null) {

                                /* Get Progress of Operation */
                                $.ajax({
                                    type:  "GET",
                                    cache: false,
                                    url:   "/rest/serverengine/workflow/print/getProgress/" + operationId
                                })
                                    .done(function (response, status, request) {

                                        if (response !== "done") {
                                            if (response !== progress) {
                                                progress = response;
                                                $progressBar.attr("value", progress);
                                            }
                                            setTimeout(getProgress, 1000);
                                        } else {
                                            $progressBar.attr("value", (progress = 100));
                                            c.displayInfo("Operation Completed");
                                            getFinalResult();
                                            operationId = null;
                                            setTimeout(function () {
                                                $progressBar.attr("value", 0);
                                                $submitButton.prop("disabled", false);
                                                $cancelButton.prop("disabled", true);
                                            }, 100);
                                        }
                                    })
                                    .fail(c.displayDefaultFailure);
                            }
                        };
                        getProgress();
                    })
                    .fail(c.displayDefaultFailure);
            })
            .trigger("change");
    });
}(jQuery, Common));

Screenshot & Output

Usage

To run the example simply select the input combination of your choosing, populate the appropriate input fields and then check any options that you may require.

The following file based input fields can be referenced by Managed File ID\Name:

  • Data file
  • Data Mapping configuration
  • Template
  • Job Creation preset
  • Output Creation preset

Specific to the specification of a Job Creation Preset, one or more Runtime Parameters can also be specified. Parameters can be added and removed using the Add Parameter and Remove Selected buttons respectively, and once added the following fields can be then populated for each parameter:

  • Name – The name of the runtime parameter (as specified in the Job Creation Preset)

  • Type – The type of the runtime parameter as either String, Number, Boolean or Date (as specified in the Job Creation Preset)

  • Value – The value of the runtime parameter (specific to the type selected)

The following options are only available if the input combination includes output creation:

  • Create Only – Create the output in server but do not send spool file to its final destination. In this example this would mean that the output files(s) would not be sent to the output directory specified in the output creation preset.
  • Get Result as Text – Return the result as text specifically. If our All-In-One Configuration includes output creation, then in this example this would return the absolute path to the output file(s).

The following option is only available if the input combination includes all four processes:

  • Print Range – Restrict the print output to a specific range of records in the input data, not a specific range of pages.

The following option is only available if the input combination specifically includes the data mapping process but with no job creation preset specified:

  • Persist Data Records – Create/persist data records entities in the server during the data mapping process (intended for use with once-off jobs where the storage of data records in the server is not required).

Lastly, select the Submit button to start the All-In-One operation.

Once the operation has started processing, the JSON All-In-One Configuration along with the Operation ID will be displayed in the Results area and the Cancel button will become enabled, giving you the option to cancel the running operation.

The progress of the operation will be displayed in the progress bar, and once the All-in-One operation has completed, the result will be returned and displayed to the Results area.

If the All-In-One configuration includes output creation, then the result returned will be the output files (either their absolute path(s) or the output file itself). If the configuration does not include output creation, then the result returned will be either a Data Set ID, Content Set IDs or Job Set ID.

If the result returned is expected to be file data, then then a download link will be displayed.

Further Reading

See the All-In-One Service page of the REST API Reference section for further detail.